Skip to content

Commit 17a6209

Browse files
committed
refactor(token-swap): AccountConstraints naming, UncheckedAccount, quasar parity
Anchor (F5/F6): - Rename account-constraint structs from `...Accounts` to `...AccountConstraints` (handlers, lib.rs, tests) - Migrate unchecked `AccountInfo` to `UncheckedAccount` (clears the deprecation warnings; modern stable-Anchor idiom) - Drop now-unnecessary `mut` on create_config / create_pool contexts Quasar (F7) - port the correctness work the mirror was missing: - checked arithmetic everywhere (swap fee/effective-reserve math, withdraw effective reserves + total liquidity, deposit reserves) - extract the basis-points divisor into BASIS_POINTS_DIVISOR - Checks-Effects-Interactions: write state before transfer CPIs in swap_tokens and claim_admin_fees - fail fast instead of silently clamping deposit/swap input to balance - fix LP-mint formula: sqrt(a*b) only bootstraps the first deposit; subsequent deposits mint min(a*supply/pool_a, b*supply/pool_b) - "on-chain" -> "onchain" Verified: anchor 18/18 LiteSVM tests pass, quasar 4/4 tests pass, both programs build with cargo build-sbf.
1 parent 28bb47c commit 17a6209

14 files changed

Lines changed: 218 additions & 124 deletions

File tree

tokens/token-swap/anchor/programs/token-swap/src/instructions/admin/claim_admin_fees.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::{
1919
/// `Signer` constraint on `admin` together mean only the address stored in
2020
/// `Config.admin` can call this. Any other signer will be rejected by
2121
/// Anchor's built-in `has_one` check.
22-
pub fn handle_claim_admin_fees(context: Context<ClaimAdminFeesAccounts>) -> Result<()> {
22+
pub fn handle_claim_admin_fees(context: Context<ClaimAdminFeesAccountConstraints>) -> Result<()> {
2323
let owed_a = context.accounts.pool_config.admin_fees_owed_a;
2424
let owed_b = context.accounts.pool_config.admin_fees_owed_b;
2525

@@ -98,7 +98,7 @@ pub fn handle_claim_admin_fees(context: Context<ClaimAdminFeesAccounts>) -> Resu
9898
}
9999

100100
#[derive(Accounts)]
101-
pub struct ClaimAdminFeesAccounts<'info> {
101+
pub struct ClaimAdminFeesAccountConstraints<'info> {
102102
#[account(
103103
seeds = [CONFIG_SEED],
104104
bump,
@@ -130,7 +130,7 @@ pub struct ClaimAdminFeesAccounts<'info> {
130130
],
131131
bump,
132132
)]
133-
pub pool_authority: AccountInfo<'info>,
133+
pub pool_authority: UncheckedAccount<'info>,
134134

135135
pub mint_a: Box<InterfaceAccount<'info, Mint>>,
136136

tokens/token-swap/anchor/programs/token-swap/src/instructions/create_config.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
};
88

99
pub fn handle_create_config(
10-
mut context: Context<CreateConfigAccounts>,
10+
context: Context<CreateConfigAccountConstraints>,
1111
fee: u16,
1212
admin_share_bps: u16,
1313
) -> Result<()> {
@@ -23,7 +23,7 @@ pub fn handle_create_config(
2323

2424
#[derive(Accounts)]
2525
#[instruction(fee: u16, admin_share_bps: u16)]
26-
pub struct CreateConfigAccounts<'info> {
26+
pub struct CreateConfigAccountConstraints<'info> {
2727
#[account(
2828
init,
2929
payer = payer,
@@ -37,7 +37,7 @@ pub struct CreateConfigAccounts<'info> {
3737

3838
/// The admin of the AMM
3939
/// CHECK: Read only, delegatable creation
40-
pub admin: AccountInfo<'info>,
40+
pub admin: UncheckedAccount<'info>,
4141

4242
/// The account paying for all rents
4343
#[account(mut)]

tokens/token-swap/anchor/programs/token-swap/src/instructions/create_pool.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::{
1010
state::{Config, PoolConfig},
1111
};
1212

13-
pub fn handle_create_pool(mut context: Context<CreatePoolAccounts>) -> Result<()> {
13+
pub fn handle_create_pool(context: Context<CreatePoolAccountConstraints>) -> Result<()> {
1414
let bump = context.bumps.pool_config;
1515
let pool_config = &mut context.accounts.pool_config;
1616
pool_config.config = context.accounts.config.key();
@@ -22,7 +22,7 @@ pub fn handle_create_pool(mut context: Context<CreatePoolAccounts>) -> Result<()
2222
}
2323

2424
#[derive(Accounts)]
25-
pub struct CreatePoolAccounts<'info> {
25+
pub struct CreatePoolAccountConstraints<'info> {
2626
#[account(
2727
seeds = [CONFIG_SEED],
2828
bump,
@@ -53,7 +53,7 @@ pub struct CreatePoolAccounts<'info> {
5353
],
5454
bump,
5555
)]
56-
pub pool_authority: AccountInfo<'info>,
56+
pub pool_authority: UncheckedAccount<'info>,
5757

5858
#[account(
5959
init,

tokens/token-swap/anchor/programs/token-swap/src/instructions/deposit_liquidity.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ fn integer_sqrt(n: u128) -> u128 {
2828
}
2929

3030
pub fn handle_deposit_liquidity(
31-
context: Context<DepositLiquidityAccounts>,
31+
context: Context<DepositLiquidityAccountConstraints>,
3232
amount_a: u64,
3333
amount_b: u64,
3434
minimum_lp_tokens_out: u64,
@@ -244,7 +244,7 @@ pub fn handle_deposit_liquidity(
244244
}
245245

246246
#[derive(Accounts)]
247-
pub struct DepositLiquidityAccounts<'info> {
247+
pub struct DepositLiquidityAccountConstraints<'info> {
248248
#[account(
249249
seeds = [
250250
pool_config.config.as_ref(),
@@ -267,7 +267,7 @@ pub struct DepositLiquidityAccounts<'info> {
267267
],
268268
bump,
269269
)]
270-
pub pool_authority: AccountInfo<'info>,
270+
pub pool_authority: UncheckedAccount<'info>,
271271

272272
/// The account paying for all rents
273273
pub depositor: Signer<'info>,

tokens/token-swap/anchor/programs/token-swap/src/instructions/swap_tokens.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::{
1111
};
1212

1313
pub fn handle_swap_tokens(
14-
context: Context<SwapTokensAccounts>,
14+
context: Context<SwapTokensAccountConstraints>,
1515
input_is_token_a: bool,
1616
input_amount: u64,
1717
min_output_amount: u64,
@@ -261,7 +261,7 @@ pub fn handle_swap_tokens(
261261
}
262262

263263
#[derive(Accounts)]
264-
pub struct SwapTokensAccounts<'info> {
264+
pub struct SwapTokensAccountConstraints<'info> {
265265
#[account(
266266
seeds = [CONFIG_SEED],
267267
bump,
@@ -292,7 +292,7 @@ pub struct SwapTokensAccounts<'info> {
292292
],
293293
bump,
294294
)]
295-
pub pool_authority: AccountInfo<'info>,
295+
pub pool_authority: UncheckedAccount<'info>,
296296

297297
/// The account doing the swap
298298
pub trader: Signer<'info>,

tokens/token-swap/anchor/programs/token-swap/src/instructions/withdraw_liquidity.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::{
1111
};
1212

1313
pub fn handle_withdraw_liquidity(
14-
context: Context<WithdrawLiquidityAccounts>,
14+
context: Context<WithdrawLiquidityAccountConstraints>,
1515
amount: u64,
1616
minimum_token_a_out: u64,
1717
minimum_token_b_out: u64,
@@ -140,7 +140,7 @@ pub fn handle_withdraw_liquidity(
140140
}
141141

142142
#[derive(Accounts)]
143-
pub struct WithdrawLiquidityAccounts<'info> {
143+
pub struct WithdrawLiquidityAccountConstraints<'info> {
144144
#[account(
145145
seeds = [CONFIG_SEED],
146146
bump,
@@ -169,7 +169,7 @@ pub struct WithdrawLiquidityAccounts<'info> {
169169
],
170170
bump,
171171
)]
172-
pub pool_authority: AccountInfo<'info>,
172+
pub pool_authority: UncheckedAccount<'info>,
173173

174174
pub withdrawer: Signer<'info>,
175175

tokens/token-swap/anchor/programs/token-swap/src/lib.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,19 @@ pub mod swap_example {
1313
use super::*;
1414

1515
pub fn create_config(
16-
context: Context<CreateConfigAccounts>,
16+
context: Context<CreateConfigAccountConstraints>,
1717
fee: u16,
1818
admin_share_bps: u16,
1919
) -> Result<()> {
2020
instructions::handle_create_config(context, fee, admin_share_bps)
2121
}
2222

23-
pub fn create_pool(context: Context<CreatePoolAccounts>) -> Result<()> {
23+
pub fn create_pool(context: Context<CreatePoolAccountConstraints>) -> Result<()> {
2424
instructions::handle_create_pool(context)
2525
}
2626

2727
pub fn deposit_liquidity(
28-
context: Context<DepositLiquidityAccounts>,
28+
context: Context<DepositLiquidityAccountConstraints>,
2929
amount_a: u64,
3030
amount_b: u64,
3131
minimum_lp_tokens_out: u64,
@@ -39,7 +39,7 @@ pub mod swap_example {
3939
}
4040

4141
pub fn withdraw_liquidity(
42-
context: Context<WithdrawLiquidityAccounts>,
42+
context: Context<WithdrawLiquidityAccountConstraints>,
4343
amount: u64,
4444
minimum_token_a_out: u64,
4545
minimum_token_b_out: u64,
@@ -53,7 +53,7 @@ pub mod swap_example {
5353
}
5454

5555
pub fn swap_tokens(
56-
context: Context<SwapTokensAccounts>,
56+
context: Context<SwapTokensAccountConstraints>,
5757
input_is_token_a: bool,
5858
input_amount: u64,
5959
min_output_amount: u64,
@@ -66,7 +66,7 @@ pub mod swap_example {
6666
)
6767
}
6868

69-
pub fn claim_admin_fees(context: Context<ClaimAdminFeesAccounts>) -> Result<()> {
69+
pub fn claim_admin_fees(context: Context<ClaimAdminFeesAccountConstraints>) -> Result<()> {
7070
instructions::handle_claim_admin_fees(context)
7171
}
7272
}

tokens/token-swap/anchor/programs/token-swap/tests/test_swap.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ fn full_setup() -> TestSetup {
128128
let create_config_ix = Instruction::new_with_bytes(
129129
program_id,
130130
&swap_example::instruction::CreateConfig { fee, admin_share_bps }.data(),
131-
swap_example::accounts::CreateConfigAccounts {
131+
swap_example::accounts::CreateConfigAccountConstraints {
132132
config: config_key,
133133
admin: admin.pubkey(),
134134
payer: payer.pubkey(),
@@ -148,7 +148,7 @@ fn full_setup() -> TestSetup {
148148
let create_pool_ix = Instruction::new_with_bytes(
149149
program_id,
150150
&swap_example::instruction::CreatePool {}.data(),
151-
swap_example::accounts::CreatePoolAccounts {
151+
swap_example::accounts::CreatePoolAccountConstraints {
152152
config: config_key,
153153
pool_config: pool_config_key,
154154
pool_authority,
@@ -203,7 +203,7 @@ fn test_create_config() {
203203
let create_config_ix = Instruction::new_with_bytes(
204204
program_id,
205205
&swap_example::instruction::CreateConfig { fee, admin_share_bps }.data(),
206-
swap_example::accounts::CreateConfigAccounts {
206+
swap_example::accounts::CreateConfigAccountConstraints {
207207
config: config_key,
208208
admin: admin.pubkey(),
209209
payer: payer.pubkey(),
@@ -242,7 +242,7 @@ fn test_deposit_liquidity() {
242242
minimum_lp_tokens_out: 0,
243243
}
244244
.data(),
245-
swap_example::accounts::DepositLiquidityAccounts {
245+
swap_example::accounts::DepositLiquidityAccountConstraints {
246246
pool_config: ts.pool_config_key,
247247
pool_authority: ts.pool_authority,
248248
depositor: ts.admin.pubkey(),
@@ -289,7 +289,7 @@ fn test_swap_a_to_b() {
289289
minimum_lp_tokens_out: 0,
290290
}
291291
.data(),
292-
swap_example::accounts::DepositLiquidityAccounts {
292+
swap_example::accounts::DepositLiquidityAccountConstraints {
293293
pool_config: ts.pool_config_key,
294294
pool_authority: ts.pool_authority,
295295
depositor: ts.admin.pubkey(),
@@ -328,7 +328,7 @@ fn test_swap_a_to_b() {
328328
min_output_amount: 100,
329329
}
330330
.data(),
331-
swap_example::accounts::SwapTokensAccounts {
331+
swap_example::accounts::SwapTokensAccountConstraints {
332332
config: ts.config_key,
333333
pool_config: ts.pool_config_key,
334334
pool_authority: ts.pool_authority,
@@ -376,7 +376,7 @@ fn test_withdraw_liquidity() {
376376
minimum_lp_tokens_out: 0,
377377
}
378378
.data(),
379-
swap_example::accounts::DepositLiquidityAccounts {
379+
swap_example::accounts::DepositLiquidityAccountConstraints {
380380
pool_config: ts.pool_config_key,
381381
pool_authority: ts.pool_authority,
382382
depositor: ts.admin.pubkey(),
@@ -417,7 +417,7 @@ fn test_withdraw_liquidity() {
417417
minimum_token_b_out: 0,
418418
}
419419
.data(),
420-
swap_example::accounts::WithdrawLiquidityAccounts {
420+
swap_example::accounts::WithdrawLiquidityAccountConstraints {
421421
config: ts.config_key,
422422
pool_config: ts.pool_config_key,
423423
pool_authority: ts.pool_authority,
@@ -462,7 +462,7 @@ fn deposit_and_swap_a_to_b(ts: &mut TestSetup, deposit_a: u64, deposit_b: u64, s
462462
minimum_lp_tokens_out: 0,
463463
}
464464
.data(),
465-
swap_example::accounts::DepositLiquidityAccounts {
465+
swap_example::accounts::DepositLiquidityAccountConstraints {
466466
pool_config: ts.pool_config_key,
467467
pool_authority: ts.pool_authority,
468468
depositor: ts.admin.pubkey(),
@@ -497,7 +497,7 @@ fn deposit_and_swap_a_to_b(ts: &mut TestSetup, deposit_a: u64, deposit_b: u64, s
497497
min_output_amount: 1,
498498
}
499499
.data(),
500-
swap_example::accounts::SwapTokensAccounts {
500+
swap_example::accounts::SwapTokensAccountConstraints {
501501
config: ts.config_key,
502502
pool_config: ts.pool_config_key,
503503
pool_authority: ts.pool_authority,
@@ -531,7 +531,7 @@ fn claim_admin_fees_ix(ts: &TestSetup) -> Instruction {
531531
Instruction::new_with_bytes(
532532
ts.program_id,
533533
&swap_example::instruction::ClaimAdminFees {}.data(),
534-
swap_example::accounts::ClaimAdminFeesAccounts {
534+
swap_example::accounts::ClaimAdminFeesAccountConstraints {
535535
config: ts.config_key,
536536
pool_config: ts.pool_config_key,
537537
pool_authority: ts.pool_authority,
@@ -558,7 +558,7 @@ fn swap_a_to_b(ts: &mut TestSetup, input_amount: u64) {
558558
min_output_amount: 1,
559559
}
560560
.data(),
561-
swap_example::accounts::SwapTokensAccounts {
561+
swap_example::accounts::SwapTokensAccountConstraints {
562562
config: ts.config_key,
563563
pool_config: ts.pool_config_key,
564564
pool_authority: ts.pool_authority,
@@ -672,7 +672,7 @@ fn test_claim_admin_fees() {
672672
let claim_ix_again = Instruction::new_with_bytes(
673673
ts.program_id,
674674
&swap_example::instruction::ClaimAdminFees {}.data(),
675-
swap_example::accounts::ClaimAdminFeesAccounts {
675+
swap_example::accounts::ClaimAdminFeesAccountConstraints {
676676
config: ts.config_key,
677677
pool_config: ts.pool_config_key,
678678
pool_authority: ts.pool_authority,
@@ -733,7 +733,7 @@ fn test_claim_admin_fees_rejects_non_admin() {
733733
let claim_ix = Instruction::new_with_bytes(
734734
ts.program_id,
735735
&swap_example::instruction::ClaimAdminFees {}.data(),
736-
swap_example::accounts::ClaimAdminFeesAccounts {
736+
swap_example::accounts::ClaimAdminFeesAccountConstraints {
737737
config: ts.config_key,
738738
pool_config: ts.pool_config_key,
739739
pool_authority: ts.pool_authority,
@@ -776,7 +776,7 @@ fn deposit_ix(ts: &TestSetup, amount_a: u64, amount_b: u64) -> Instruction {
776776
minimum_lp_tokens_out: 0,
777777
}
778778
.data(),
779-
swap_example::accounts::DepositLiquidityAccounts {
779+
swap_example::accounts::DepositLiquidityAccountConstraints {
780780
pool_config: ts.pool_config_key,
781781
pool_authority: ts.pool_authority,
782782
depositor: ts.admin.pubkey(),
@@ -950,7 +950,7 @@ fn test_deposit_after_swap_uses_shifted_effective_ratio() {
950950
min_output_amount: 1,
951951
}
952952
.data(),
953-
swap_example::accounts::SwapTokensAccounts {
953+
swap_example::accounts::SwapTokensAccountConstraints {
954954
config: ts.config_key,
955955
pool_config: ts.pool_config_key,
956956
pool_authority: ts.pool_authority,
@@ -1164,7 +1164,7 @@ fn swap_a_to_b_ix(ts: &TestSetup, input_amount: u64, min_output_amount: u64) ->
11641164
min_output_amount,
11651165
}
11661166
.data(),
1167-
swap_example::accounts::SwapTokensAccounts {
1167+
swap_example::accounts::SwapTokensAccountConstraints {
11681168
config: ts.config_key,
11691169
pool_config: ts.pool_config_key,
11701170
pool_authority: ts.pool_authority,
@@ -1199,7 +1199,7 @@ fn deposit_ix_with_min_lp(
11991199
minimum_lp_tokens_out,
12001200
}
12011201
.data(),
1202-
swap_example::accounts::DepositLiquidityAccounts {
1202+
swap_example::accounts::DepositLiquidityAccountConstraints {
12031203
pool_config: ts.pool_config_key,
12041204
pool_authority: ts.pool_authority,
12051205
depositor: ts.admin.pubkey(),
@@ -1235,7 +1235,7 @@ fn withdraw_ix_with_min(
12351235
minimum_token_b_out,
12361236
}
12371237
.data(),
1238-
swap_example::accounts::WithdrawLiquidityAccounts {
1238+
swap_example::accounts::WithdrawLiquidityAccountConstraints {
12391239
config: ts.config_key,
12401240
pool_config: ts.pool_config_key,
12411241
pool_authority: ts.pool_authority,

0 commit comments

Comments
 (0)