feat(amm): route user deposits and LP burns through ATA program

Add `owner` and `ata_program_id` parameters to `add_liquidity`,
`remove_liquidity`, `swap_exact_input`, and `swap_exact_output`. User
deposit-side transfers now emit `ATA::Transfer` chained calls instead of
`Token::Transfer` directly, and LP burns emit `ATA::Burn` instead of
`Token::Burn`. Vault withdrawal chained calls are unchanged.

- Add `ata_program_id` field to `AddLiquidity`, `RemoveLiquidity`,
  `SwapExactInput`, and `SwapExactOutput` instruction variants in
  `amm_core`
- Add `ata_core` dependency to `amm_program` and guest crates
- Update guest binary, unit tests, and integration tests to supply the
  new `owner` account and `ata_program_id` at every call site
- Regenerate `artifacts/amm-idl.json`

Closes #11
This commit is contained in:
r4bbit 2026-04-22 14:35:30 +02:00
parent 471abef719
commit 9444d72c60
No known key found for this signature in database
GPG Key ID: E95F1E9447DC91A9
12 changed files with 359 additions and 82 deletions

1
Cargo.lock generated
View File

@ -54,6 +54,7 @@ name = "amm_program"
version = "0.1.0"
dependencies = [
"amm_core",
"ata_core",
"nssa_core",
"token_core",
]

View File

@ -6,4 +6,5 @@ edition = "2021"
[dependencies]
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc1", features = ["host"] }
amm_core = { path = "core" }
ata_core = { path = "../ata/core" }
token_core = { path = "../token/core" }

View File

@ -44,13 +44,15 @@ pub enum Instruction {
/// - Vault Holding Account for Token A (initialized)
/// - Vault Holding Account for Token B (initialized)
/// - Pool Liquidity Token Definition (initialized)
/// - User Holding Account for Token A (authorized)
/// - User Holding Account for Token B (authorized)
/// - User Holding Account for Pool Liquidity
/// - Owner account (authorized)
/// - User ATA for Token A
/// - User ATA for Token B
/// - User ATA for Pool Liquidity
AddLiquidity {
min_amount_liquidity: u128,
max_amount_to_add_token_a: u128,
max_amount_to_add_token_b: u128,
ata_program_id: ProgramId,
},
/// Removes liquidity from the Pool
@ -60,13 +62,15 @@ pub enum Instruction {
/// - Vault Holding Account for Token A (initialized)
/// - Vault Holding Account for Token B (initialized)
/// - Pool Liquidity Token Definition (initialized)
/// - User Holding Account for Token A (initialized)
/// - User Holding Account for Token B (initialized)
/// - User Holding Account for Pool Liquidity (authorized)
/// - Owner account (authorized)
/// - User ATA for Token A (initialized)
/// - User ATA for Token B (initialized)
/// - User ATA for Pool Liquidity
RemoveLiquidity {
remove_liquidity_amount: u128,
min_amount_to_remove_token_a: u128,
min_amount_to_remove_token_b: u128,
ata_program_id: ProgramId,
},
/// Swap some quantity of Tokens (either Token A or Token B)
@ -76,13 +80,14 @@ pub enum Instruction {
/// - AMM Pool (initialized)
/// - Vault Holding Account for Token A (initialized)
/// - Vault Holding Account for Token B (initialized)
/// - User Holding Account for Token A
/// - User Holding Account for Token B Either User Holding Account for Token A or Token B is
/// authorized.
/// - Owner account (authorized)
/// - User ATA for Token A
/// - User ATA for Token B
SwapExactInput {
swap_amount_in: u128,
min_amount_out: u128,
token_definition_id_in: AccountId,
ata_program_id: ProgramId,
},
/// Swap tokens specifying the exact desired output amount,
@ -92,13 +97,14 @@ pub enum Instruction {
/// - AMM Pool (initialized)
/// - Vault Holding Account for Token A (initialized)
/// - Vault Holding Account for Token B (initialized)
/// - User Holding Account for Token A
/// - User Holding Account for Token B Either User Holding Account for Token A or Token B is
/// authorized.
/// - Owner account (authorized)
/// - User ATA for Token A
/// - User ATA for Token B
SwapExactOutput {
exact_amount_out: u128,
max_amount_in: u128,
token_definition_id_in: AccountId,
ata_program_id: ProgramId,
},
/// Sync pool reserves with current vault balances.

View File

@ -35,6 +35,7 @@ version = "0.1.0"
dependencies = [
"amm_core",
"amm_program",
"ata_core",
"borsh",
"nssa_core",
"risc0-zkvm",
@ -59,6 +60,7 @@ name = "amm_program"
version = "0.1.0"
dependencies = [
"amm_core",
"ata_core",
"nssa_core",
"token_core",
]
@ -304,6 +306,16 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "ata_core"
version = "0.1.0"
dependencies = [
"borsh",
"nssa_core",
"risc0-zkvm",
"serde",
]
[[package]]
name = "atomic-waker"
version = "1.1.2"

View File

@ -14,6 +14,7 @@ spel-framework = { git = "https://github.com/logos-co/spel.git", tag = "v0.2.0-r
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc1" }
risc0-zkvm = { version = "=3.0.5", default-features = false }
amm_core = { path = "../../core" }
ata_core = { path = "../../../ata/core" }
amm_program = { path = "../..", package = "amm_program" }
token_core = { path = "../../../token/core" }
serde = { version = "1.0", features = ["derive"] }

View File

@ -56,24 +56,28 @@ mod amm {
vault_a: AccountWithMetadata,
vault_b: AccountWithMetadata,
pool_definition_lp: AccountWithMetadata,
owner: AccountWithMetadata,
user_holding_a: AccountWithMetadata,
user_holding_b: AccountWithMetadata,
user_holding_lp: AccountWithMetadata,
min_amount_liquidity: u128,
max_amount_to_add_token_a: u128,
max_amount_to_add_token_b: u128,
ata_program_id: ProgramId,
) -> SpelResult {
let (post_states, chained_calls) = amm_program::add::add_liquidity(
pool,
vault_a,
vault_b,
pool_definition_lp,
owner,
user_holding_a,
user_holding_b,
user_holding_lp,
NonZeroU128::new(min_amount_liquidity).expect("min_amount_liquidity must be nonzero"),
max_amount_to_add_token_a,
max_amount_to_add_token_b,
ata_program_id,
);
Ok(SpelOutput::with_chained_calls(post_states, chained_calls))
}
@ -85,18 +89,21 @@ mod amm {
vault_a: AccountWithMetadata,
vault_b: AccountWithMetadata,
pool_definition_lp: AccountWithMetadata,
owner: AccountWithMetadata,
user_holding_a: AccountWithMetadata,
user_holding_b: AccountWithMetadata,
user_holding_lp: AccountWithMetadata,
remove_liquidity_amount: u128,
min_amount_to_remove_token_a: u128,
min_amount_to_remove_token_b: u128,
ata_program_id: ProgramId,
) -> SpelResult {
let (post_states, chained_calls) = amm_program::remove::remove_liquidity(
pool,
vault_a,
vault_b,
pool_definition_lp,
owner,
user_holding_a,
user_holding_b,
user_holding_lp,
@ -104,6 +111,7 @@ mod amm {
.expect("remove_liquidity_amount must be nonzero"),
min_amount_to_remove_token_a,
min_amount_to_remove_token_b,
ata_program_id,
);
Ok(SpelOutput::with_chained_calls(post_states, chained_calls))
}
@ -114,21 +122,25 @@ mod amm {
pool: AccountWithMetadata,
vault_a: AccountWithMetadata,
vault_b: AccountWithMetadata,
owner: AccountWithMetadata,
user_holding_a: AccountWithMetadata,
user_holding_b: AccountWithMetadata,
swap_amount_in: u128,
min_amount_out: u128,
token_definition_id_in: AccountId,
ata_program_id: ProgramId,
) -> SpelResult {
let (post_states, chained_calls) = amm_program::swap::swap_exact_input(
pool,
vault_a,
vault_b,
owner,
user_holding_a,
user_holding_b,
swap_amount_in,
min_amount_out,
token_definition_id_in,
ata_program_id,
);
Ok(SpelOutput::with_chained_calls(post_states, chained_calls))
}
@ -139,21 +151,25 @@ mod amm {
pool: AccountWithMetadata,
vault_a: AccountWithMetadata,
vault_b: AccountWithMetadata,
owner: AccountWithMetadata,
user_holding_a: AccountWithMetadata,
user_holding_b: AccountWithMetadata,
exact_amount_out: u128,
max_amount_in: u128,
token_definition_id_in: AccountId,
ata_program_id: ProgramId,
) -> SpelResult {
let (post_states, chained_calls) = amm_program::swap::swap_exact_output(
pool,
vault_a,
vault_b,
owner,
user_holding_a,
user_holding_b,
exact_amount_out,
max_amount_in,
token_definition_id_in,
ata_program_id,
);
Ok(SpelOutput::with_chained_calls(post_states, chained_calls))
}

View File

@ -6,7 +6,7 @@ use amm_core::{
};
use nssa_core::{
account::{AccountWithMetadata, Data},
program::{AccountPostState, ChainedCall},
program::{AccountPostState, ChainedCall, ProgramId},
};
#[expect(clippy::too_many_arguments, reason = "TODO: Fix later")]
@ -15,12 +15,14 @@ pub fn add_liquidity(
vault_a: AccountWithMetadata,
vault_b: AccountWithMetadata,
pool_definition_lp: AccountWithMetadata,
owner: AccountWithMetadata,
user_holding_a: AccountWithMetadata,
user_holding_b: AccountWithMetadata,
user_holding_lp: AccountWithMetadata,
min_amount_liquidity: NonZeroU128,
max_amount_to_add_token_a: u128,
max_amount_to_add_token_b: u128,
ata_program_id: ProgramId,
) -> (Vec<AccountPostState>, Vec<ChainedCall>) {
// 1. Fetch Pool state
let pool_def_data = PoolDefinition::try_from(&pool.account.data)
@ -138,25 +140,27 @@ pub fn add_liquidity(
};
pool_post.data = Data::from(&pool_post_definition);
let token_program_id = user_holding_a.account.program_owner;
let token_program_id = vault_a.account.program_owner;
// Chain call for Token A (UserHoldingA -> Vault_A)
// Chain call for Token A (owner's ATA -> Vault_A via ATA program)
let call_token_a = ChainedCall::new(
token_program_id,
vec![user_holding_a.clone(), vault_a.clone()],
&token_core::Instruction::Transfer {
amount_to_transfer: actual_amount_a,
ata_program_id,
vec![owner.clone(), user_holding_a.clone(), vault_a.clone()],
&ata_core::Instruction::Transfer {
ata_program_id,
amount: actual_amount_a,
},
);
// Chain call for Token B (UserHoldingB -> Vault_B)
// Chain call for Token B (owner's ATA -> Vault_B via ATA program)
let call_token_b = ChainedCall::new(
token_program_id,
vec![user_holding_b.clone(), vault_b.clone()],
&token_core::Instruction::Transfer {
amount_to_transfer: actual_amount_b,
ata_program_id,
vec![owner.clone(), user_holding_b.clone(), vault_b.clone()],
&ata_core::Instruction::Transfer {
ata_program_id,
amount: actual_amount_b,
},
);
// Chain call for LP (mint new tokens for user_holding_lp)
// Chain call for LP (mint new tokens for user's LP ATA)
let mut pool_definition_lp_auth = pool_definition_lp.clone();
pool_definition_lp_auth.is_authorized = true;
let call_token_lp = ChainedCall::new(
@ -175,6 +179,7 @@ pub fn add_liquidity(
AccountPostState::new(vault_a.account.clone()),
AccountPostState::new(vault_b.account.clone()),
AccountPostState::new(pool_definition_lp.account.clone()),
AccountPostState::new(owner.account.clone()),
AccountPostState::new(user_holding_a.account.clone()),
AccountPostState::new(user_holding_b.account.clone()),
AccountPostState::new(user_holding_lp.account.clone()),

View File

@ -1,12 +1,11 @@
use std::num::NonZeroU128;
use amm_core::{
assert_supported_fee_tier, compute_liquidity_token_pda_seed, compute_vault_pda_seed,
PoolDefinition, MINIMUM_LIQUIDITY,
assert_supported_fee_tier, compute_vault_pda_seed, PoolDefinition, MINIMUM_LIQUIDITY,
};
use nssa_core::{
account::{AccountWithMetadata, Data},
program::{AccountPostState, ChainedCall},
program::{AccountPostState, ChainedCall, ProgramId},
};
#[expect(clippy::too_many_arguments, reason = "TODO: Fix later")]
@ -15,12 +14,14 @@ pub fn remove_liquidity(
vault_a: AccountWithMetadata,
vault_b: AccountWithMetadata,
pool_definition_lp: AccountWithMetadata,
owner: AccountWithMetadata,
user_holding_a: AccountWithMetadata,
user_holding_b: AccountWithMetadata,
user_holding_lp: AccountWithMetadata,
remove_liquidity_amount: NonZeroU128,
min_amount_to_remove_token_a: u128,
min_amount_to_remove_token_b: u128,
ata_program_id: ProgramId,
) -> (Vec<AccountPostState>, Vec<ChainedCall>) {
let remove_liquidity_amount: u128 = remove_liquidity_amount.into();
@ -143,9 +144,9 @@ pub fn remove_liquidity(
pool_post.data = Data::from(&pool_post_definition);
let token_program_id = user_holding_a.account.program_owner;
let token_program_id = vault_a.account.program_owner;
// Chaincall for Token A withdraw
// Chaincall for Token A withdraw (vault PDA -> user's ATA)
let call_token_a = ChainedCall::new(
token_program_id,
vec![running_vault_a, user_holding_a.clone()],
@ -157,7 +158,7 @@ pub fn remove_liquidity(
pool.account_id,
pool_def_data.definition_token_a_id,
)]);
// Chaincall for Token B withdraw
// Chaincall for Token B withdraw (vault PDA -> user's ATA)
let call_token_b = ChainedCall::new(
token_program_id,
vec![running_vault_b, user_holding_b.clone()],
@ -169,17 +170,19 @@ pub fn remove_liquidity(
pool.account_id,
pool_def_data.definition_token_b_id,
)]);
// Chaincall for LP adjustment
let mut pool_definition_lp_auth = pool_definition_lp.clone();
pool_definition_lp_auth.is_authorized = true;
// Chaincall for LP burn (owner's LP ATA -> burn via ATA program)
let call_token_lp = ChainedCall::new(
token_program_id,
vec![pool_definition_lp_auth, user_holding_lp.clone()],
&token_core::Instruction::Burn {
amount_to_burn: delta_lp,
ata_program_id,
vec![
owner.clone(),
user_holding_lp.clone(),
pool_definition_lp.clone(),
],
&ata_core::Instruction::Burn {
ata_program_id,
amount: delta_lp,
},
)
.with_pda_seeds(vec![compute_liquidity_token_pda_seed(pool.account_id)]);
);
let chained_calls = vec![call_token_lp, call_token_b, call_token_a];
@ -188,6 +191,7 @@ pub fn remove_liquidity(
AccountPostState::new(vault_a.account.clone()),
AccountPostState::new(vault_b.account.clone()),
AccountPostState::new(pool_definition_lp.account.clone()),
AccountPostState::new(owner.account.clone()),
AccountPostState::new(user_holding_a.account.clone()),
AccountPostState::new(user_holding_b.account.clone()),
AccountPostState::new(user_holding_lp.account.clone()),

View File

@ -4,7 +4,7 @@ use amm_core::{
pub use amm_core::{compute_liquidity_token_pda_seed, compute_vault_pda_seed, PoolDefinition};
use nssa_core::{
account::{AccountId, AccountWithMetadata, Data},
program::{AccountPostState, ChainedCall},
program::{AccountPostState, ChainedCall, ProgramId},
};
/// Validates swap setup: checks pool liquidity is ready, vaults match, and reserves are sufficient.
@ -56,6 +56,7 @@ fn create_swap_post_states(
pool_def_data: PoolDefinition,
vault_a: AccountWithMetadata,
vault_b: AccountWithMetadata,
owner: AccountWithMetadata,
user_holding_a: AccountWithMetadata,
user_holding_b: AccountWithMetadata,
deposit_a: u128,
@ -86,6 +87,7 @@ fn create_swap_post_states(
AccountPostState::new(pool_post),
AccountPostState::new(vault_a.account),
AccountPostState::new(vault_b.account),
AccountPostState::new(owner.account),
AccountPostState::new(user_holding_a.account),
AccountPostState::new(user_holding_b.account),
]
@ -97,17 +99,20 @@ pub fn swap_exact_input(
pool: AccountWithMetadata,
vault_a: AccountWithMetadata,
vault_b: AccountWithMetadata,
owner: AccountWithMetadata,
user_holding_a: AccountWithMetadata,
user_holding_b: AccountWithMetadata,
swap_amount_in: u128,
min_amount_out: u128,
token_in_id: AccountId,
ata_program_id: ProgramId,
) -> (Vec<AccountPostState>, Vec<ChainedCall>) {
let pool_def_data = validate_swap_setup(&pool, &vault_a, &vault_b);
let (chained_calls, [deposit_a, withdraw_a], [deposit_b, withdraw_b]) =
if token_in_id == pool_def_data.definition_token_a_id {
let (chained_calls, deposit_a, withdraw_b) = swap_logic(
owner.clone(),
user_holding_a.clone(),
vault_a.clone(),
vault_b.clone(),
@ -118,11 +123,13 @@ pub fn swap_exact_input(
pool_def_data.reserve_a,
pool_def_data.reserve_b,
pool.account_id,
ata_program_id,
);
(chained_calls, [deposit_a, 0], [0, withdraw_b])
} else if token_in_id == pool_def_data.definition_token_b_id {
let (chained_calls, deposit_b, withdraw_a) = swap_logic(
owner.clone(),
user_holding_b.clone(),
vault_b.clone(),
vault_a.clone(),
@ -133,6 +140,7 @@ pub fn swap_exact_input(
pool_def_data.reserve_b,
pool_def_data.reserve_a,
pool.account_id,
ata_program_id,
);
(chained_calls, [0, withdraw_a], [deposit_b, 0])
@ -145,6 +153,7 @@ pub fn swap_exact_input(
pool_def_data,
vault_a,
vault_b,
owner,
user_holding_a,
user_holding_b,
deposit_a,
@ -158,6 +167,7 @@ pub fn swap_exact_input(
#[expect(clippy::too_many_arguments, reason = "TODO: Fix later")]
fn swap_logic(
owner: AccountWithMetadata,
user_deposit: AccountWithMetadata,
vault_deposit: AccountWithMetadata,
vault_withdraw: AccountWithMetadata,
@ -168,6 +178,7 @@ fn swap_logic(
reserve_deposit_vault_amount: u128,
reserve_withdraw_vault_amount: u128,
pool_id: AccountId,
ata_program_id: ProgramId,
) -> (Vec<ChainedCall>, u128, u128) {
let effective_amount_in = swap_amount_in
.checked_mul(FEE_BPS_DENOMINATOR - fee_bps)
@ -195,14 +206,16 @@ fn swap_logic(
);
assert!(withdraw_amount != 0, "Withdraw amount should be nonzero");
let token_program_id = user_deposit.account.program_owner;
let token_program_id = vault_withdraw.account.program_owner;
let mut chained_calls = Vec::new();
// Deposit: owner's ATA -> vault via ATA program
chained_calls.push(ChainedCall::new(
token_program_id,
vec![user_deposit, vault_deposit],
&token_core::Instruction::Transfer {
amount_to_transfer: swap_amount_in,
ata_program_id,
vec![owner, user_deposit, vault_deposit],
&ata_core::Instruction::Transfer {
ata_program_id,
amount: swap_amount_in,
},
));
@ -216,6 +229,7 @@ fn swap_logic(
.definition_id(),
);
// Withdrawal: vault PDA -> user's ATA (no ATA auth needed for recipient)
chained_calls.push(
ChainedCall::new(
token_program_id,
@ -236,17 +250,20 @@ pub fn swap_exact_output(
pool: AccountWithMetadata,
vault_a: AccountWithMetadata,
vault_b: AccountWithMetadata,
owner: AccountWithMetadata,
user_holding_a: AccountWithMetadata,
user_holding_b: AccountWithMetadata,
exact_amount_out: u128,
max_amount_in: u128,
token_in_id: AccountId,
ata_program_id: ProgramId,
) -> (Vec<AccountPostState>, Vec<ChainedCall>) {
let pool_def_data = validate_swap_setup(&pool, &vault_a, &vault_b);
let (chained_calls, [deposit_a, withdraw_a], [deposit_b, withdraw_b]) =
if token_in_id == pool_def_data.definition_token_a_id {
let (chained_calls, deposit_a, withdraw_b) = exact_output_swap_logic(
owner.clone(),
user_holding_a.clone(),
vault_a.clone(),
vault_b.clone(),
@ -257,11 +274,13 @@ pub fn swap_exact_output(
pool_def_data.reserve_b,
pool_def_data.fees,
pool.account_id,
ata_program_id,
);
(chained_calls, [deposit_a, 0], [0, withdraw_b])
} else if token_in_id == pool_def_data.definition_token_b_id {
let (chained_calls, deposit_b, withdraw_a) = exact_output_swap_logic(
owner.clone(),
user_holding_b.clone(),
vault_b.clone(),
vault_a.clone(),
@ -272,6 +291,7 @@ pub fn swap_exact_output(
pool_def_data.reserve_a,
pool_def_data.fees,
pool.account_id,
ata_program_id,
);
(chained_calls, [0, withdraw_a], [deposit_b, 0])
@ -284,6 +304,7 @@ pub fn swap_exact_output(
pool_def_data,
vault_a,
vault_b,
owner,
user_holding_a,
user_holding_b,
deposit_a,
@ -297,6 +318,7 @@ pub fn swap_exact_output(
#[expect(clippy::too_many_arguments, reason = "TODO: Fix later")]
fn exact_output_swap_logic(
owner: AccountWithMetadata,
user_deposit: AccountWithMetadata,
vault_deposit: AccountWithMetadata,
vault_withdraw: AccountWithMetadata,
@ -307,6 +329,7 @@ fn exact_output_swap_logic(
reserve_withdraw_vault_amount: u128,
fee_bps: u128,
pool_id: AccountId,
ata_program_id: ProgramId,
) -> (Vec<ChainedCall>, u128, u128) {
// Guard: exact_amount_out must be nonzero
assert_ne!(exact_amount_out, 0, "Exact amount out must be nonzero");
@ -346,14 +369,16 @@ fn exact_output_swap_logic(
"Required input exceeds maximum amount in"
);
let token_program_id = user_deposit.account.program_owner;
let token_program_id = vault_withdraw.account.program_owner;
let mut chained_calls = Vec::new();
// Deposit: owner's ATA -> vault via ATA program
chained_calls.push(ChainedCall::new(
token_program_id,
vec![user_deposit, vault_deposit],
&token_core::Instruction::Transfer {
amount_to_transfer: deposit_amount,
ata_program_id,
vec![owner, user_deposit, vault_deposit],
&ata_core::Instruction::Transfer {
ata_program_id,
amount: deposit_amount,
},
));
@ -367,6 +392,7 @@ fn exact_output_swap_logic(
.definition_id(),
);
// Withdrawal: vault PDA -> user's ATA (no ATA auth needed for recipient)
chained_calls.push(
ChainedCall::new(
token_program_id,

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,5 @@
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.53s
Running `target/debug/idl-gen amm/methods/guest/src/bin/amm.rs`
{
"version": "0.1.0",
"name": "amm",
@ -100,6 +102,12 @@
"signer": false,
"init": false
},
{
"name": "owner",
"writable": false,
"signer": false,
"init": false
},
{
"name": "user_holding_a",
"writable": false,
@ -131,6 +139,10 @@
{
"name": "max_amount_to_add_token_b",
"type": "u128"
},
{
"name": "ata_program_id",
"type": "program_id"
}
]
},
@ -161,6 +173,12 @@
"signer": false,
"init": false
},
{
"name": "owner",
"writable": false,
"signer": false,
"init": false
},
{
"name": "user_holding_a",
"writable": false,
@ -192,6 +210,10 @@
{
"name": "min_amount_to_remove_token_b",
"type": "u128"
},
{
"name": "ata_program_id",
"type": "program_id"
}
]
},
@ -216,6 +238,12 @@
"signer": false,
"init": false
},
{
"name": "owner",
"writable": false,
"signer": false,
"init": false
},
{
"name": "user_holding_a",
"writable": false,
@ -241,6 +269,10 @@
{
"name": "token_definition_id_in",
"type": "account_id"
},
{
"name": "ata_program_id",
"type": "program_id"
}
]
},
@ -265,6 +297,12 @@
"signer": false,
"init": false
},
{
"name": "owner",
"writable": false,
"signer": false,
"init": false
},
{
"name": "user_holding_a",
"writable": false,
@ -290,6 +328,10 @@
{
"name": "token_definition_id_in",
"type": "account_id"
},
{
"name": "ata_program_id",
"type": "program_id"
}
]
},

View File

@ -38,6 +38,10 @@ impl Ids {
amm_methods::AMM_ID
}
fn ata_program() -> nssa_core::program::ProgramId {
ata_methods::ATA_ID
}
fn token_a_definition() -> AccountId {
AccountId::new([3; 32])
}
@ -1018,6 +1022,7 @@ fn execute_swap_a_to_b(state: &mut V03State, swap_amount_in: u128, min_amount_ou
swap_amount_in,
min_amount_out,
token_definition_id_in: Ids::token_a_definition(),
ata_program_id: Ids::ata_program(),
};
let message = public_transaction::Message::try_new(
@ -1045,6 +1050,7 @@ fn execute_swap_b_to_a(state: &mut V03State, swap_amount_in: u128, min_amount_ou
swap_amount_in,
min_amount_out,
token_definition_id_in: Ids::token_b_definition(),
ata_program_id: Ids::ata_program(),
};
let message = public_transaction::Message::try_new(
@ -1077,6 +1083,7 @@ fn execute_add_liquidity(
min_amount_liquidity,
max_amount_to_add_token_a,
max_amount_to_add_token_b,
ata_program_id: Ids::ata_program(),
};
let message = public_transaction::Message::try_new(
@ -1115,6 +1122,7 @@ fn execute_remove_liquidity(
remove_liquidity_amount,
min_amount_to_remove_token_a,
min_amount_to_remove_token_b,
ata_program_id: Ids::ata_program(),
};
let message = public_transaction::Message::try_new(
@ -1178,6 +1186,7 @@ fn amm_remove_liquidity() {
remove_liquidity_amount: Balances::remove_lp(),
min_amount_to_remove_token_a: Balances::remove_min_a(),
min_amount_to_remove_token_b: Balances::remove_min_b(),
ata_program_id: Ids::ata_program(),
};
let message = public_transaction::Message::try_new(
@ -1240,6 +1249,7 @@ fn amm_remove_liquidity_insufficient_user_lp_fails() {
remove_liquidity_amount: Balances::remove_lp(),
min_amount_to_remove_token_a: Balances::remove_min_a(),
min_amount_to_remove_token_b: Balances::remove_min_b(),
ata_program_id: Ids::ata_program(),
};
let message = public_transaction::Message::try_new(
@ -1464,6 +1474,7 @@ fn amm_add_liquidity() {
min_amount_liquidity: Balances::add_min_lp(),
max_amount_to_add_token_a: Balances::add_max_a(),
max_amount_to_add_token_b: Balances::add_max_b(),
ata_program_id: Ids::ata_program(),
};
let message = public_transaction::Message::try_new(
@ -1526,6 +1537,7 @@ fn amm_swap_b_to_a() {
swap_amount_in: Balances::swap_amount_in(),
min_amount_out: Balances::swap_min_out(),
token_definition_id_in: Ids::token_b_definition(),
ata_program_id: Ids::ata_program(),
};
let message = public_transaction::Message::try_new(
@ -1577,6 +1589,7 @@ fn amm_swap_a_to_b() {
swap_amount_in: Balances::swap_amount_in(),
min_amount_out: Balances::swap_min_out(),
token_definition_id_in: Ids::token_a_definition(),
ata_program_id: Ids::ata_program(),
};
let message = public_transaction::Message::try_new(