mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-05-18 15:09:51 +00:00
feat(amm)!: add transaction deadlines to swap and liquidity instructions
All mutable AMM instructions now require a `deadline: u64` field (Unix timestamp in milliseconds). Enforcement uses the LEZ-native timestamp validity window set on ProgramOutput; the runtime rejects the transaction if the sequencer submission timestamp is at or past the deadline. BREAKING CHANGE: AddLiquidity, RemoveLiquidity, SwapExactInput, SwapExactOutput, and NewDefinition instruction variants now require a `deadline` field. Closes #8
This commit is contained in:
parent
5a61cf39f2
commit
6b21c3695a
@ -35,6 +35,8 @@ pub enum Instruction {
|
||||
token_b_amount: u128,
|
||||
fees: u128,
|
||||
amm_program_id: ProgramId,
|
||||
/// Unix timestamp (milliseconds) after which this transaction is invalid.
|
||||
deadline: u64,
|
||||
},
|
||||
|
||||
/// Adds liquidity to the Pool
|
||||
@ -51,6 +53,8 @@ pub enum Instruction {
|
||||
min_amount_liquidity: u128,
|
||||
max_amount_to_add_token_a: u128,
|
||||
max_amount_to_add_token_b: u128,
|
||||
/// Unix timestamp (milliseconds) after which this transaction is invalid.
|
||||
deadline: u64,
|
||||
},
|
||||
|
||||
/// Removes liquidity from the Pool
|
||||
@ -67,6 +71,8 @@ pub enum Instruction {
|
||||
remove_liquidity_amount: u128,
|
||||
min_amount_to_remove_token_a: u128,
|
||||
min_amount_to_remove_token_b: u128,
|
||||
/// Unix timestamp (milliseconds) after which this transaction is invalid.
|
||||
deadline: u64,
|
||||
},
|
||||
|
||||
/// Swap some quantity of Tokens (either Token A or Token B)
|
||||
@ -77,12 +83,13 @@ pub enum Instruction {
|
||||
/// - 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.
|
||||
/// - User Holding Account for Token B; either is authorized.
|
||||
SwapExactInput {
|
||||
swap_amount_in: u128,
|
||||
min_amount_out: u128,
|
||||
token_definition_id_in: AccountId,
|
||||
/// Unix timestamp (milliseconds) after which this transaction is invalid.
|
||||
deadline: u64,
|
||||
},
|
||||
|
||||
/// Swap tokens specifying the exact desired output amount,
|
||||
@ -93,12 +100,13 @@ pub enum Instruction {
|
||||
/// - 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.
|
||||
/// - User Holding Account for Token B; either is authorized.
|
||||
SwapExactOutput {
|
||||
exact_amount_out: u128,
|
||||
max_amount_in: u128,
|
||||
token_definition_id_in: AccountId,
|
||||
/// Unix timestamp (milliseconds) after which this transaction is invalid.
|
||||
deadline: u64,
|
||||
},
|
||||
|
||||
/// Sync pool reserves with current vault balances.
|
||||
|
||||
10
amm/methods/guest/Cargo.lock
generated
10
amm/methods/guest/Cargo.lock
generated
@ -2898,10 +2898,11 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "spel-framework"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/logos-co/spel.git?tag=v0.2.0-rc.2#9005e9fbbd78b0530412f9987273f753ed32eb2d"
|
||||
source = "git+https://github.com/logos-co/spel.git?rev=9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3#9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3"
|
||||
dependencies = [
|
||||
"borsh",
|
||||
"nssa_core",
|
||||
"serde_json",
|
||||
"spel-framework-core",
|
||||
"spel-framework-macros",
|
||||
]
|
||||
@ -2909,24 +2910,27 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "spel-framework-core"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/logos-co/spel.git?tag=v0.2.0-rc.2#9005e9fbbd78b0530412f9987273f753ed32eb2d"
|
||||
source = "git+https://github.com/logos-co/spel.git?rev=9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3#9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3"
|
||||
dependencies = [
|
||||
"borsh",
|
||||
"nssa_core",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"syn 2.0.117",
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spel-framework-macros"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/logos-co/spel.git?tag=v0.2.0-rc.2#9005e9fbbd78b0530412f9987273f753ed32eb2d"
|
||||
source = "git+https://github.com/logos-co/spel.git?rev=9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3#9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"spel-framework-core",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ name = "amm"
|
||||
path = "src/bin/amm.rs"
|
||||
|
||||
[dependencies]
|
||||
spel-framework = { git = "https://github.com/logos-co/spel.git", tag = "v0.2.0-rc.2", package = "spel-framework" }
|
||||
spel-framework = { git = "https://github.com/logos-co/spel.git", rev = "9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3", package = "spel-framework" }
|
||||
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" }
|
||||
|
||||
@ -31,6 +31,7 @@ mod amm {
|
||||
token_b_amount: u128,
|
||||
fees: u128,
|
||||
amm_program_id: ProgramId,
|
||||
deadline: u64,
|
||||
) -> SpelResult {
|
||||
let (post_states, chained_calls) = amm_program::new_definition::new_definition(
|
||||
pool,
|
||||
@ -46,7 +47,8 @@ mod amm {
|
||||
fees,
|
||||
amm_program_id,
|
||||
);
|
||||
Ok(SpelOutput::with_chained_calls(post_states, chained_calls))
|
||||
Ok(SpelOutput::with_chained_calls(post_states, chained_calls)
|
||||
.with_timestamp_validity_window(..deadline))
|
||||
}
|
||||
|
||||
/// Adds liquidity to the Pool.
|
||||
@ -62,6 +64,7 @@ mod amm {
|
||||
min_amount_liquidity: u128,
|
||||
max_amount_to_add_token_a: u128,
|
||||
max_amount_to_add_token_b: u128,
|
||||
deadline: u64,
|
||||
) -> SpelResult {
|
||||
let (post_states, chained_calls) = amm_program::add::add_liquidity(
|
||||
pool,
|
||||
@ -75,7 +78,8 @@ mod amm {
|
||||
max_amount_to_add_token_a,
|
||||
max_amount_to_add_token_b,
|
||||
);
|
||||
Ok(SpelOutput::with_chained_calls(post_states, chained_calls))
|
||||
Ok(SpelOutput::with_chained_calls(post_states, chained_calls)
|
||||
.with_timestamp_validity_window(..deadline))
|
||||
}
|
||||
|
||||
/// Removes liquidity from the Pool.
|
||||
@ -91,6 +95,7 @@ mod amm {
|
||||
remove_liquidity_amount: u128,
|
||||
min_amount_to_remove_token_a: u128,
|
||||
min_amount_to_remove_token_b: u128,
|
||||
deadline: u64,
|
||||
) -> SpelResult {
|
||||
let (post_states, chained_calls) = amm_program::remove::remove_liquidity(
|
||||
pool,
|
||||
@ -105,7 +110,8 @@ mod amm {
|
||||
min_amount_to_remove_token_a,
|
||||
min_amount_to_remove_token_b,
|
||||
);
|
||||
Ok(SpelOutput::with_chained_calls(post_states, chained_calls))
|
||||
Ok(SpelOutput::with_chained_calls(post_states, chained_calls)
|
||||
.with_timestamp_validity_window(..deadline))
|
||||
}
|
||||
|
||||
/// Swap some quantity of tokens while maintaining the pool constant product.
|
||||
@ -119,6 +125,7 @@ mod amm {
|
||||
swap_amount_in: u128,
|
||||
min_amount_out: u128,
|
||||
token_definition_id_in: AccountId,
|
||||
deadline: u64,
|
||||
) -> SpelResult {
|
||||
let (post_states, chained_calls) = amm_program::swap::swap_exact_input(
|
||||
pool,
|
||||
@ -130,7 +137,8 @@ mod amm {
|
||||
min_amount_out,
|
||||
token_definition_id_in,
|
||||
);
|
||||
Ok(SpelOutput::with_chained_calls(post_states, chained_calls))
|
||||
Ok(SpelOutput::with_chained_calls(post_states, chained_calls)
|
||||
.with_timestamp_validity_window(..deadline))
|
||||
}
|
||||
|
||||
/// Swap tokens specifying the exact desired output amount.
|
||||
@ -144,6 +152,7 @@ mod amm {
|
||||
exact_amount_out: u128,
|
||||
max_amount_in: u128,
|
||||
token_definition_id_in: AccountId,
|
||||
deadline: u64,
|
||||
) -> SpelResult {
|
||||
let (post_states, chained_calls) = amm_program::swap::swap_exact_output(
|
||||
pool,
|
||||
@ -155,7 +164,8 @@ mod amm {
|
||||
max_amount_in,
|
||||
token_definition_id_in,
|
||||
);
|
||||
Ok(SpelOutput::with_chained_calls(post_states, chained_calls))
|
||||
Ok(SpelOutput::with_chained_calls(post_states, chained_calls)
|
||||
.with_timestamp_validity_window(..deadline))
|
||||
}
|
||||
|
||||
/// Sync pool reserves with current vault balances.
|
||||
|
||||
@ -70,6 +70,10 @@
|
||||
{
|
||||
"name": "amm_program_id",
|
||||
"type": "program_id"
|
||||
},
|
||||
{
|
||||
"name": "deadline",
|
||||
"type": "u64"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -131,6 +135,10 @@
|
||||
{
|
||||
"name": "max_amount_to_add_token_b",
|
||||
"type": "u128"
|
||||
},
|
||||
{
|
||||
"name": "deadline",
|
||||
"type": "u64"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -192,6 +200,10 @@
|
||||
{
|
||||
"name": "min_amount_to_remove_token_b",
|
||||
"type": "u128"
|
||||
},
|
||||
{
|
||||
"name": "deadline",
|
||||
"type": "u64"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -241,6 +253,10 @@
|
||||
{
|
||||
"name": "token_definition_id_in",
|
||||
"type": "account_id"
|
||||
},
|
||||
{
|
||||
"name": "deadline",
|
||||
"type": "u64"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -290,6 +306,10 @@
|
||||
{
|
||||
"name": "token_definition_id_in",
|
||||
"type": "account_id"
|
||||
},
|
||||
{
|
||||
"name": "deadline",
|
||||
"type": "u64"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
10
ata/methods/guest/Cargo.lock
generated
10
ata/methods/guest/Cargo.lock
generated
@ -2897,10 +2897,11 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "spel-framework"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/logos-co/spel.git?tag=v0.2.0-rc.2#9005e9fbbd78b0530412f9987273f753ed32eb2d"
|
||||
source = "git+https://github.com/logos-co/spel.git?rev=9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3#9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3"
|
||||
dependencies = [
|
||||
"borsh",
|
||||
"nssa_core",
|
||||
"serde_json",
|
||||
"spel-framework-core",
|
||||
"spel-framework-macros",
|
||||
]
|
||||
@ -2908,24 +2909,27 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "spel-framework-core"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/logos-co/spel.git?tag=v0.2.0-rc.2#9005e9fbbd78b0530412f9987273f753ed32eb2d"
|
||||
source = "git+https://github.com/logos-co/spel.git?rev=9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3#9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3"
|
||||
dependencies = [
|
||||
"borsh",
|
||||
"nssa_core",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"syn 2.0.117",
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spel-framework-macros"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/logos-co/spel.git?tag=v0.2.0-rc.2#9005e9fbbd78b0530412f9987273f753ed32eb2d"
|
||||
source = "git+https://github.com/logos-co/spel.git?rev=9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3#9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"spel-framework-core",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ name = "ata"
|
||||
path = "src/bin/ata.rs"
|
||||
|
||||
[dependencies]
|
||||
spel-framework = { git = "https://github.com/logos-co/spel.git", tag = "v0.2.0-rc.2", package = "spel-framework" }
|
||||
spel-framework = { git = "https://github.com/logos-co/spel.git", rev = "9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3", package = "spel-framework" }
|
||||
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 }
|
||||
ata_core = { path = "../../core" }
|
||||
|
||||
@ -966,6 +966,7 @@ fn try_execute_new_definition(
|
||||
token_b_amount: Balances::vault_b_init(),
|
||||
fees,
|
||||
amm_program_id: Ids::amm_program(),
|
||||
deadline: u64::MAX,
|
||||
};
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
@ -1018,6 +1019,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(),
|
||||
deadline: u64::MAX,
|
||||
};
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
@ -1045,6 +1047,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(),
|
||||
deadline: u64::MAX,
|
||||
};
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
@ -1077,6 +1080,7 @@ fn execute_add_liquidity(
|
||||
min_amount_liquidity,
|
||||
max_amount_to_add_token_a,
|
||||
max_amount_to_add_token_b,
|
||||
deadline: u64::MAX,
|
||||
};
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
@ -1115,6 +1119,7 @@ fn execute_remove_liquidity(
|
||||
remove_liquidity_amount,
|
||||
min_amount_to_remove_token_a,
|
||||
min_amount_to_remove_token_b,
|
||||
deadline: u64::MAX,
|
||||
};
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
@ -1178,6 +1183,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(),
|
||||
deadline: u64::MAX,
|
||||
};
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
@ -1240,6 +1246,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(),
|
||||
deadline: u64::MAX,
|
||||
};
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
@ -1464,6 +1471,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(),
|
||||
deadline: u64::MAX,
|
||||
};
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
@ -1526,6 +1534,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(),
|
||||
deadline: u64::MAX,
|
||||
};
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
@ -1577,6 +1586,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(),
|
||||
deadline: u64::MAX,
|
||||
};
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
@ -1671,6 +1681,205 @@ fn amm_fee_accumulates_across_multiple_swaps_and_pays_out_on_remove() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn amm_swap_rejects_expired_deadline() {
|
||||
let mut state = state_for_amm_tests();
|
||||
|
||||
let deadline_ms = 1_000u64;
|
||||
let block_timestamp_ms = 2_000u64;
|
||||
|
||||
let instruction = amm_core::Instruction::SwapExactInput {
|
||||
swap_amount_in: Balances::swap_amount_in(),
|
||||
min_amount_out: Balances::swap_min_out(),
|
||||
token_definition_id_in: Ids::token_a_definition(),
|
||||
deadline: deadline_ms,
|
||||
};
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
Ids::amm_program(),
|
||||
vec![
|
||||
Ids::pool_definition(),
|
||||
Ids::vault_a(),
|
||||
Ids::vault_b(),
|
||||
Ids::user_a(),
|
||||
Ids::user_b(),
|
||||
],
|
||||
vec![Nonce(0)],
|
||||
instruction,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_a()]);
|
||||
let tx = PublicTransaction::new(message, witness_set);
|
||||
assert!(matches!(
|
||||
state.transition_from_public_transaction(&tx, 0, block_timestamp_ms),
|
||||
Err(NssaError::OutOfValidityWindow)
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn amm_swap_exact_output_rejects_expired_deadline() {
|
||||
let mut state = state_for_amm_tests();
|
||||
|
||||
let deadline_ms = 1_000u64;
|
||||
let block_timestamp_ms = 2_000u64;
|
||||
|
||||
let instruction = amm_core::Instruction::SwapExactOutput {
|
||||
exact_amount_out: Balances::swap_min_out(),
|
||||
max_amount_in: Balances::swap_amount_in(),
|
||||
token_definition_id_in: Ids::token_a_definition(),
|
||||
deadline: deadline_ms,
|
||||
};
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
Ids::amm_program(),
|
||||
vec![
|
||||
Ids::pool_definition(),
|
||||
Ids::vault_a(),
|
||||
Ids::vault_b(),
|
||||
Ids::user_a(),
|
||||
Ids::user_b(),
|
||||
],
|
||||
vec![current_nonce(&state, Ids::user_a())],
|
||||
instruction,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_a()]);
|
||||
let tx = PublicTransaction::new(message, witness_set);
|
||||
assert!(matches!(
|
||||
state.transition_from_public_transaction(&tx, 0, block_timestamp_ms),
|
||||
Err(NssaError::OutOfValidityWindow)
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn amm_add_liquidity_rejects_expired_deadline() {
|
||||
let mut state = state_for_amm_tests();
|
||||
|
||||
let deadline_ms = 1_000u64;
|
||||
let block_timestamp_ms = 2_000u64;
|
||||
|
||||
let instruction = amm_core::Instruction::AddLiquidity {
|
||||
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(),
|
||||
deadline: deadline_ms,
|
||||
};
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
Ids::amm_program(),
|
||||
vec![
|
||||
Ids::pool_definition(),
|
||||
Ids::vault_a(),
|
||||
Ids::vault_b(),
|
||||
Ids::token_lp_definition(),
|
||||
Ids::user_a(),
|
||||
Ids::user_b(),
|
||||
Ids::user_lp(),
|
||||
],
|
||||
vec![
|
||||
current_nonce(&state, Ids::user_a()),
|
||||
current_nonce(&state, Ids::user_b()),
|
||||
],
|
||||
instruction,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let witness_set =
|
||||
public_transaction::WitnessSet::for_message(&message, &[&Keys::user_a(), &Keys::user_b()]);
|
||||
let tx = PublicTransaction::new(message, witness_set);
|
||||
assert!(matches!(
|
||||
state.transition_from_public_transaction(&tx, 0, block_timestamp_ms),
|
||||
Err(NssaError::OutOfValidityWindow)
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn amm_remove_liquidity_rejects_expired_deadline() {
|
||||
let mut state = state_for_amm_tests();
|
||||
|
||||
let deadline_ms = 1_000u64;
|
||||
let block_timestamp_ms = 2_000u64;
|
||||
|
||||
let instruction = amm_core::Instruction::RemoveLiquidity {
|
||||
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(),
|
||||
deadline: deadline_ms,
|
||||
};
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
Ids::amm_program(),
|
||||
vec![
|
||||
Ids::pool_definition(),
|
||||
Ids::vault_a(),
|
||||
Ids::vault_b(),
|
||||
Ids::token_lp_definition(),
|
||||
Ids::user_a(),
|
||||
Ids::user_b(),
|
||||
Ids::user_lp(),
|
||||
],
|
||||
vec![current_nonce(&state, Ids::user_lp())],
|
||||
instruction,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_lp()]);
|
||||
let tx = PublicTransaction::new(message, witness_set);
|
||||
assert!(matches!(
|
||||
state.transition_from_public_transaction(&tx, 0, block_timestamp_ms),
|
||||
Err(NssaError::OutOfValidityWindow)
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn amm_new_definition_rejects_expired_deadline() {
|
||||
let mut state = state_for_amm_tests_with_precreated_user_lp_for_new_def();
|
||||
|
||||
let deadline_ms = 1_000u64;
|
||||
let block_timestamp_ms = 2_000u64;
|
||||
|
||||
let instruction = amm_core::Instruction::NewDefinition {
|
||||
token_a_amount: Balances::vault_a_init(),
|
||||
token_b_amount: Balances::vault_b_init(),
|
||||
fees: amm_core::FEE_TIER_BPS_30,
|
||||
amm_program_id: Ids::amm_program(),
|
||||
deadline: deadline_ms,
|
||||
};
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
Ids::amm_program(),
|
||||
vec![
|
||||
Ids::pool_definition(),
|
||||
Ids::vault_a(),
|
||||
Ids::vault_b(),
|
||||
Ids::token_lp_definition(),
|
||||
Ids::lp_lock_holding(),
|
||||
Ids::user_a(),
|
||||
Ids::user_b(),
|
||||
Ids::user_lp(),
|
||||
],
|
||||
vec![
|
||||
current_nonce(&state, Ids::user_a()),
|
||||
current_nonce(&state, Ids::user_b()),
|
||||
current_nonce(&state, Ids::user_lp()),
|
||||
],
|
||||
instruction,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let witness_set = public_transaction::WitnessSet::for_message(
|
||||
&message,
|
||||
&[&Keys::user_a(), &Keys::user_b(), &Keys::user_lp()],
|
||||
);
|
||||
let tx = PublicTransaction::new(message, witness_set);
|
||||
assert!(matches!(
|
||||
state.transition_from_public_transaction(&tx, 0, block_timestamp_ms),
|
||||
Err(NssaError::OutOfValidityWindow)
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn amm_add_liquidity_after_fee_accrual() {
|
||||
let mut state = state_for_amm_tests();
|
||||
|
||||
10
token/methods/guest/Cargo.lock
generated
10
token/methods/guest/Cargo.lock
generated
@ -2864,10 +2864,11 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "spel-framework"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/logos-co/spel.git?tag=v0.2.0-rc.2#9005e9fbbd78b0530412f9987273f753ed32eb2d"
|
||||
source = "git+https://github.com/logos-co/spel.git?rev=9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3#9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3"
|
||||
dependencies = [
|
||||
"borsh",
|
||||
"nssa_core",
|
||||
"serde_json",
|
||||
"spel-framework-core",
|
||||
"spel-framework-macros",
|
||||
]
|
||||
@ -2875,24 +2876,27 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "spel-framework-core"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/logos-co/spel.git?tag=v0.2.0-rc.2#9005e9fbbd78b0530412f9987273f753ed32eb2d"
|
||||
source = "git+https://github.com/logos-co/spel.git?rev=9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3#9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3"
|
||||
dependencies = [
|
||||
"borsh",
|
||||
"nssa_core",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"syn 2.0.117",
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spel-framework-macros"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/logos-co/spel.git?tag=v0.2.0-rc.2#9005e9fbbd78b0530412f9987273f753ed32eb2d"
|
||||
source = "git+https://github.com/logos-co/spel.git?rev=9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3#9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"spel-framework-core",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ name = "token"
|
||||
path = "src/bin/token.rs"
|
||||
|
||||
[dependencies]
|
||||
spel-framework = { git = "https://github.com/logos-co/spel.git", tag = "v0.2.0-rc.2", package = "spel-framework" }
|
||||
spel-framework = { git = "https://github.com/logos-co/spel.git", rev = "9e7f2754e1d4cdb3ea36e63b1ff86c3af55488d3", package = "spel-framework" }
|
||||
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 }
|
||||
token_core = { path = "../../core" }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user