mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-05-19 15:39:28 +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
37fc2ea088
commit
216e92d25a
@ -35,6 +35,8 @@ pub enum Instruction {
|
|||||||
token_b_amount: u128,
|
token_b_amount: u128,
|
||||||
fees: u128,
|
fees: u128,
|
||||||
amm_program_id: ProgramId,
|
amm_program_id: ProgramId,
|
||||||
|
/// Unix timestamp (milliseconds) after which this transaction is invalid.
|
||||||
|
deadline: u64,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Adds liquidity to the Pool
|
/// Adds liquidity to the Pool
|
||||||
@ -51,6 +53,8 @@ pub enum Instruction {
|
|||||||
min_amount_liquidity: u128,
|
min_amount_liquidity: u128,
|
||||||
max_amount_to_add_token_a: u128,
|
max_amount_to_add_token_a: u128,
|
||||||
max_amount_to_add_token_b: u128,
|
max_amount_to_add_token_b: u128,
|
||||||
|
/// Unix timestamp (milliseconds) after which this transaction is invalid.
|
||||||
|
deadline: u64,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Removes liquidity from the Pool
|
/// Removes liquidity from the Pool
|
||||||
@ -67,6 +71,8 @@ pub enum Instruction {
|
|||||||
remove_liquidity_amount: u128,
|
remove_liquidity_amount: u128,
|
||||||
min_amount_to_remove_token_a: u128,
|
min_amount_to_remove_token_a: u128,
|
||||||
min_amount_to_remove_token_b: 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)
|
/// 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 A (initialized)
|
||||||
/// - Vault Holding Account for Token B (initialized)
|
/// - Vault Holding Account for Token B (initialized)
|
||||||
/// - User Holding Account for Token A
|
/// - User Holding Account for Token A
|
||||||
/// - User Holding Account for Token B Either User Holding Account for Token A or Token B is
|
/// - User Holding Account for Token B; either is authorized.
|
||||||
/// authorized.
|
|
||||||
SwapExactInput {
|
SwapExactInput {
|
||||||
swap_amount_in: u128,
|
swap_amount_in: u128,
|
||||||
min_amount_out: u128,
|
min_amount_out: u128,
|
||||||
token_definition_id_in: AccountId,
|
token_definition_id_in: AccountId,
|
||||||
|
/// Unix timestamp (milliseconds) after which this transaction is invalid.
|
||||||
|
deadline: u64,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Swap tokens specifying the exact desired output amount,
|
/// 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 A (initialized)
|
||||||
/// - Vault Holding Account for Token B (initialized)
|
/// - Vault Holding Account for Token B (initialized)
|
||||||
/// - User Holding Account for Token A
|
/// - User Holding Account for Token A
|
||||||
/// - User Holding Account for Token B Either User Holding Account for Token A or Token B is
|
/// - User Holding Account for Token B; either is authorized.
|
||||||
/// authorized.
|
|
||||||
SwapExactOutput {
|
SwapExactOutput {
|
||||||
exact_amount_out: u128,
|
exact_amount_out: u128,
|
||||||
max_amount_in: u128,
|
max_amount_in: u128,
|
||||||
token_definition_id_in: AccountId,
|
token_definition_id_in: AccountId,
|
||||||
|
/// Unix timestamp (milliseconds) after which this transaction is invalid.
|
||||||
|
deadline: u64,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Sync pool reserves with current vault balances.
|
/// 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]]
|
[[package]]
|
||||||
name = "spel-framework"
|
name = "spel-framework"
|
||||||
version = "0.2.0"
|
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 = [
|
dependencies = [
|
||||||
"borsh",
|
"borsh",
|
||||||
"nssa_core",
|
"nssa_core",
|
||||||
|
"serde_json",
|
||||||
"spel-framework-core",
|
"spel-framework-core",
|
||||||
"spel-framework-macros",
|
"spel-framework-macros",
|
||||||
]
|
]
|
||||||
@ -2909,24 +2910,27 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "spel-framework-core"
|
name = "spel-framework-core"
|
||||||
version = "0.2.0"
|
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 = [
|
dependencies = [
|
||||||
"borsh",
|
"borsh",
|
||||||
"nssa_core",
|
"nssa_core",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
|
"syn 2.0.117",
|
||||||
"thiserror 1.0.69",
|
"thiserror 1.0.69",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spel-framework-macros"
|
name = "spel-framework-macros"
|
||||||
version = "0.2.0"
|
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 = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
|
"spel-framework-core",
|
||||||
"syn 2.0.117",
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ name = "amm"
|
|||||||
path = "src/bin/amm.rs"
|
path = "src/bin/amm.rs"
|
||||||
|
|
||||||
[dependencies]
|
[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" }
|
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 }
|
risc0-zkvm = { version = "=3.0.5", default-features = false }
|
||||||
amm_core = { path = "../../core" }
|
amm_core = { path = "../../core" }
|
||||||
|
|||||||
@ -31,6 +31,7 @@ mod amm {
|
|||||||
token_b_amount: u128,
|
token_b_amount: u128,
|
||||||
fees: u128,
|
fees: u128,
|
||||||
amm_program_id: ProgramId,
|
amm_program_id: ProgramId,
|
||||||
|
deadline: u64,
|
||||||
) -> SpelResult {
|
) -> SpelResult {
|
||||||
let (post_states, chained_calls) = amm_program::new_definition::new_definition(
|
let (post_states, chained_calls) = amm_program::new_definition::new_definition(
|
||||||
pool,
|
pool,
|
||||||
@ -46,7 +47,8 @@ mod amm {
|
|||||||
fees,
|
fees,
|
||||||
amm_program_id,
|
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.
|
/// Adds liquidity to the Pool.
|
||||||
@ -62,6 +64,7 @@ mod amm {
|
|||||||
min_amount_liquidity: u128,
|
min_amount_liquidity: u128,
|
||||||
max_amount_to_add_token_a: u128,
|
max_amount_to_add_token_a: u128,
|
||||||
max_amount_to_add_token_b: u128,
|
max_amount_to_add_token_b: u128,
|
||||||
|
deadline: u64,
|
||||||
) -> SpelResult {
|
) -> SpelResult {
|
||||||
let (post_states, chained_calls) = amm_program::add::add_liquidity(
|
let (post_states, chained_calls) = amm_program::add::add_liquidity(
|
||||||
pool,
|
pool,
|
||||||
@ -75,7 +78,8 @@ mod amm {
|
|||||||
max_amount_to_add_token_a,
|
max_amount_to_add_token_a,
|
||||||
max_amount_to_add_token_b,
|
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.
|
/// Removes liquidity from the Pool.
|
||||||
@ -91,6 +95,7 @@ mod amm {
|
|||||||
remove_liquidity_amount: u128,
|
remove_liquidity_amount: u128,
|
||||||
min_amount_to_remove_token_a: u128,
|
min_amount_to_remove_token_a: u128,
|
||||||
min_amount_to_remove_token_b: u128,
|
min_amount_to_remove_token_b: u128,
|
||||||
|
deadline: u64,
|
||||||
) -> SpelResult {
|
) -> SpelResult {
|
||||||
let (post_states, chained_calls) = amm_program::remove::remove_liquidity(
|
let (post_states, chained_calls) = amm_program::remove::remove_liquidity(
|
||||||
pool,
|
pool,
|
||||||
@ -105,7 +110,8 @@ mod amm {
|
|||||||
min_amount_to_remove_token_a,
|
min_amount_to_remove_token_a,
|
||||||
min_amount_to_remove_token_b,
|
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.
|
/// Swap some quantity of tokens while maintaining the pool constant product.
|
||||||
@ -119,6 +125,7 @@ mod amm {
|
|||||||
swap_amount_in: u128,
|
swap_amount_in: u128,
|
||||||
min_amount_out: u128,
|
min_amount_out: u128,
|
||||||
token_definition_id_in: AccountId,
|
token_definition_id_in: AccountId,
|
||||||
|
deadline: u64,
|
||||||
) -> SpelResult {
|
) -> SpelResult {
|
||||||
let (post_states, chained_calls) = amm_program::swap::swap_exact_input(
|
let (post_states, chained_calls) = amm_program::swap::swap_exact_input(
|
||||||
pool,
|
pool,
|
||||||
@ -130,7 +137,8 @@ mod amm {
|
|||||||
min_amount_out,
|
min_amount_out,
|
||||||
token_definition_id_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))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Swap tokens specifying the exact desired output amount.
|
/// Swap tokens specifying the exact desired output amount.
|
||||||
@ -144,6 +152,7 @@ mod amm {
|
|||||||
exact_amount_out: u128,
|
exact_amount_out: u128,
|
||||||
max_amount_in: u128,
|
max_amount_in: u128,
|
||||||
token_definition_id_in: AccountId,
|
token_definition_id_in: AccountId,
|
||||||
|
deadline: u64,
|
||||||
) -> SpelResult {
|
) -> SpelResult {
|
||||||
let (post_states, chained_calls) = amm_program::swap::swap_exact_output(
|
let (post_states, chained_calls) = amm_program::swap::swap_exact_output(
|
||||||
pool,
|
pool,
|
||||||
@ -155,7 +164,8 @@ mod amm {
|
|||||||
max_amount_in,
|
max_amount_in,
|
||||||
token_definition_id_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.
|
/// Sync pool reserves with current vault balances.
|
||||||
|
|||||||
@ -70,6 +70,10 @@
|
|||||||
{
|
{
|
||||||
"name": "amm_program_id",
|
"name": "amm_program_id",
|
||||||
"type": "program_id"
|
"type": "program_id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deadline",
|
||||||
|
"type": "u64"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -131,6 +135,10 @@
|
|||||||
{
|
{
|
||||||
"name": "max_amount_to_add_token_b",
|
"name": "max_amount_to_add_token_b",
|
||||||
"type": "u128"
|
"type": "u128"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deadline",
|
||||||
|
"type": "u64"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -192,6 +200,10 @@
|
|||||||
{
|
{
|
||||||
"name": "min_amount_to_remove_token_b",
|
"name": "min_amount_to_remove_token_b",
|
||||||
"type": "u128"
|
"type": "u128"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deadline",
|
||||||
|
"type": "u64"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -241,6 +253,10 @@
|
|||||||
{
|
{
|
||||||
"name": "token_definition_id_in",
|
"name": "token_definition_id_in",
|
||||||
"type": "account_id"
|
"type": "account_id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deadline",
|
||||||
|
"type": "u64"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -290,6 +306,10 @@
|
|||||||
{
|
{
|
||||||
"name": "token_definition_id_in",
|
"name": "token_definition_id_in",
|
||||||
"type": "account_id"
|
"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]]
|
[[package]]
|
||||||
name = "spel-framework"
|
name = "spel-framework"
|
||||||
version = "0.2.0"
|
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 = [
|
dependencies = [
|
||||||
"borsh",
|
"borsh",
|
||||||
"nssa_core",
|
"nssa_core",
|
||||||
|
"serde_json",
|
||||||
"spel-framework-core",
|
"spel-framework-core",
|
||||||
"spel-framework-macros",
|
"spel-framework-macros",
|
||||||
]
|
]
|
||||||
@ -2908,24 +2909,27 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "spel-framework-core"
|
name = "spel-framework-core"
|
||||||
version = "0.2.0"
|
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 = [
|
dependencies = [
|
||||||
"borsh",
|
"borsh",
|
||||||
"nssa_core",
|
"nssa_core",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
|
"syn 2.0.117",
|
||||||
"thiserror 1.0.69",
|
"thiserror 1.0.69",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spel-framework-macros"
|
name = "spel-framework-macros"
|
||||||
version = "0.2.0"
|
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 = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
|
"spel-framework-core",
|
||||||
"syn 2.0.117",
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ name = "ata"
|
|||||||
path = "src/bin/ata.rs"
|
path = "src/bin/ata.rs"
|
||||||
|
|
||||||
[dependencies]
|
[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" }
|
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 }
|
risc0-zkvm = { version = "=3.0.5", default-features = false }
|
||||||
ata_core = { path = "../../core" }
|
ata_core = { path = "../../core" }
|
||||||
|
|||||||
@ -966,6 +966,7 @@ fn try_execute_new_definition(
|
|||||||
token_b_amount: Balances::vault_b_init(),
|
token_b_amount: Balances::vault_b_init(),
|
||||||
fees,
|
fees,
|
||||||
amm_program_id: Ids::amm_program(),
|
amm_program_id: Ids::amm_program(),
|
||||||
|
deadline: u64::MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
let message = public_transaction::Message::try_new(
|
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,
|
swap_amount_in,
|
||||||
min_amount_out,
|
min_amount_out,
|
||||||
token_definition_id_in: Ids::token_a_definition(),
|
token_definition_id_in: Ids::token_a_definition(),
|
||||||
|
deadline: u64::MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
let message = public_transaction::Message::try_new(
|
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,
|
swap_amount_in,
|
||||||
min_amount_out,
|
min_amount_out,
|
||||||
token_definition_id_in: Ids::token_b_definition(),
|
token_definition_id_in: Ids::token_b_definition(),
|
||||||
|
deadline: u64::MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
let message = public_transaction::Message::try_new(
|
let message = public_transaction::Message::try_new(
|
||||||
@ -1077,6 +1080,7 @@ fn execute_add_liquidity(
|
|||||||
min_amount_liquidity,
|
min_amount_liquidity,
|
||||||
max_amount_to_add_token_a,
|
max_amount_to_add_token_a,
|
||||||
max_amount_to_add_token_b,
|
max_amount_to_add_token_b,
|
||||||
|
deadline: u64::MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
let message = public_transaction::Message::try_new(
|
let message = public_transaction::Message::try_new(
|
||||||
@ -1115,6 +1119,7 @@ fn execute_remove_liquidity(
|
|||||||
remove_liquidity_amount,
|
remove_liquidity_amount,
|
||||||
min_amount_to_remove_token_a,
|
min_amount_to_remove_token_a,
|
||||||
min_amount_to_remove_token_b,
|
min_amount_to_remove_token_b,
|
||||||
|
deadline: u64::MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
let message = public_transaction::Message::try_new(
|
let message = public_transaction::Message::try_new(
|
||||||
@ -1178,6 +1183,7 @@ fn amm_remove_liquidity() {
|
|||||||
remove_liquidity_amount: Balances::remove_lp(),
|
remove_liquidity_amount: Balances::remove_lp(),
|
||||||
min_amount_to_remove_token_a: Balances::remove_min_a(),
|
min_amount_to_remove_token_a: Balances::remove_min_a(),
|
||||||
min_amount_to_remove_token_b: Balances::remove_min_b(),
|
min_amount_to_remove_token_b: Balances::remove_min_b(),
|
||||||
|
deadline: u64::MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
let message = public_transaction::Message::try_new(
|
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(),
|
remove_liquidity_amount: Balances::remove_lp(),
|
||||||
min_amount_to_remove_token_a: Balances::remove_min_a(),
|
min_amount_to_remove_token_a: Balances::remove_min_a(),
|
||||||
min_amount_to_remove_token_b: Balances::remove_min_b(),
|
min_amount_to_remove_token_b: Balances::remove_min_b(),
|
||||||
|
deadline: u64::MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
let message = public_transaction::Message::try_new(
|
let message = public_transaction::Message::try_new(
|
||||||
@ -1464,6 +1471,7 @@ fn amm_add_liquidity() {
|
|||||||
min_amount_liquidity: Balances::add_min_lp(),
|
min_amount_liquidity: Balances::add_min_lp(),
|
||||||
max_amount_to_add_token_a: Balances::add_max_a(),
|
max_amount_to_add_token_a: Balances::add_max_a(),
|
||||||
max_amount_to_add_token_b: Balances::add_max_b(),
|
max_amount_to_add_token_b: Balances::add_max_b(),
|
||||||
|
deadline: u64::MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
let message = public_transaction::Message::try_new(
|
let message = public_transaction::Message::try_new(
|
||||||
@ -1526,6 +1534,7 @@ fn amm_swap_b_to_a() {
|
|||||||
swap_amount_in: Balances::swap_amount_in(),
|
swap_amount_in: Balances::swap_amount_in(),
|
||||||
min_amount_out: Balances::swap_min_out(),
|
min_amount_out: Balances::swap_min_out(),
|
||||||
token_definition_id_in: Ids::token_b_definition(),
|
token_definition_id_in: Ids::token_b_definition(),
|
||||||
|
deadline: u64::MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
let message = public_transaction::Message::try_new(
|
let message = public_transaction::Message::try_new(
|
||||||
@ -1577,6 +1586,7 @@ fn amm_swap_a_to_b() {
|
|||||||
swap_amount_in: Balances::swap_amount_in(),
|
swap_amount_in: Balances::swap_amount_in(),
|
||||||
min_amount_out: Balances::swap_min_out(),
|
min_amount_out: Balances::swap_min_out(),
|
||||||
token_definition_id_in: Ids::token_a_definition(),
|
token_definition_id_in: Ids::token_a_definition(),
|
||||||
|
deadline: u64::MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
let message = public_transaction::Message::try_new(
|
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]
|
#[test]
|
||||||
fn amm_add_liquidity_after_fee_accrual() {
|
fn amm_add_liquidity_after_fee_accrual() {
|
||||||
let mut state = state_for_amm_tests();
|
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]]
|
[[package]]
|
||||||
name = "spel-framework"
|
name = "spel-framework"
|
||||||
version = "0.2.0"
|
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 = [
|
dependencies = [
|
||||||
"borsh",
|
"borsh",
|
||||||
"nssa_core",
|
"nssa_core",
|
||||||
|
"serde_json",
|
||||||
"spel-framework-core",
|
"spel-framework-core",
|
||||||
"spel-framework-macros",
|
"spel-framework-macros",
|
||||||
]
|
]
|
||||||
@ -2875,24 +2876,27 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "spel-framework-core"
|
name = "spel-framework-core"
|
||||||
version = "0.2.0"
|
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 = [
|
dependencies = [
|
||||||
"borsh",
|
"borsh",
|
||||||
"nssa_core",
|
"nssa_core",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
|
"syn 2.0.117",
|
||||||
"thiserror 1.0.69",
|
"thiserror 1.0.69",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spel-framework-macros"
|
name = "spel-framework-macros"
|
||||||
version = "0.2.0"
|
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 = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
|
"spel-framework-core",
|
||||||
"syn 2.0.117",
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ name = "token"
|
|||||||
path = "src/bin/token.rs"
|
path = "src/bin/token.rs"
|
||||||
|
|
||||||
[dependencies]
|
[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" }
|
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 }
|
risc0-zkvm = { version = "=3.0.5", default-features = false }
|
||||||
token_core = { path = "../../core" }
|
token_core = { path = "../../core" }
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user