mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-05-19 07:29:32 +00:00
chore(lint): add staged lint baseline
This commit is contained in:
parent
6b21c3695a
commit
b7c6efee9c
17
.github/workflows/ci.yml
vendored
17
.github/workflows/ci.yml
vendored
@ -59,7 +59,22 @@ jobs:
|
|||||||
${{ runner.os }}-cargo-
|
${{ runner.os }}-cargo-
|
||||||
|
|
||||||
- name: Clippy
|
- name: Clippy
|
||||||
run: RISC0_SKIP_BUILD=1 cargo clippy --workspace --all-targets -- -D warnings
|
run: |
|
||||||
|
if grep -R -n -E '#\[(allow|expect)\([^]]*reason[[:space:]]*=[[:space:]]*"(TODO|FIXME|fix later|later|temporary|hack)' --include='*.rs' token amm ata integration_tests tools; then
|
||||||
|
echo "Found non-actionable lint suppression reason"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
RISC0_SKIP_BUILD=1 cargo clippy --workspace --all-targets -- -D warnings
|
||||||
|
|
||||||
|
- name: Guest Clippy
|
||||||
|
run: |
|
||||||
|
for manifest in \
|
||||||
|
token/methods/guest/Cargo.toml \
|
||||||
|
amm/methods/guest/Cargo.toml \
|
||||||
|
ata/methods/guest/Cargo.toml
|
||||||
|
do
|
||||||
|
cargo clippy --manifest-path "$manifest" --all-targets -- -D warnings
|
||||||
|
done
|
||||||
|
|
||||||
unit-tests:
|
unit-tests:
|
||||||
name: Unit Tests
|
name: Unit Tests
|
||||||
|
|||||||
38
Cargo.toml
38
Cargo.toml
@ -33,3 +33,41 @@ borsh = { version = "1.0", features = ["derive"] }
|
|||||||
risc0-zkvm = { version = "=3.0.5" }
|
risc0-zkvm = { version = "=3.0.5" }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
tokio = { version = "1.28.2", features = ["net", "rt-multi-thread", "sync", "macros"] }
|
tokio = { version = "1.28.2", features = ["net", "rt-multi-thread", "sync", "macros"] }
|
||||||
|
|
||||||
|
[workspace.lints.rust]
|
||||||
|
rust_2018_idioms = { level = "deny", priority = -1 }
|
||||||
|
unsafe_code = "forbid"
|
||||||
|
|
||||||
|
[workspace.lints.clippy]
|
||||||
|
all = { level = "deny", priority = -1 }
|
||||||
|
|
||||||
|
# Generated-code / placeholder blockers.
|
||||||
|
dbg_macro = "deny"
|
||||||
|
todo = "deny"
|
||||||
|
unimplemented = "deny"
|
||||||
|
unwrap_used = "deny"
|
||||||
|
|
||||||
|
# Lint suppression hygiene.
|
||||||
|
allow_attributes = "warn"
|
||||||
|
allow_attributes_without_reason = "deny"
|
||||||
|
|
||||||
|
# Determinism, panic-safety, and arithmetic correctness.
|
||||||
|
arithmetic_side_effects = "deny"
|
||||||
|
indexing_slicing = "deny"
|
||||||
|
integer_division = "warn"
|
||||||
|
|
||||||
|
# Cast discipline.
|
||||||
|
as_conversions = "deny"
|
||||||
|
cast_possible_truncation = "deny"
|
||||||
|
cast_possible_wrap = "deny"
|
||||||
|
cast_precision_loss = "warn"
|
||||||
|
cast_sign_loss = "deny"
|
||||||
|
|
||||||
|
# API and enum evolution.
|
||||||
|
large_enum_variant = "deny"
|
||||||
|
match_wildcard_for_single_variants = "warn"
|
||||||
|
wildcard_enum_match_arm = "deny"
|
||||||
|
|
||||||
|
# Too noisy for this codebase unless enforced selectively.
|
||||||
|
module_name_repetitions = "allow"
|
||||||
|
similar_names = "allow"
|
||||||
|
|||||||
@ -3,6 +3,9 @@ name = "amm_program"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc1", features = ["host"] }
|
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc1", features = ["host"] }
|
||||||
amm_core = { path = "core" }
|
amm_core = { path = "core" }
|
||||||
|
|||||||
@ -3,6 +3,9 @@ name = "amm_core"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc1", features = ["host"] }
|
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc1", features = ["host"] }
|
||||||
token_core = { path = "../../token/core" }
|
token_core = { path = "../../token/core" }
|
||||||
|
|||||||
@ -203,8 +203,9 @@ pub fn compute_pool_pda_seed(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut bytes = [0; 64];
|
let mut bytes = [0; 64];
|
||||||
bytes[0..32].copy_from_slice(&token_1.to_bytes());
|
let (token_1_bytes, token_2_bytes) = bytes.split_at_mut(32);
|
||||||
bytes[32..].copy_from_slice(&token_2.to_bytes());
|
token_1_bytes.copy_from_slice(&token_1.to_bytes());
|
||||||
|
token_2_bytes.copy_from_slice(&token_2.to_bytes());
|
||||||
|
|
||||||
PdaSeed::new(
|
PdaSeed::new(
|
||||||
Impl::hash_bytes(&bytes)
|
Impl::hash_bytes(&bytes)
|
||||||
@ -229,8 +230,9 @@ pub fn compute_vault_pda_seed(pool_id: AccountId, definition_token_id: AccountId
|
|||||||
use risc0_zkvm::sha::{Impl, Sha256};
|
use risc0_zkvm::sha::{Impl, Sha256};
|
||||||
|
|
||||||
let mut bytes = [0; 64];
|
let mut bytes = [0; 64];
|
||||||
bytes[0..32].copy_from_slice(&pool_id.to_bytes());
|
let (pool_bytes, definition_bytes) = bytes.split_at_mut(32);
|
||||||
bytes[32..].copy_from_slice(&definition_token_id.to_bytes());
|
pool_bytes.copy_from_slice(&pool_id.to_bytes());
|
||||||
|
definition_bytes.copy_from_slice(&definition_token_id.to_bytes());
|
||||||
|
|
||||||
PdaSeed::new(
|
PdaSeed::new(
|
||||||
Impl::hash_bytes(&bytes)
|
Impl::hash_bytes(&bytes)
|
||||||
@ -248,8 +250,9 @@ pub fn compute_liquidity_token_pda_seed(pool_id: AccountId) -> PdaSeed {
|
|||||||
use risc0_zkvm::sha::{Impl, Sha256};
|
use risc0_zkvm::sha::{Impl, Sha256};
|
||||||
|
|
||||||
let mut bytes = [0; 64];
|
let mut bytes = [0; 64];
|
||||||
bytes[0..32].copy_from_slice(&pool_id.to_bytes());
|
let (pool_bytes, seed_bytes) = bytes.split_at_mut(32);
|
||||||
bytes[32..].copy_from_slice(&LIQUIDITY_TOKEN_PDA_SEED);
|
pool_bytes.copy_from_slice(&pool_id.to_bytes());
|
||||||
|
seed_bytes.copy_from_slice(&LIQUIDITY_TOKEN_PDA_SEED);
|
||||||
|
|
||||||
PdaSeed::new(
|
PdaSeed::new(
|
||||||
Impl::hash_bytes(&bytes)
|
Impl::hash_bytes(&bytes)
|
||||||
@ -267,8 +270,9 @@ pub fn compute_lp_lock_holding_pda_seed(pool_id: AccountId) -> PdaSeed {
|
|||||||
use risc0_zkvm::sha::{Impl, Sha256};
|
use risc0_zkvm::sha::{Impl, Sha256};
|
||||||
|
|
||||||
let mut bytes = [0; 64];
|
let mut bytes = [0; 64];
|
||||||
bytes[0..32].copy_from_slice(&pool_id.to_bytes());
|
let (pool_bytes, seed_bytes) = bytes.split_at_mut(32);
|
||||||
bytes[32..].copy_from_slice(&LP_LOCK_HOLDING_PDA_SEED);
|
pool_bytes.copy_from_slice(&pool_id.to_bytes());
|
||||||
|
seed_bytes.copy_from_slice(&LP_LOCK_HOLDING_PDA_SEED);
|
||||||
|
|
||||||
PdaSeed::new(
|
PdaSeed::new(
|
||||||
Impl::hash_bytes(&bytes)
|
Impl::hash_bytes(&bytes)
|
||||||
|
|||||||
@ -3,6 +3,9 @@ name = "amm-methods"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
risc0-build = "=3.0.5"
|
risc0-build = "=3.0.5"
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,32 @@ edition = "2021"
|
|||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
|
|
||||||
|
[lints.rust]
|
||||||
|
rust_2018_idioms = { level = "deny", priority = -1 }
|
||||||
|
unsafe_code = "forbid"
|
||||||
|
|
||||||
|
[lints.clippy]
|
||||||
|
all = { level = "deny", priority = -1 }
|
||||||
|
allow_attributes = "warn"
|
||||||
|
allow_attributes_without_reason = "deny"
|
||||||
|
arithmetic_side_effects = "deny"
|
||||||
|
as_conversions = "deny"
|
||||||
|
cast_possible_truncation = "deny"
|
||||||
|
cast_possible_wrap = "deny"
|
||||||
|
cast_precision_loss = "warn"
|
||||||
|
cast_sign_loss = "deny"
|
||||||
|
dbg_macro = "deny"
|
||||||
|
indexing_slicing = "deny"
|
||||||
|
integer_division = "warn"
|
||||||
|
large_enum_variant = "deny"
|
||||||
|
match_wildcard_for_single_variants = "warn"
|
||||||
|
module_name_repetitions = "allow"
|
||||||
|
similar_names = "allow"
|
||||||
|
todo = "deny"
|
||||||
|
unimplemented = "deny"
|
||||||
|
unwrap_used = "deny"
|
||||||
|
wildcard_enum_match_arm = "deny"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "amm"
|
name = "amm"
|
||||||
path = "src/bin/amm.rs"
|
path = "src/bin/amm.rs"
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#![no_main]
|
#![cfg_attr(not(test), no_main)]
|
||||||
|
|
||||||
use std::num::NonZeroU128;
|
use std::num::NonZeroU128;
|
||||||
|
|
||||||
@ -8,15 +8,27 @@ use nssa_core::{
|
|||||||
program::ProgramId,
|
program::ProgramId,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
risc0_zkvm::guest::entry!(main);
|
risc0_zkvm::guest::entry!(main);
|
||||||
|
|
||||||
#[lez_program(instruction = "amm_core::Instruction")]
|
#[lez_program(instruction = "amm_core::Instruction")]
|
||||||
mod amm {
|
mod amm {
|
||||||
#[allow(unused_imports)]
|
#[expect(
|
||||||
|
unused_imports,
|
||||||
|
reason = "SPEL instruction macro requires importing parent-scope handler types"
|
||||||
|
)]
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// Initializes a new Pool (or re-initializes an existing zero-supply Pool).
|
/// Initializes a new Pool (or re-initializes an existing zero-supply Pool).
|
||||||
/// A fresh user LP holding must be explicitly authorized by the caller.
|
/// A fresh user LP holding must be explicitly authorized by the caller.
|
||||||
|
#[expect(
|
||||||
|
clippy::too_many_arguments,
|
||||||
|
reason = "instruction ABI exposes explicit pool, vault, mint, lock, and user accounts"
|
||||||
|
)]
|
||||||
|
#[expect(
|
||||||
|
deprecated,
|
||||||
|
reason = "AMM guest chained-call wrapper remains until auto-claim migration is scoped"
|
||||||
|
)]
|
||||||
#[instruction]
|
#[instruction]
|
||||||
pub fn new_definition(
|
pub fn new_definition(
|
||||||
pool: AccountWithMetadata,
|
pool: AccountWithMetadata,
|
||||||
@ -52,6 +64,14 @@ mod amm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Adds liquidity to the Pool.
|
/// Adds liquidity to the Pool.
|
||||||
|
#[expect(
|
||||||
|
clippy::too_many_arguments,
|
||||||
|
reason = "instruction ABI exposes explicit pool, vault, and user accounts"
|
||||||
|
)]
|
||||||
|
#[expect(
|
||||||
|
deprecated,
|
||||||
|
reason = "AMM guest chained-call wrapper remains until auto-claim migration is scoped"
|
||||||
|
)]
|
||||||
#[instruction]
|
#[instruction]
|
||||||
pub fn add_liquidity(
|
pub fn add_liquidity(
|
||||||
pool: AccountWithMetadata,
|
pool: AccountWithMetadata,
|
||||||
@ -83,6 +103,14 @@ mod amm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Removes liquidity from the Pool.
|
/// Removes liquidity from the Pool.
|
||||||
|
#[expect(
|
||||||
|
clippy::too_many_arguments,
|
||||||
|
reason = "instruction ABI exposes explicit pool, vault, and user accounts"
|
||||||
|
)]
|
||||||
|
#[expect(
|
||||||
|
deprecated,
|
||||||
|
reason = "AMM guest chained-call wrapper remains until auto-claim migration is scoped"
|
||||||
|
)]
|
||||||
#[instruction]
|
#[instruction]
|
||||||
pub fn remove_liquidity(
|
pub fn remove_liquidity(
|
||||||
pool: AccountWithMetadata,
|
pool: AccountWithMetadata,
|
||||||
@ -115,6 +143,14 @@ mod amm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Swap some quantity of tokens while maintaining the pool constant product.
|
/// Swap some quantity of tokens while maintaining the pool constant product.
|
||||||
|
#[expect(
|
||||||
|
clippy::too_many_arguments,
|
||||||
|
reason = "instruction ABI exposes explicit pool, vault, user accounts, and bounds"
|
||||||
|
)]
|
||||||
|
#[expect(
|
||||||
|
deprecated,
|
||||||
|
reason = "AMM guest chained-call wrapper remains until auto-claim migration is scoped"
|
||||||
|
)]
|
||||||
#[instruction]
|
#[instruction]
|
||||||
pub fn swap_exact_input(
|
pub fn swap_exact_input(
|
||||||
pool: AccountWithMetadata,
|
pool: AccountWithMetadata,
|
||||||
@ -142,6 +178,14 @@ mod amm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Swap tokens specifying the exact desired output amount.
|
/// Swap tokens specifying the exact desired output amount.
|
||||||
|
#[expect(
|
||||||
|
clippy::too_many_arguments,
|
||||||
|
reason = "instruction ABI exposes explicit pool, vault, user accounts, and bounds"
|
||||||
|
)]
|
||||||
|
#[expect(
|
||||||
|
deprecated,
|
||||||
|
reason = "AMM guest chained-call wrapper remains until auto-claim migration is scoped"
|
||||||
|
)]
|
||||||
#[instruction]
|
#[instruction]
|
||||||
pub fn swap_exact_output(
|
pub fn swap_exact_output(
|
||||||
pool: AccountWithMetadata,
|
pool: AccountWithMetadata,
|
||||||
@ -169,6 +213,10 @@ mod amm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sync pool reserves with current vault balances.
|
/// Sync pool reserves with current vault balances.
|
||||||
|
#[expect(
|
||||||
|
deprecated,
|
||||||
|
reason = "AMM guest chained-call wrapper remains until auto-claim migration is scoped"
|
||||||
|
)]
|
||||||
#[instruction]
|
#[instruction]
|
||||||
pub fn sync_reserves(
|
pub fn sync_reserves(
|
||||||
pool: AccountWithMetadata,
|
pool: AccountWithMetadata,
|
||||||
|
|||||||
@ -9,7 +9,10 @@ use nssa_core::{
|
|||||||
program::{AccountPostState, ChainedCall},
|
program::{AccountPostState, ChainedCall},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[expect(clippy::too_many_arguments, reason = "TODO: Fix later")]
|
#[expect(
|
||||||
|
clippy::too_many_arguments,
|
||||||
|
reason = "instruction surface passes explicit pool, vault, and user accounts"
|
||||||
|
)]
|
||||||
pub fn add_liquidity(
|
pub fn add_liquidity(
|
||||||
pool: AccountWithMetadata,
|
pool: AccountWithMetadata,
|
||||||
vault_a: AccountWithMetadata,
|
vault_a: AccountWithMetadata,
|
||||||
@ -67,12 +70,14 @@ pub fn add_liquidity(
|
|||||||
.reserve_a
|
.reserve_a
|
||||||
.checked_mul(max_amount_to_add_token_b)
|
.checked_mul(max_amount_to_add_token_b)
|
||||||
.expect("reserve_a * max_amount_b overflows u128")
|
.expect("reserve_a * max_amount_b overflows u128")
|
||||||
/ pool_def_data.reserve_b;
|
.checked_div(pool_def_data.reserve_b)
|
||||||
|
.expect("reserve_b must be nonzero after validation");
|
||||||
let ideal_b: u128 = pool_def_data
|
let ideal_b: u128 = pool_def_data
|
||||||
.reserve_b
|
.reserve_b
|
||||||
.checked_mul(max_amount_to_add_token_a)
|
.checked_mul(max_amount_to_add_token_a)
|
||||||
.expect("reserve_b * max_amount_a overflows u128")
|
.expect("reserve_b * max_amount_a overflows u128")
|
||||||
/ pool_def_data.reserve_a;
|
.checked_div(pool_def_data.reserve_a)
|
||||||
|
.expect("reserve_a must be nonzero after validation");
|
||||||
|
|
||||||
let actual_amount_a = if ideal_a > max_amount_to_add_token_a {
|
let actual_amount_a = if ideal_a > max_amount_to_add_token_a {
|
||||||
max_amount_to_add_token_a
|
max_amount_to_add_token_a
|
||||||
@ -104,12 +109,14 @@ pub fn add_liquidity(
|
|||||||
.liquidity_pool_supply
|
.liquidity_pool_supply
|
||||||
.checked_mul(actual_amount_a)
|
.checked_mul(actual_amount_a)
|
||||||
.expect("liquidity_pool_supply * actual_amount_a overflows u128")
|
.expect("liquidity_pool_supply * actual_amount_a overflows u128")
|
||||||
/ pool_def_data.reserve_a,
|
.checked_div(pool_def_data.reserve_a)
|
||||||
|
.expect("reserve_a must be nonzero after validation"),
|
||||||
pool_def_data
|
pool_def_data
|
||||||
.liquidity_pool_supply
|
.liquidity_pool_supply
|
||||||
.checked_mul(actual_amount_b)
|
.checked_mul(actual_amount_b)
|
||||||
.expect("liquidity_pool_supply * actual_amount_b overflows u128")
|
.expect("liquidity_pool_supply * actual_amount_b overflows u128")
|
||||||
/ pool_def_data.reserve_b,
|
.checked_div(pool_def_data.reserve_b)
|
||||||
|
.expect("reserve_b must be nonzero after validation"),
|
||||||
);
|
);
|
||||||
|
|
||||||
assert!(delta_lp != 0, "Payable LP must be nonzero");
|
assert!(delta_lp != 0, "Payable LP must be nonzero");
|
||||||
|
|||||||
@ -12,7 +12,10 @@ use nssa_core::{
|
|||||||
};
|
};
|
||||||
use token_core::TokenDefinition;
|
use token_core::TokenDefinition;
|
||||||
|
|
||||||
#[expect(clippy::too_many_arguments, reason = "TODO: Fix later")]
|
#[expect(
|
||||||
|
clippy::too_many_arguments,
|
||||||
|
reason = "instruction surface passes explicit pool, vault, mint, lock, and user accounts"
|
||||||
|
)]
|
||||||
pub fn new_definition(
|
pub fn new_definition(
|
||||||
pool: AccountWithMetadata,
|
pool: AccountWithMetadata,
|
||||||
vault_a: AccountWithMetadata,
|
vault_a: AccountWithMetadata,
|
||||||
@ -94,7 +97,9 @@ pub fn new_definition(
|
|||||||
initial_lp > MINIMUM_LIQUIDITY,
|
initial_lp > MINIMUM_LIQUIDITY,
|
||||||
"Initial liquidity must exceed minimum liquidity lock"
|
"Initial liquidity must exceed minimum liquidity lock"
|
||||||
);
|
);
|
||||||
let user_lp = initial_lp - MINIMUM_LIQUIDITY;
|
let user_lp = initial_lp
|
||||||
|
.checked_sub(MINIMUM_LIQUIDITY)
|
||||||
|
.expect("initial liquidity must exceed minimum liquidity after validation");
|
||||||
|
|
||||||
// Update pool account
|
// Update pool account
|
||||||
let mut pool_post = pool.account.clone();
|
let mut pool_post = pool.account.clone();
|
||||||
|
|||||||
@ -9,7 +9,10 @@ use nssa_core::{
|
|||||||
program::{AccountPostState, ChainedCall},
|
program::{AccountPostState, ChainedCall},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[expect(clippy::too_many_arguments, reason = "TODO: Fix later")]
|
#[expect(
|
||||||
|
clippy::too_many_arguments,
|
||||||
|
reason = "instruction surface passes explicit pool, vault, and user accounts"
|
||||||
|
)]
|
||||||
pub fn remove_liquidity(
|
pub fn remove_liquidity(
|
||||||
pool: AccountWithMetadata,
|
pool: AccountWithMetadata,
|
||||||
vault_a: AccountWithMetadata,
|
vault_a: AccountWithMetadata,
|
||||||
@ -91,7 +94,10 @@ pub fn remove_liquidity(
|
|||||||
pool_def_data.liquidity_pool_supply > MINIMUM_LIQUIDITY,
|
pool_def_data.liquidity_pool_supply > MINIMUM_LIQUIDITY,
|
||||||
"Pool only contains locked liquidity"
|
"Pool only contains locked liquidity"
|
||||||
);
|
);
|
||||||
let unlocked_liquidity = pool_def_data.liquidity_pool_supply - MINIMUM_LIQUIDITY;
|
let unlocked_liquidity = pool_def_data
|
||||||
|
.liquidity_pool_supply
|
||||||
|
.checked_sub(MINIMUM_LIQUIDITY)
|
||||||
|
.expect("liquidity supply must be at least the locked minimum after validation");
|
||||||
// The remove instruction never sees the LP lock account directly, so we must still refuse any
|
// The remove instruction never sees the LP lock account directly, so we must still refuse any
|
||||||
// request that would burn through the permanent floor even if ownership is already corrupted.
|
// request that would burn through the permanent floor even if ownership is already corrupted.
|
||||||
assert!(
|
assert!(
|
||||||
@ -103,12 +109,14 @@ pub fn remove_liquidity(
|
|||||||
.reserve_a
|
.reserve_a
|
||||||
.checked_mul(remove_liquidity_amount)
|
.checked_mul(remove_liquidity_amount)
|
||||||
.expect("reserve_a * remove_liquidity_amount overflows u128")
|
.expect("reserve_a * remove_liquidity_amount overflows u128")
|
||||||
/ pool_def_data.liquidity_pool_supply;
|
.checked_div(pool_def_data.liquidity_pool_supply)
|
||||||
|
.expect("liquidity supply must be nonzero after validation");
|
||||||
let withdraw_amount_b = pool_def_data
|
let withdraw_amount_b = pool_def_data
|
||||||
.reserve_b
|
.reserve_b
|
||||||
.checked_mul(remove_liquidity_amount)
|
.checked_mul(remove_liquidity_amount)
|
||||||
.expect("reserve_b * remove_liquidity_amount overflows u128")
|
.expect("reserve_b * remove_liquidity_amount overflows u128")
|
||||||
/ pool_def_data.liquidity_pool_supply;
|
.checked_div(pool_def_data.liquidity_pool_supply)
|
||||||
|
.expect("liquidity supply must be nonzero after validation");
|
||||||
|
|
||||||
// 3. Validate and slippage check
|
// 3. Validate and slippage check
|
||||||
assert!(
|
assert!(
|
||||||
|
|||||||
@ -46,7 +46,10 @@ fn validate_swap_setup(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates post-state and returns reserves after swap.
|
/// Creates post-state and returns reserves after swap.
|
||||||
#[expect(clippy::too_many_arguments, reason = "TODO: Fix later")]
|
#[expect(
|
||||||
|
clippy::too_many_arguments,
|
||||||
|
reason = "post-state assembly keeps pool, vault, user account, and delta state explicit"
|
||||||
|
)]
|
||||||
#[expect(
|
#[expect(
|
||||||
clippy::needless_pass_by_value,
|
clippy::needless_pass_by_value,
|
||||||
reason = "consistent with codebase style"
|
reason = "consistent with codebase style"
|
||||||
@ -91,7 +94,10 @@ fn create_swap_post_states(
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[expect(clippy::too_many_arguments, reason = "TODO: Fix later")]
|
#[expect(
|
||||||
|
clippy::too_many_arguments,
|
||||||
|
reason = "instruction surface passes explicit pool, vault, and user accounts"
|
||||||
|
)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn swap_exact_input(
|
pub fn swap_exact_input(
|
||||||
pool: AccountWithMetadata,
|
pool: AccountWithMetadata,
|
||||||
@ -156,7 +162,10 @@ pub fn swap_exact_input(
|
|||||||
(post_states, chained_calls)
|
(post_states, chained_calls)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[expect(clippy::too_many_arguments, reason = "TODO: Fix later")]
|
#[expect(
|
||||||
|
clippy::too_many_arguments,
|
||||||
|
reason = "swap calculation keeps account context and pricing parameters explicit"
|
||||||
|
)]
|
||||||
fn swap_logic(
|
fn swap_logic(
|
||||||
user_deposit: AccountWithMetadata,
|
user_deposit: AccountWithMetadata,
|
||||||
vault_deposit: AccountWithMetadata,
|
vault_deposit: AccountWithMetadata,
|
||||||
@ -169,10 +178,14 @@ fn swap_logic(
|
|||||||
reserve_withdraw_vault_amount: u128,
|
reserve_withdraw_vault_amount: u128,
|
||||||
pool_id: AccountId,
|
pool_id: AccountId,
|
||||||
) -> (Vec<ChainedCall>, u128, u128) {
|
) -> (Vec<ChainedCall>, u128, u128) {
|
||||||
|
let fee_multiplier = FEE_BPS_DENOMINATOR
|
||||||
|
.checked_sub(fee_bps)
|
||||||
|
.expect("fee_bps exceeds fee denominator");
|
||||||
let effective_amount_in = swap_amount_in
|
let effective_amount_in = swap_amount_in
|
||||||
.checked_mul(FEE_BPS_DENOMINATOR - fee_bps)
|
.checked_mul(fee_multiplier)
|
||||||
.expect("swap_amount_in * (FEE_BPS_DENOMINATOR - fee_bps) overflows u128")
|
.expect("swap_amount_in * (FEE_BPS_DENOMINATOR - fee_bps) overflows u128")
|
||||||
/ FEE_BPS_DENOMINATOR;
|
.checked_div(FEE_BPS_DENOMINATOR)
|
||||||
|
.expect("fee denominator must be nonzero");
|
||||||
assert!(
|
assert!(
|
||||||
effective_amount_in != 0,
|
effective_amount_in != 0,
|
||||||
"Effective swap amount should be nonzero"
|
"Effective swap amount should be nonzero"
|
||||||
@ -184,9 +197,12 @@ fn swap_logic(
|
|||||||
let withdraw_amount = reserve_withdraw_vault_amount
|
let withdraw_amount = reserve_withdraw_vault_amount
|
||||||
.checked_mul(effective_amount_in)
|
.checked_mul(effective_amount_in)
|
||||||
.expect("reserve * effective_amount_in overflows u128")
|
.expect("reserve * effective_amount_in overflows u128")
|
||||||
/ reserve_deposit_vault_amount
|
.checked_div(
|
||||||
|
reserve_deposit_vault_amount
|
||||||
.checked_add(effective_amount_in)
|
.checked_add(effective_amount_in)
|
||||||
.expect("reserve + effective_amount_in overflows u128");
|
.expect("reserve + effective_amount_in overflows u128"),
|
||||||
|
)
|
||||||
|
.expect("reserve plus effective input must be nonzero");
|
||||||
|
|
||||||
// Slippage check
|
// Slippage check
|
||||||
assert!(
|
assert!(
|
||||||
@ -230,7 +246,10 @@ fn swap_logic(
|
|||||||
(chained_calls, swap_amount_in, withdraw_amount)
|
(chained_calls, swap_amount_in, withdraw_amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[expect(clippy::too_many_arguments, reason = "TODO: Fix later")]
|
#[expect(
|
||||||
|
clippy::too_many_arguments,
|
||||||
|
reason = "instruction surface passes explicit pool, vault, and user accounts"
|
||||||
|
)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn swap_exact_output(
|
pub fn swap_exact_output(
|
||||||
pool: AccountWithMetadata,
|
pool: AccountWithMetadata,
|
||||||
@ -295,7 +314,10 @@ pub fn swap_exact_output(
|
|||||||
(post_states, chained_calls)
|
(post_states, chained_calls)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[expect(clippy::too_many_arguments, reason = "TODO: Fix later")]
|
#[expect(
|
||||||
|
clippy::too_many_arguments,
|
||||||
|
reason = "swap calculation keeps account context and pricing parameters explicit"
|
||||||
|
)]
|
||||||
fn exact_output_swap_logic(
|
fn exact_output_swap_logic(
|
||||||
user_deposit: AccountWithMetadata,
|
user_deposit: AccountWithMetadata,
|
||||||
vault_deposit: AccountWithMetadata,
|
vault_deposit: AccountWithMetadata,
|
||||||
|
|||||||
166
amm/src/tests.rs
166
amm/src/tests.rs
@ -1,4 +1,9 @@
|
|||||||
#![cfg(test)]
|
#![cfg(test)]
|
||||||
|
#![expect(
|
||||||
|
clippy::arithmetic_side_effects,
|
||||||
|
clippy::integer_division,
|
||||||
|
reason = "test fixtures use fixed values to lock AMM math boundaries"
|
||||||
|
)]
|
||||||
|
|
||||||
use std::num::NonZero;
|
use std::num::NonZero;
|
||||||
|
|
||||||
@ -1398,7 +1403,7 @@ fn test_call_add_liquidity_vault_a_omitted() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::add_min_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::add_min_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::add_max_amount_a(),
|
BalanceForTests::add_max_amount_a(),
|
||||||
BalanceForTests::add_max_amount_b(),
|
BalanceForTests::add_max_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1415,7 +1420,7 @@ fn test_call_add_liquidity_vault_b_omitted() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::add_min_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::add_min_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::add_max_amount_a(),
|
BalanceForTests::add_max_amount_a(),
|
||||||
BalanceForTests::add_max_amount_b(),
|
BalanceForTests::add_max_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1432,7 +1437,7 @@ fn test_call_add_liquidity_lp_definition_mismatch() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::add_min_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::add_min_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::add_max_amount_a(),
|
BalanceForTests::add_max_amount_a(),
|
||||||
BalanceForTests::add_max_amount_b(),
|
BalanceForTests::add_max_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1449,7 +1454,7 @@ fn test_call_add_liquidity_zero_balance_1() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::add_min_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::add_min_amount_lp()).expect("test setup should succeed"),
|
||||||
0,
|
0,
|
||||||
BalanceForTests::add_max_amount_b(),
|
BalanceForTests::add_max_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1466,7 +1471,7 @@ fn test_call_add_liquidity_zero_balance_2() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::add_min_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::add_min_amount_lp()).expect("test setup should succeed"),
|
||||||
0,
|
0,
|
||||||
BalanceForTests::add_max_amount_a(),
|
BalanceForTests::add_max_amount_a(),
|
||||||
);
|
);
|
||||||
@ -1483,7 +1488,7 @@ fn test_call_add_liquidity_vault_a_balance_below_reserve() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::add_min_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::add_min_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::add_max_amount_a(),
|
BalanceForTests::add_max_amount_a(),
|
||||||
BalanceForTests::add_max_amount_b(),
|
BalanceForTests::add_max_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1500,7 +1505,7 @@ fn test_call_add_liquidity_vault_b_balance_below_reserve() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::add_min_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::add_min_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::add_max_amount_a(),
|
BalanceForTests::add_max_amount_a(),
|
||||||
BalanceForTests::add_max_amount_b(),
|
BalanceForTests::add_max_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1517,7 +1522,7 @@ fn test_call_add_liquidity_vault_insufficient_balance_1() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::add_min_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::add_min_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::add_max_amount_a(),
|
BalanceForTests::add_max_amount_a(),
|
||||||
BalanceForTests::add_max_amount_b(),
|
BalanceForTests::add_max_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1534,7 +1539,7 @@ fn test_call_add_liquidity_vault_insufficient_balance_2() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::add_min_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::add_min_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::add_max_amount_a(),
|
BalanceForTests::add_max_amount_a(),
|
||||||
BalanceForTests::add_max_amount_b(),
|
BalanceForTests::add_max_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1551,7 +1556,7 @@ fn test_call_add_liquidity_actual_amount_zero_1() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::add_min_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::add_min_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::add_max_amount_a(),
|
BalanceForTests::add_max_amount_a(),
|
||||||
BalanceForTests::add_max_amount_b(),
|
BalanceForTests::add_max_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1568,7 +1573,7 @@ fn test_call_add_liquidity_actual_amount_zero_2() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::add_min_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::add_min_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::add_max_amount_a_low(),
|
BalanceForTests::add_max_amount_a_low(),
|
||||||
BalanceForTests::add_max_amount_b_low(),
|
BalanceForTests::add_max_amount_b_low(),
|
||||||
);
|
);
|
||||||
@ -1585,7 +1590,7 @@ fn test_call_add_liquidity_reserves_zero_1() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::add_min_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::add_min_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::add_max_amount_a(),
|
BalanceForTests::add_max_amount_a(),
|
||||||
BalanceForTests::add_max_amount_b(),
|
BalanceForTests::add_max_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1602,7 +1607,7 @@ fn test_call_add_liquidity_reserves_zero_2() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::add_min_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::add_min_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::add_max_amount_a(),
|
BalanceForTests::add_max_amount_a(),
|
||||||
BalanceForTests::add_max_amount_b(),
|
BalanceForTests::add_max_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1619,7 +1624,7 @@ fn test_call_add_liquidity_payable_lp_zero() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::add_min_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::add_min_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::add_max_amount_a_low(),
|
BalanceForTests::add_max_amount_a_low(),
|
||||||
BalanceForTests::add_max_amount_b_low(),
|
BalanceForTests::add_max_amount_b_low(),
|
||||||
);
|
);
|
||||||
@ -1635,7 +1640,7 @@ fn test_call_add_liquidity_chained_call_successsful() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::add_min_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::add_min_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::add_max_amount_a(),
|
BalanceForTests::add_max_amount_a(),
|
||||||
BalanceForTests::add_max_amount_b(),
|
BalanceForTests::add_max_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1667,7 +1672,7 @@ fn test_call_remove_liquidity_vault_a_omitted() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::remove_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::remove_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::remove_min_amount_a(),
|
BalanceForTests::remove_min_amount_a(),
|
||||||
BalanceForTests::remove_min_amount_b(),
|
BalanceForTests::remove_min_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1684,7 +1689,7 @@ fn test_call_remove_liquidity_vault_b_omitted() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::remove_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::remove_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::remove_min_amount_a(),
|
BalanceForTests::remove_min_amount_a(),
|
||||||
BalanceForTests::remove_min_amount_b(),
|
BalanceForTests::remove_min_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1701,7 +1706,7 @@ fn test_call_remove_liquidity_lp_def_mismatch() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::remove_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::remove_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::remove_min_amount_a(),
|
BalanceForTests::remove_min_amount_a(),
|
||||||
BalanceForTests::remove_min_amount_b(),
|
BalanceForTests::remove_min_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1720,7 +1725,7 @@ fn test_call_remove_liquidity_insufficient_liquidity_amount() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(), /* different token account than lp to
|
AccountWithMetadataForTests::user_holding_a(), /* different token account than lp to
|
||||||
* create desired
|
* create desired
|
||||||
* error */
|
* error */
|
||||||
NonZero::new(BalanceForTests::remove_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::remove_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::remove_min_amount_a(),
|
BalanceForTests::remove_min_amount_a(),
|
||||||
BalanceForTests::remove_min_amount_b(),
|
BalanceForTests::remove_min_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1739,7 +1744,7 @@ fn test_call_remove_liquidity_insufficient_balance_1() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::remove_amount_lp_1()).unwrap(),
|
NonZero::new(BalanceForTests::remove_amount_lp_1()).expect("test setup should succeed"),
|
||||||
BalanceForTests::remove_min_amount_a(),
|
BalanceForTests::remove_min_amount_a(),
|
||||||
BalanceForTests::remove_min_amount_b(),
|
BalanceForTests::remove_min_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1757,7 +1762,7 @@ fn test_call_remove_liquidity_pool_at_minimum_liquidity() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_with_balance(MINIMUM_LIQUIDITY),
|
AccountWithMetadataForTests::user_holding_lp_with_balance(MINIMUM_LIQUIDITY),
|
||||||
NonZero::new(MINIMUM_LIQUIDITY).unwrap(),
|
NonZero::new(MINIMUM_LIQUIDITY).expect("test setup should succeed"),
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
@ -1777,7 +1782,7 @@ fn test_call_remove_liquidity_exceeds_unlocked_supply() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_with_balance(BalanceForTests::lp_supply_init()),
|
AccountWithMetadataForTests::user_holding_lp_with_balance(BalanceForTests::lp_supply_init()),
|
||||||
NonZero::new(BalanceForTests::lp_supply_init()).unwrap(),
|
NonZero::new(BalanceForTests::lp_supply_init()).expect("test setup should succeed"),
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
@ -1796,7 +1801,7 @@ fn test_call_remove_liquidity_insufficient_balance_2() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::remove_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::remove_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::remove_min_amount_a(),
|
BalanceForTests::remove_min_amount_a(),
|
||||||
BalanceForTests::remove_min_amount_b(),
|
BalanceForTests::remove_min_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1813,7 +1818,7 @@ fn test_call_remove_liquidity_min_bal_zero_1() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::remove_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::remove_amount_lp()).expect("test setup should succeed"),
|
||||||
0,
|
0,
|
||||||
BalanceForTests::remove_min_amount_b(),
|
BalanceForTests::remove_min_amount_b(),
|
||||||
);
|
);
|
||||||
@ -1830,7 +1835,7 @@ fn test_call_remove_liquidity_min_bal_zero_2() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::remove_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::remove_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::remove_min_amount_a(),
|
BalanceForTests::remove_min_amount_a(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
@ -1846,7 +1851,7 @@ fn test_call_remove_liquidity_chained_call_successful() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(BalanceForTests::remove_amount_lp()).unwrap(),
|
NonZero::new(BalanceForTests::remove_amount_lp()).expect("test setup should succeed"),
|
||||||
BalanceForTests::remove_min_amount_a(),
|
BalanceForTests::remove_min_amount_a(),
|
||||||
BalanceForTests::remove_min_amount_b_low(),
|
BalanceForTests::remove_min_amount_b_low(),
|
||||||
);
|
);
|
||||||
@ -1880,7 +1885,7 @@ fn test_call_new_definition_with_zero_balance_1() {
|
|||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
||||||
NonZero::new(0).expect("Balances must be nonzero"),
|
NonZero::new(0).expect("Balances must be nonzero"),
|
||||||
NonZero::new(BalanceForTests::vault_b_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_b_reserve_init()).expect("test setup should succeed"),
|
||||||
BalanceForTests::fee_tier(),
|
BalanceForTests::fee_tier(),
|
||||||
AMM_PROGRAM_ID,
|
AMM_PROGRAM_ID,
|
||||||
);
|
);
|
||||||
@ -1898,7 +1903,7 @@ fn test_call_new_definition_with_zero_balance_2() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
||||||
NonZero::new(BalanceForTests::vault_a_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_a_reserve_init()).expect("test setup should succeed"),
|
||||||
NonZero::new(0).expect("Balances must be nonzero"),
|
NonZero::new(0).expect("Balances must be nonzero"),
|
||||||
BalanceForTests::fee_tier(),
|
BalanceForTests::fee_tier(),
|
||||||
AMM_PROGRAM_ID,
|
AMM_PROGRAM_ID,
|
||||||
@ -1917,8 +1922,8 @@ fn test_call_new_definition_same_token_definition() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
||||||
NonZero::new(BalanceForTests::vault_a_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_a_reserve_init()).expect("test setup should succeed"),
|
||||||
NonZero::new(BalanceForTests::vault_b_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_b_reserve_init()).expect("test setup should succeed"),
|
||||||
BalanceForTests::fee_tier(),
|
BalanceForTests::fee_tier(),
|
||||||
AMM_PROGRAM_ID,
|
AMM_PROGRAM_ID,
|
||||||
);
|
);
|
||||||
@ -1936,8 +1941,8 @@ fn test_call_new_definition_wrong_liquidity_id() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
||||||
NonZero::new(BalanceForTests::vault_a_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_a_reserve_init()).expect("test setup should succeed"),
|
||||||
NonZero::new(BalanceForTests::vault_b_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_b_reserve_init()).expect("test setup should succeed"),
|
||||||
BalanceForTests::fee_tier(),
|
BalanceForTests::fee_tier(),
|
||||||
AMM_PROGRAM_ID,
|
AMM_PROGRAM_ID,
|
||||||
);
|
);
|
||||||
@ -1955,8 +1960,8 @@ fn test_call_new_definition_wrong_lp_lock_holding_id() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
||||||
NonZero::new(BalanceForTests::vault_a_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_a_reserve_init()).expect("test setup should succeed"),
|
||||||
NonZero::new(BalanceForTests::vault_b_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_b_reserve_init()).expect("test setup should succeed"),
|
||||||
BalanceForTests::fee_tier(),
|
BalanceForTests::fee_tier(),
|
||||||
AMM_PROGRAM_ID,
|
AMM_PROGRAM_ID,
|
||||||
);
|
);
|
||||||
@ -1974,8 +1979,8 @@ fn test_call_new_definition_wrong_pool_id() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
||||||
NonZero::new(BalanceForTests::vault_a_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_a_reserve_init()).expect("test setup should succeed"),
|
||||||
NonZero::new(BalanceForTests::vault_b_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_b_reserve_init()).expect("test setup should succeed"),
|
||||||
BalanceForTests::fee_tier(),
|
BalanceForTests::fee_tier(),
|
||||||
AMM_PROGRAM_ID,
|
AMM_PROGRAM_ID,
|
||||||
);
|
);
|
||||||
@ -1993,8 +1998,8 @@ fn test_call_new_definition_wrong_vault_id_1() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
||||||
NonZero::new(BalanceForTests::vault_a_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_a_reserve_init()).expect("test setup should succeed"),
|
||||||
NonZero::new(BalanceForTests::vault_b_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_b_reserve_init()).expect("test setup should succeed"),
|
||||||
BalanceForTests::fee_tier(),
|
BalanceForTests::fee_tier(),
|
||||||
AMM_PROGRAM_ID,
|
AMM_PROGRAM_ID,
|
||||||
);
|
);
|
||||||
@ -2012,8 +2017,8 @@ fn test_call_new_definition_wrong_vault_id_2() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
||||||
NonZero::new(BalanceForTests::vault_a_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_a_reserve_init()).expect("test setup should succeed"),
|
||||||
NonZero::new(BalanceForTests::vault_b_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_b_reserve_init()).expect("test setup should succeed"),
|
||||||
BalanceForTests::fee_tier(),
|
BalanceForTests::fee_tier(),
|
||||||
AMM_PROGRAM_ID,
|
AMM_PROGRAM_ID,
|
||||||
);
|
);
|
||||||
@ -2032,8 +2037,8 @@ fn test_call_new_definition_rejects_initialized_pool() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
||||||
NonZero::new(BalanceForTests::vault_a_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_a_reserve_init()).expect("test setup should succeed"),
|
||||||
NonZero::new(BalanceForTests::vault_b_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_b_reserve_init()).expect("test setup should succeed"),
|
||||||
BalanceForTests::fee_tier(),
|
BalanceForTests::fee_tier(),
|
||||||
AMM_PROGRAM_ID,
|
AMM_PROGRAM_ID,
|
||||||
);
|
);
|
||||||
@ -2052,8 +2057,8 @@ fn test_call_new_definition_initial_lp_too_small() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
||||||
NonZero::new(MINIMUM_LIQUIDITY).unwrap(),
|
NonZero::new(MINIMUM_LIQUIDITY).expect("test setup should succeed"),
|
||||||
NonZero::new(MINIMUM_LIQUIDITY).unwrap(),
|
NonZero::new(MINIMUM_LIQUIDITY).expect("test setup should succeed"),
|
||||||
BalanceForTests::fee_tier(),
|
BalanceForTests::fee_tier(),
|
||||||
AMM_PROGRAM_ID,
|
AMM_PROGRAM_ID,
|
||||||
);
|
);
|
||||||
@ -2070,8 +2075,8 @@ fn test_call_new_definition_chained_call_successful() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
||||||
NonZero::new(BalanceForTests::vault_a_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_a_reserve_init()).expect("test setup should succeed"),
|
||||||
NonZero::new(BalanceForTests::vault_b_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_b_reserve_init()).expect("test setup should succeed"),
|
||||||
BalanceForTests::fee_tier(),
|
BalanceForTests::fee_tier(),
|
||||||
AMM_PROGRAM_ID,
|
AMM_PROGRAM_ID,
|
||||||
);
|
);
|
||||||
@ -2192,7 +2197,8 @@ fn test_call_swap_below_minimum_liquidity() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_call_swap_rejects_unsupported_fee_tier() {
|
fn test_call_swap_rejects_unsupported_fee_tier() {
|
||||||
let mut pool = AccountWithMetadataForTests::pool_definition_init();
|
let mut pool = AccountWithMetadataForTests::pool_definition_init();
|
||||||
let mut pool_def = PoolDefinition::try_from(&pool.account.data).unwrap();
|
let mut pool_def =
|
||||||
|
PoolDefinition::try_from(&pool.account.data).expect("test setup should succeed");
|
||||||
pool_def.fees = 2;
|
pool_def.fees = 2;
|
||||||
pool.account.data = Data::from(&pool_def);
|
pool.account.data = Data::from(&pool_def);
|
||||||
|
|
||||||
@ -2718,15 +2724,16 @@ fn test_new_definition_lp_asymmetric_amounts() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
||||||
NonZero::new(BalanceForTests::vault_a_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_a_reserve_init()).expect("test setup should succeed"),
|
||||||
NonZero::new(BalanceForTests::vault_b_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_b_reserve_init()).expect("test setup should succeed"),
|
||||||
BalanceForTests::fee_tier(),
|
BalanceForTests::fee_tier(),
|
||||||
AMM_PROGRAM_ID,
|
AMM_PROGRAM_ID,
|
||||||
);
|
);
|
||||||
|
|
||||||
// check the minted LP amount
|
// check the minted LP amount
|
||||||
let pool_post = post_states[0].clone();
|
let pool_post = post_states[0].clone();
|
||||||
let pool_def = PoolDefinition::try_from(&pool_post.account().data).unwrap();
|
let pool_def =
|
||||||
|
PoolDefinition::try_from(&pool_post.account().data).expect("test setup should succeed");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
pool_def.liquidity_pool_supply,
|
pool_def.liquidity_pool_supply,
|
||||||
BalanceForTests::lp_supply_init()
|
BalanceForTests::lp_supply_init()
|
||||||
@ -2755,14 +2762,15 @@ fn test_new_definition_lp_symmetric_amounts() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
||||||
NonZero::new(token_a_amount).unwrap(),
|
NonZero::new(token_a_amount).expect("test setup should succeed"),
|
||||||
NonZero::new(token_b_amount).unwrap(),
|
NonZero::new(token_b_amount).expect("test setup should succeed"),
|
||||||
BalanceForTests::fee_tier(),
|
BalanceForTests::fee_tier(),
|
||||||
AMM_PROGRAM_ID,
|
AMM_PROGRAM_ID,
|
||||||
);
|
);
|
||||||
|
|
||||||
let pool_post = post_states[0].clone();
|
let pool_post = post_states[0].clone();
|
||||||
let pool_def = PoolDefinition::try_from(&pool_post.account().data).unwrap();
|
let pool_def =
|
||||||
|
PoolDefinition::try_from(&pool_post.account().data).expect("test setup should succeed");
|
||||||
assert_eq!(pool_def.liquidity_pool_supply, expected_lp);
|
assert_eq!(pool_def.liquidity_pool_supply, expected_lp);
|
||||||
|
|
||||||
let chained_call_lp_lock = chained_calls[0].clone();
|
let chained_call_lp_lock = chained_calls[0].clone();
|
||||||
@ -2824,8 +2832,8 @@ fn test_minimum_liquidity_lock_and_remove_all_user_lp() {
|
|||||||
AccountForTests::user_holding_a(),
|
AccountForTests::user_holding_a(),
|
||||||
AccountForTests::user_holding_b(),
|
AccountForTests::user_holding_b(),
|
||||||
AccountForTests::user_holding_lp_uninit(),
|
AccountForTests::user_holding_lp_uninit(),
|
||||||
NonZero::new(token_a_amount).unwrap(),
|
NonZero::new(token_a_amount).expect("test setup should succeed"),
|
||||||
NonZero::new(token_b_amount).unwrap(),
|
NonZero::new(token_b_amount).expect("test setup should succeed"),
|
||||||
BalanceForTests::fee_tier(),
|
BalanceForTests::fee_tier(),
|
||||||
AMM_PROGRAM_ID,
|
AMM_PROGRAM_ID,
|
||||||
);
|
);
|
||||||
@ -2863,7 +2871,8 @@ fn test_minimum_liquidity_lock_and_remove_all_user_lp() {
|
|||||||
assert_eq!(chained_calls[0], expected_lock_call);
|
assert_eq!(chained_calls[0], expected_lock_call);
|
||||||
assert_eq!(chained_calls[1], expected_user_call);
|
assert_eq!(chained_calls[1], expected_user_call);
|
||||||
|
|
||||||
let pool_post = PoolDefinition::try_from(&post_states[0].account().data).unwrap();
|
let pool_post = PoolDefinition::try_from(&post_states[0].account().data)
|
||||||
|
.expect("test setup should succeed");
|
||||||
assert_eq!(pool_post.liquidity_pool_supply, initial_lp);
|
assert_eq!(pool_post.liquidity_pool_supply, initial_lp);
|
||||||
|
|
||||||
let pool_for_remove = AccountWithMetadata {
|
let pool_for_remove = AccountWithMetadata {
|
||||||
@ -2879,13 +2888,13 @@ fn test_minimum_liquidity_lock_and_remove_all_user_lp() {
|
|||||||
AccountForTests::user_holding_a(),
|
AccountForTests::user_holding_a(),
|
||||||
AccountForTests::user_holding_b(),
|
AccountForTests::user_holding_b(),
|
||||||
AccountForTests::user_holding_lp_with_balance(user_lp),
|
AccountForTests::user_holding_lp_with_balance(user_lp),
|
||||||
NonZero::new(user_lp).unwrap(),
|
NonZero::new(user_lp).expect("test setup should succeed"),
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
|
|
||||||
let pool_after_remove =
|
let pool_after_remove = PoolDefinition::try_from(&remove_post_states[0].account().data)
|
||||||
PoolDefinition::try_from(&remove_post_states[0].account().data).unwrap();
|
.expect("test setup should succeed");
|
||||||
assert_eq!(pool_after_remove.liquidity_pool_supply, MINIMUM_LIQUIDITY);
|
assert_eq!(pool_after_remove.liquidity_pool_supply, MINIMUM_LIQUIDITY);
|
||||||
assert!(pool_after_remove.reserve_a > 0);
|
assert!(pool_after_remove.reserve_a > 0);
|
||||||
assert!(pool_after_remove.reserve_b > 0);
|
assert!(pool_after_remove.reserve_b > 0);
|
||||||
@ -2902,7 +2911,7 @@ fn test_sync_reserves_with_donation() {
|
|||||||
balance: BalanceForTests::vault_a_reserve_init() + donation_a,
|
balance: BalanceForTests::vault_a_reserve_init() + donation_a,
|
||||||
});
|
});
|
||||||
|
|
||||||
let pool_pre = PoolDefinition::try_from(&pool.account.data).unwrap();
|
let pool_pre = PoolDefinition::try_from(&pool.account.data).expect("test setup should succeed");
|
||||||
assert_eq!(pool_pre.reserve_a, BalanceForTests::vault_a_reserve_init());
|
assert_eq!(pool_pre.reserve_a, BalanceForTests::vault_a_reserve_init());
|
||||||
|
|
||||||
let (post_states, chained_calls) = sync_reserves(
|
let (post_states, chained_calls) = sync_reserves(
|
||||||
@ -2912,7 +2921,8 @@ fn test_sync_reserves_with_donation() {
|
|||||||
);
|
);
|
||||||
assert!(chained_calls.is_empty());
|
assert!(chained_calls.is_empty());
|
||||||
|
|
||||||
let pool_post = PoolDefinition::try_from(&post_states[0].account().data).unwrap();
|
let pool_post = PoolDefinition::try_from(&post_states[0].account().data)
|
||||||
|
.expect("test setup should succeed");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
pool_post.reserve_a,
|
pool_post.reserve_a,
|
||||||
BalanceForTests::vault_a_reserve_init() + donation_a
|
BalanceForTests::vault_a_reserve_init() + donation_a
|
||||||
@ -2969,11 +2979,12 @@ fn test_donation_then_add_liquidity_sync_mitigates_mispricing() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(1).unwrap(),
|
NonZero::new(1).expect("test setup should succeed"),
|
||||||
100,
|
100,
|
||||||
50,
|
50,
|
||||||
);
|
);
|
||||||
let unsynced_pool_post = PoolDefinition::try_from(&post_unsynced[0].account().data).unwrap();
|
let unsynced_pool_post = PoolDefinition::try_from(&post_unsynced[0].account().data)
|
||||||
|
.expect("test setup should succeed");
|
||||||
let unsynced_delta_lp =
|
let unsynced_delta_lp =
|
||||||
unsynced_pool_post.liquidity_pool_supply - BalanceForTests::lp_supply_init();
|
unsynced_pool_post.liquidity_pool_supply - BalanceForTests::lp_supply_init();
|
||||||
|
|
||||||
@ -2999,14 +3010,15 @@ fn test_donation_then_add_liquidity_sync_mitigates_mispricing() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(1).unwrap(),
|
NonZero::new(1).expect("test setup should succeed"),
|
||||||
100,
|
100,
|
||||||
50,
|
50,
|
||||||
);
|
);
|
||||||
let synced_pool_post = PoolDefinition::try_from(&post_synced[0].account().data).unwrap();
|
let synced_pool_post = PoolDefinition::try_from(&post_synced[0].account().data)
|
||||||
|
.expect("test setup should succeed");
|
||||||
let synced_delta_lp = synced_pool_post.liquidity_pool_supply
|
let synced_delta_lp = synced_pool_post.liquidity_pool_supply
|
||||||
- PoolDefinition::try_from(&sync_post[0].account().data)
|
- PoolDefinition::try_from(&sync_post[0].account().data)
|
||||||
.unwrap()
|
.expect("test setup should succeed")
|
||||||
.liquidity_pool_supply;
|
.liquidity_pool_supply;
|
||||||
|
|
||||||
assert!(synced_delta_lp < unsynced_delta_lp);
|
assert!(synced_delta_lp < unsynced_delta_lp);
|
||||||
@ -3026,8 +3038,8 @@ fn new_definition_overflow_protection() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
||||||
NonZero::new(large_amount).unwrap(),
|
NonZero::new(large_amount).expect("test setup should succeed"),
|
||||||
NonZero::new(2).unwrap(),
|
NonZero::new(2).expect("test setup should succeed"),
|
||||||
BalanceForTests::fee_tier(),
|
BalanceForTests::fee_tier(),
|
||||||
AMM_PROGRAM_ID,
|
AMM_PROGRAM_ID,
|
||||||
);
|
);
|
||||||
@ -3096,7 +3108,7 @@ fn add_liquidity_overflow_protection() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_init(),
|
AccountWithMetadataForTests::user_holding_lp_init(),
|
||||||
NonZero::new(1).unwrap(),
|
NonZero::new(1).expect("test setup should succeed"),
|
||||||
500,
|
500,
|
||||||
2, // max_amount_b=2 → reserve_a * 2 overflows
|
2, // max_amount_b=2 → reserve_a * 2 overflows
|
||||||
);
|
);
|
||||||
@ -3180,7 +3192,8 @@ fn remove_liquidity_overflow_protection() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
user_lp,
|
user_lp,
|
||||||
NonZero::new(2).unwrap(), // remove_amount=2 → reserve_a * 2 overflows
|
NonZero::new(2).expect("test setup should succeed"), /* remove_amount=2 → reserve_a * 2
|
||||||
|
* overflows */
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
@ -3273,14 +3286,17 @@ fn test_new_definition_supports_all_fee_tiers() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
||||||
NonZero::new(BalanceForTests::vault_a_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_a_reserve_init())
|
||||||
NonZero::new(BalanceForTests::vault_b_reserve_init()).unwrap(),
|
.expect("test setup should succeed"),
|
||||||
|
NonZero::new(BalanceForTests::vault_b_reserve_init())
|
||||||
|
.expect("test setup should succeed"),
|
||||||
fees,
|
fees,
|
||||||
AMM_PROGRAM_ID,
|
AMM_PROGRAM_ID,
|
||||||
);
|
);
|
||||||
|
|
||||||
let pool_post = post_states[0].clone();
|
let pool_post = post_states[0].clone();
|
||||||
let pool_def = PoolDefinition::try_from(&pool_post.account().data).unwrap();
|
let pool_def =
|
||||||
|
PoolDefinition::try_from(&pool_post.account().data).expect("test setup should succeed");
|
||||||
assert_eq!(pool_def.fees, fees);
|
assert_eq!(pool_def.fees, fees);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3297,8 +3313,8 @@ fn test_new_definition_rejects_unsupported_fee_tier() {
|
|||||||
AccountWithMetadataForTests::user_holding_a(),
|
AccountWithMetadataForTests::user_holding_a(),
|
||||||
AccountWithMetadataForTests::user_holding_b(),
|
AccountWithMetadataForTests::user_holding_b(),
|
||||||
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
AccountWithMetadataForTests::user_holding_lp_uninit(),
|
||||||
NonZero::new(BalanceForTests::vault_a_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_a_reserve_init()).expect("test setup should succeed"),
|
||||||
NonZero::new(BalanceForTests::vault_b_reserve_init()).unwrap(),
|
NonZero::new(BalanceForTests::vault_b_reserve_init()).expect("test setup should succeed"),
|
||||||
2,
|
2,
|
||||||
AMM_PROGRAM_ID,
|
AMM_PROGRAM_ID,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -3,6 +3,9 @@ name = "ata_program"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc1", features = ["host"] }
|
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc1", features = ["host"] }
|
||||||
ata_core = { path = "core" }
|
ata_core = { path = "core" }
|
||||||
|
|||||||
@ -3,6 +3,9 @@ name = "ata_core"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc1", features = ["host"] }
|
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc1", features = ["host"] }
|
||||||
borsh = { version = "1.5", features = ["derive"] }
|
borsh = { version = "1.5", features = ["derive"] }
|
||||||
|
|||||||
@ -50,8 +50,9 @@ pub enum Instruction {
|
|||||||
pub fn compute_ata_seed(owner_id: AccountId, definition_id: AccountId) -> PdaSeed {
|
pub fn compute_ata_seed(owner_id: AccountId, definition_id: AccountId) -> PdaSeed {
|
||||||
use risc0_zkvm::sha::{Impl, Sha256};
|
use risc0_zkvm::sha::{Impl, Sha256};
|
||||||
let mut bytes = [0u8; 64];
|
let mut bytes = [0u8; 64];
|
||||||
bytes[0..32].copy_from_slice(&owner_id.to_bytes());
|
let (owner_bytes, definition_bytes) = bytes.split_at_mut(32);
|
||||||
bytes[32..64].copy_from_slice(&definition_id.to_bytes());
|
owner_bytes.copy_from_slice(&owner_id.to_bytes());
|
||||||
|
definition_bytes.copy_from_slice(&definition_id.to_bytes());
|
||||||
PdaSeed::new(
|
PdaSeed::new(
|
||||||
Impl::hash_bytes(&bytes)
|
Impl::hash_bytes(&bytes)
|
||||||
.as_bytes()
|
.as_bytes()
|
||||||
|
|||||||
@ -3,6 +3,9 @@ name = "ata-methods"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
risc0-build = "=3.0.5"
|
risc0-build = "=3.0.5"
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,32 @@ edition = "2021"
|
|||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
|
|
||||||
|
[lints.rust]
|
||||||
|
rust_2018_idioms = { level = "deny", priority = -1 }
|
||||||
|
unsafe_code = "forbid"
|
||||||
|
|
||||||
|
[lints.clippy]
|
||||||
|
all = { level = "deny", priority = -1 }
|
||||||
|
allow_attributes = "warn"
|
||||||
|
allow_attributes_without_reason = "deny"
|
||||||
|
arithmetic_side_effects = "deny"
|
||||||
|
as_conversions = "deny"
|
||||||
|
cast_possible_truncation = "deny"
|
||||||
|
cast_possible_wrap = "deny"
|
||||||
|
cast_precision_loss = "warn"
|
||||||
|
cast_sign_loss = "deny"
|
||||||
|
dbg_macro = "deny"
|
||||||
|
indexing_slicing = "deny"
|
||||||
|
integer_division = "warn"
|
||||||
|
large_enum_variant = "deny"
|
||||||
|
match_wildcard_for_single_variants = "warn"
|
||||||
|
module_name_repetitions = "allow"
|
||||||
|
similar_names = "allow"
|
||||||
|
todo = "deny"
|
||||||
|
unimplemented = "deny"
|
||||||
|
unwrap_used = "deny"
|
||||||
|
wildcard_enum_match_arm = "deny"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "ata"
|
name = "ata"
|
||||||
path = "src/bin/ata.rs"
|
path = "src/bin/ata.rs"
|
||||||
|
|||||||
@ -1,17 +1,25 @@
|
|||||||
#![no_main]
|
#![cfg_attr(not(test), no_main)]
|
||||||
|
|
||||||
use spel_framework::prelude::*;
|
use spel_framework::prelude::*;
|
||||||
use nssa_core::{account::AccountWithMetadata, program::ProgramId};
|
use nssa_core::{account::AccountWithMetadata, program::ProgramId};
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
risc0_zkvm::guest::entry!(main);
|
risc0_zkvm::guest::entry!(main);
|
||||||
|
|
||||||
#[lez_program(instruction = "ata_core::Instruction")]
|
#[lez_program(instruction = "ata_core::Instruction")]
|
||||||
mod ata {
|
mod ata {
|
||||||
#[allow(unused_imports)]
|
#[expect(
|
||||||
|
unused_imports,
|
||||||
|
reason = "SPEL instruction macro requires importing parent-scope handler types"
|
||||||
|
)]
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// Create the Associated Token Account for (owner, definition).
|
/// Create the Associated Token Account for (owner, definition).
|
||||||
/// Idempotent: no-op if the account already exists.
|
/// Idempotent: no-op if the account already exists.
|
||||||
|
#[expect(
|
||||||
|
deprecated,
|
||||||
|
reason = "ATA guest chained-call wrapper remains until auto-claim migration is scoped"
|
||||||
|
)]
|
||||||
#[instruction]
|
#[instruction]
|
||||||
pub fn create(
|
pub fn create(
|
||||||
owner: AccountWithMetadata,
|
owner: AccountWithMetadata,
|
||||||
@ -30,6 +38,10 @@ mod ata {
|
|||||||
|
|
||||||
/// Transfer tokens FROM owner's ATA to a recipient token holding account.
|
/// Transfer tokens FROM owner's ATA to a recipient token holding account.
|
||||||
/// The recipient holding account must already be initialized.
|
/// The recipient holding account must already be initialized.
|
||||||
|
#[expect(
|
||||||
|
deprecated,
|
||||||
|
reason = "ATA guest chained-call wrapper remains until auto-claim migration is scoped"
|
||||||
|
)]
|
||||||
#[instruction]
|
#[instruction]
|
||||||
pub fn transfer(
|
pub fn transfer(
|
||||||
owner: AccountWithMetadata,
|
owner: AccountWithMetadata,
|
||||||
@ -50,6 +62,10 @@ mod ata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Burn tokens FROM owner's ATA.
|
/// Burn tokens FROM owner's ATA.
|
||||||
|
#[expect(
|
||||||
|
deprecated,
|
||||||
|
reason = "ATA guest chained-call wrapper remains until auto-claim migration is scoped"
|
||||||
|
)]
|
||||||
#[instruction]
|
#[instruction]
|
||||||
pub fn burn(
|
pub fn burn(
|
||||||
owner: AccountWithMetadata,
|
owner: AccountWithMetadata,
|
||||||
|
|||||||
11
clippy.toml
Normal file
11
clippy.toml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
msrv = "1.94.0"
|
||||||
|
|
||||||
|
avoid-breaking-exported-api = false
|
||||||
|
check-private-items = true
|
||||||
|
warn-on-all-wildcard-imports = true
|
||||||
|
|
||||||
|
allow-dbg-in-tests = false
|
||||||
|
allow-expect-in-tests = true
|
||||||
|
allow-indexing-slicing-in-tests = true
|
||||||
|
allow-print-in-tests = true
|
||||||
|
allow-unwrap-in-tests = false
|
||||||
@ -3,6 +3,9 @@ name = "integration_tests"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nssa = { workspace = true }
|
nssa = { workspace = true }
|
||||||
nssa_core = { workspace = true, features = ["host"] }
|
nssa_core = { workspace = true, features = ["host"] }
|
||||||
|
|||||||
@ -1,3 +1,8 @@
|
|||||||
|
#![expect(
|
||||||
|
clippy::arithmetic_side_effects,
|
||||||
|
reason = "integration fixtures use fixed balances to assert AMM state transitions"
|
||||||
|
)]
|
||||||
|
|
||||||
use amm_core::{
|
use amm_core::{
|
||||||
PoolDefinition, FEE_TIER_BPS_1, FEE_TIER_BPS_100, FEE_TIER_BPS_30, FEE_TIER_BPS_5,
|
PoolDefinition, FEE_TIER_BPS_1, FEE_TIER_BPS_100, FEE_TIER_BPS_30, FEE_TIER_BPS_5,
|
||||||
MINIMUM_LIQUIDITY,
|
MINIMUM_LIQUIDITY,
|
||||||
@ -995,7 +1000,7 @@ fn try_execute_new_definition(
|
|||||||
},
|
},
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = if authorize_user_lp {
|
let witness_set = if authorize_user_lp {
|
||||||
public_transaction::WitnessSet::for_message(
|
public_transaction::WitnessSet::for_message(
|
||||||
@ -1011,7 +1016,7 @@ fn try_execute_new_definition(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn execute_new_definition(state: &mut V03State, fees: u128) {
|
fn execute_new_definition(state: &mut V03State, fees: u128) {
|
||||||
try_execute_new_definition(state, fees, true).unwrap();
|
try_execute_new_definition(state, fees, true).expect("test setup should succeed");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_swap_a_to_b(state: &mut V03State, swap_amount_in: u128, min_amount_out: u128) {
|
fn execute_swap_a_to_b(state: &mut V03State, swap_amount_in: u128, min_amount_out: u128) {
|
||||||
@ -1034,12 +1039,14 @@ fn execute_swap_a_to_b(state: &mut V03State, swap_amount_in: u128, min_amount_ou
|
|||||||
vec![current_nonce(state, Ids::user_a())],
|
vec![current_nonce(state, Ids::user_a())],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_a()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_a()]);
|
||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
state.transition_from_public_transaction(&tx, 0, 0).unwrap();
|
state
|
||||||
|
.transition_from_public_transaction(&tx, 0, 0)
|
||||||
|
.expect("test setup should succeed");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_swap_b_to_a(state: &mut V03State, swap_amount_in: u128, min_amount_out: u128) {
|
fn execute_swap_b_to_a(state: &mut V03State, swap_amount_in: u128, min_amount_out: u128) {
|
||||||
@ -1062,12 +1069,14 @@ fn execute_swap_b_to_a(state: &mut V03State, swap_amount_in: u128, min_amount_ou
|
|||||||
vec![current_nonce(state, Ids::user_b())],
|
vec![current_nonce(state, Ids::user_b())],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_b()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_b()]);
|
||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
state.transition_from_public_transaction(&tx, 0, 0).unwrap();
|
state
|
||||||
|
.transition_from_public_transaction(&tx, 0, 0)
|
||||||
|
.expect("test setup should succeed");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_add_liquidity(
|
fn execute_add_liquidity(
|
||||||
@ -1100,13 +1109,15 @@ fn execute_add_liquidity(
|
|||||||
],
|
],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set =
|
let witness_set =
|
||||||
public_transaction::WitnessSet::for_message(&message, &[&Keys::user_a(), &Keys::user_b()]);
|
public_transaction::WitnessSet::for_message(&message, &[&Keys::user_a(), &Keys::user_b()]);
|
||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
state.transition_from_public_transaction(&tx, 0, 0).unwrap();
|
state
|
||||||
|
.transition_from_public_transaction(&tx, 0, 0)
|
||||||
|
.expect("test setup should succeed");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_remove_liquidity(
|
fn execute_remove_liquidity(
|
||||||
@ -1136,12 +1147,14 @@ fn execute_remove_liquidity(
|
|||||||
vec![current_nonce(state, Ids::user_lp())],
|
vec![current_nonce(state, Ids::user_lp())],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_lp()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_lp()]);
|
||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
state.transition_from_public_transaction(&tx, 0, 0).unwrap();
|
state
|
||||||
|
.transition_from_public_transaction(&tx, 0, 0)
|
||||||
|
.expect("test setup should succeed");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fungible_balance(account: &Account) -> u128 {
|
fn fungible_balance(account: &Account) -> u128 {
|
||||||
@ -1200,12 +1213,14 @@ fn amm_remove_liquidity() {
|
|||||||
vec![Nonce(0)],
|
vec![Nonce(0)],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_lp()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_lp()]);
|
||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
state.transition_from_public_transaction(&tx, 0, 0).unwrap();
|
state
|
||||||
|
.transition_from_public_transaction(&tx, 0, 0)
|
||||||
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
state.get_account_by_id(Ids::pool_definition()),
|
state.get_account_by_id(Ids::pool_definition()),
|
||||||
@ -1263,7 +1278,7 @@ fn amm_remove_liquidity_insufficient_user_lp_fails() {
|
|||||||
vec![Nonce(0)],
|
vec![Nonce(0)],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_lp()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_lp()]);
|
||||||
|
|
||||||
@ -1359,7 +1374,8 @@ fn amm_new_definition_precreated_zero_balance_user_lp() {
|
|||||||
state.force_insert_account(Ids::vault_a(), Accounts::vault_a_reinitializable());
|
state.force_insert_account(Ids::vault_a(), Accounts::vault_a_reinitializable());
|
||||||
state.force_insert_account(Ids::vault_b(), Accounts::vault_b_reinitializable());
|
state.force_insert_account(Ids::vault_b(), Accounts::vault_b_reinitializable());
|
||||||
|
|
||||||
try_execute_new_definition(&mut state, Balances::fee_tier(), false).unwrap();
|
try_execute_new_definition(&mut state, Balances::fee_tier(), false)
|
||||||
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
state.get_account_by_id(Ids::pool_definition()),
|
state.get_account_by_id(Ids::pool_definition()),
|
||||||
@ -1488,13 +1504,15 @@ fn amm_add_liquidity() {
|
|||||||
vec![Nonce(0), Nonce(0)],
|
vec![Nonce(0), Nonce(0)],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set =
|
let witness_set =
|
||||||
public_transaction::WitnessSet::for_message(&message, &[&Keys::user_a(), &Keys::user_b()]);
|
public_transaction::WitnessSet::for_message(&message, &[&Keys::user_a(), &Keys::user_b()]);
|
||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
state.transition_from_public_transaction(&tx, 0, 0).unwrap();
|
state
|
||||||
|
.transition_from_public_transaction(&tx, 0, 0)
|
||||||
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
state.get_account_by_id(Ids::pool_definition()),
|
state.get_account_by_id(Ids::pool_definition()),
|
||||||
@ -1549,12 +1567,14 @@ fn amm_swap_b_to_a() {
|
|||||||
vec![Nonce(0)],
|
vec![Nonce(0)],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_b()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_b()]);
|
||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
state.transition_from_public_transaction(&tx, 0, 0).unwrap();
|
state
|
||||||
|
.transition_from_public_transaction(&tx, 0, 0)
|
||||||
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
state.get_account_by_id(Ids::pool_definition()),
|
state.get_account_by_id(Ids::pool_definition()),
|
||||||
@ -1601,12 +1621,14 @@ fn amm_swap_a_to_b() {
|
|||||||
vec![Nonce(0)],
|
vec![Nonce(0)],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_a()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_a()]);
|
||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
state.transition_from_public_transaction(&tx, 0, 0).unwrap();
|
state
|
||||||
|
.transition_from_public_transaction(&tx, 0, 0)
|
||||||
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
state.get_account_by_id(Ids::pool_definition()),
|
state.get_account_by_id(Ids::pool_definition()),
|
||||||
@ -1707,7 +1729,7 @@ fn amm_swap_rejects_expired_deadline() {
|
|||||||
vec![Nonce(0)],
|
vec![Nonce(0)],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_a()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_a()]);
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
@ -1743,7 +1765,7 @@ fn amm_swap_exact_output_rejects_expired_deadline() {
|
|||||||
vec![current_nonce(&state, Ids::user_a())],
|
vec![current_nonce(&state, Ids::user_a())],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_a()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_a()]);
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
@ -1784,7 +1806,7 @@ fn amm_add_liquidity_rejects_expired_deadline() {
|
|||||||
],
|
],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set =
|
let witness_set =
|
||||||
public_transaction::WitnessSet::for_message(&message, &[&Keys::user_a(), &Keys::user_b()]);
|
public_transaction::WitnessSet::for_message(&message, &[&Keys::user_a(), &Keys::user_b()]);
|
||||||
@ -1823,7 +1845,7 @@ fn amm_remove_liquidity_rejects_expired_deadline() {
|
|||||||
vec![current_nonce(&state, Ids::user_lp())],
|
vec![current_nonce(&state, Ids::user_lp())],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_lp()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::user_lp()]);
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
@ -1867,7 +1889,7 @@ fn amm_new_definition_rejects_expired_deadline() {
|
|||||||
],
|
],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(
|
let witness_set = public_transaction::WitnessSet::for_message(
|
||||||
&message,
|
&message,
|
||||||
|
|||||||
@ -154,12 +154,14 @@ fn ata_create() {
|
|||||||
vec![Nonce(0)],
|
vec![Nonce(0)],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::owner_key()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::owner_key()]);
|
||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
state.transition_from_public_transaction(&tx, 0, 0).unwrap();
|
state
|
||||||
|
.transition_from_public_transaction(&tx, 0, 0)
|
||||||
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
state.get_account_by_id(Ids::owner_ata()),
|
state.get_account_by_id(Ids::owner_ata()),
|
||||||
@ -189,12 +191,14 @@ fn ata_create_is_idempotent() {
|
|||||||
vec![Nonce(0)],
|
vec![Nonce(0)],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::owner_key()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::owner_key()]);
|
||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
state.transition_from_public_transaction(&tx, 0, 0).unwrap();
|
state
|
||||||
|
.transition_from_public_transaction(&tx, 0, 0)
|
||||||
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
// Already initialized — should remain unchanged
|
// Already initialized — should remain unchanged
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -226,12 +230,14 @@ fn ata_transfer() {
|
|||||||
vec![Nonce(0)],
|
vec![Nonce(0)],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::owner_key()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::owner_key()]);
|
||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
state.transition_from_public_transaction(&tx, 0, 0).unwrap();
|
state
|
||||||
|
.transition_from_public_transaction(&tx, 0, 0)
|
||||||
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
state.get_account_by_id(Ids::owner_ata()),
|
state.get_account_by_id(Ids::owner_ata()),
|
||||||
@ -275,12 +281,14 @@ fn ata_burn() {
|
|||||||
vec![Nonce(0)],
|
vec![Nonce(0)],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::owner_key()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::owner_key()]);
|
||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
state.transition_from_public_transaction(&tx, 0, 0).unwrap();
|
state
|
||||||
|
.transition_from_public_transaction(&tx, 0, 0)
|
||||||
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
state.get_account_by_id(Ids::owner_ata()),
|
state.get_account_by_id(Ids::owner_ata()),
|
||||||
@ -340,15 +348,18 @@ fn ata_create_from_private_owner() {
|
|||||||
let instruction = ata_core::Instruction::Create {
|
let instruction = ata_core::Instruction::Create {
|
||||||
ata_program_id: Ids::ata_program(),
|
ata_program_id: Ids::ata_program(),
|
||||||
};
|
};
|
||||||
let instruction_data = Program::serialize_instruction(instruction).unwrap();
|
let instruction_data =
|
||||||
|
Program::serialize_instruction(instruction).expect("test setup should succeed");
|
||||||
|
|
||||||
// Ephemeral key for encrypting the private owner's post-state
|
// Ephemeral key for encrypting the private owner's post-state
|
||||||
let esk: Scalar = [3u8; 32];
|
let esk: Scalar = [3u8; 32];
|
||||||
let shared_secret = SharedSecretKey::new(&esk, &owner_vpk);
|
let shared_secret = SharedSecretKey::new(&esk, &owner_vpk);
|
||||||
let epk = EphemeralPublicKey::from_scalar(esk);
|
let epk = EphemeralPublicKey::from_scalar(esk);
|
||||||
|
|
||||||
let ata_program = Program::new(ata_methods::ATA_ELF.to_vec()).unwrap();
|
let ata_program =
|
||||||
let token_program = Program::new(token_methods::TOKEN_ELF.to_vec()).unwrap();
|
Program::new(ata_methods::ATA_ELF.to_vec()).expect("test setup should succeed");
|
||||||
|
let token_program =
|
||||||
|
Program::new(token_methods::TOKEN_ELF.to_vec()).expect("test setup should succeed");
|
||||||
let program_with_deps = ProgramWithDependencies::new(
|
let program_with_deps = ProgramWithDependencies::new(
|
||||||
ata_program,
|
ata_program,
|
||||||
HashMap::from([(Ids::token_program(), token_program)]),
|
HashMap::from([(Ids::token_program(), token_program)]),
|
||||||
@ -364,7 +375,7 @@ fn ata_create_from_private_owner() {
|
|||||||
vec![None], // no membership proof: owner is being created, not spending
|
vec![None], // no membership proof: owner is being created, not spending
|
||||||
&program_with_deps,
|
&program_with_deps,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let message = Message::try_from_circuit_output(
|
let message = Message::try_from_circuit_output(
|
||||||
vec![Ids::token_definition(), owner_ata_id],
|
vec![Ids::token_definition(), owner_ata_id],
|
||||||
@ -372,13 +383,13 @@ fn ata_create_from_private_owner() {
|
|||||||
vec![(owner_npk, owner_vpk, epk)],
|
vec![(owner_npk, owner_vpk, epk)],
|
||||||
output,
|
output,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = WitnessSet::for_message(&message, proof, &[]);
|
let witness_set = WitnessSet::for_message(&message, proof, &[]);
|
||||||
let tx = PrivacyPreservingTransaction::new(message, witness_set);
|
let tx = PrivacyPreservingTransaction::new(message, witness_set);
|
||||||
state
|
state
|
||||||
.transition_from_privacy_preserving_transaction(&tx, 0, 0)
|
.transition_from_privacy_preserving_transaction(&tx, 0, 0)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
state.get_account_by_id(owner_ata_id),
|
state.get_account_by_id(owner_ata_id),
|
||||||
|
|||||||
@ -129,7 +129,7 @@ fn token_new_fungible_definition() {
|
|||||||
vec![Nonce(0), Nonce(0)],
|
vec![Nonce(0), Nonce(0)],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(
|
let witness_set = public_transaction::WitnessSet::for_message(
|
||||||
&message,
|
&message,
|
||||||
@ -137,7 +137,9 @@ fn token_new_fungible_definition() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
state.transition_from_public_transaction(&tx, 0, 0).unwrap();
|
state
|
||||||
|
.transition_from_public_transaction(&tx, 0, 0)
|
||||||
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
state.get_account_by_id(Ids::token_definition()),
|
state.get_account_by_id(Ids::token_definition()),
|
||||||
@ -181,12 +183,14 @@ fn token_transfer() {
|
|||||||
vec![Nonce(0)],
|
vec![Nonce(0)],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::holder_key()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::holder_key()]);
|
||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
state.transition_from_public_transaction(&tx, 0, 0).unwrap();
|
state
|
||||||
|
.transition_from_public_transaction(&tx, 0, 0)
|
||||||
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
state.get_account_by_id(Ids::holder()),
|
state.get_account_by_id(Ids::holder()),
|
||||||
@ -229,7 +233,7 @@ fn token_transfer_fresh_public_recipient_requires_authorization() {
|
|||||||
vec![Nonce(0)],
|
vec![Nonce(0)],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::holder_key()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::holder_key()]);
|
||||||
|
|
||||||
@ -260,7 +264,7 @@ fn token_transfer_fresh_authorized_public_recipient() {
|
|||||||
vec![Nonce(0), Nonce(0)],
|
vec![Nonce(0), Nonce(0)],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(
|
let witness_set = public_transaction::WitnessSet::for_message(
|
||||||
&message,
|
&message,
|
||||||
@ -268,7 +272,9 @@ fn token_transfer_fresh_authorized_public_recipient() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
state.transition_from_public_transaction(&tx, 0, 0).unwrap();
|
state
|
||||||
|
.transition_from_public_transaction(&tx, 0, 0)
|
||||||
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
state.get_account_by_id(Ids::holder()),
|
state.get_account_by_id(Ids::holder()),
|
||||||
@ -311,12 +317,14 @@ fn token_burn() {
|
|||||||
vec![Nonce(0)],
|
vec![Nonce(0)],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::holder_key()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::holder_key()]);
|
||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
state.transition_from_public_transaction(&tx, 0, 0).unwrap();
|
state
|
||||||
|
.transition_from_public_transaction(&tx, 0, 0)
|
||||||
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
state.get_account_by_id(Ids::token_definition()),
|
state.get_account_by_id(Ids::token_definition()),
|
||||||
@ -360,12 +368,14 @@ fn token_mint() {
|
|||||||
vec![Nonce(0)],
|
vec![Nonce(0)],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::def_key()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::def_key()]);
|
||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
state.transition_from_public_transaction(&tx, 0, 0).unwrap();
|
state
|
||||||
|
.transition_from_public_transaction(&tx, 0, 0)
|
||||||
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
state.get_account_by_id(Ids::token_definition()),
|
state.get_account_by_id(Ids::token_definition()),
|
||||||
@ -409,7 +419,7 @@ fn token_mint_fresh_public_recipient_requires_authorization() {
|
|||||||
vec![Nonce(0)],
|
vec![Nonce(0)],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::def_key()]);
|
let witness_set = public_transaction::WitnessSet::for_message(&message, &[&Keys::def_key()]);
|
||||||
|
|
||||||
@ -440,7 +450,7 @@ fn token_mint_fresh_authorized_public_recipient() {
|
|||||||
vec![Nonce(0), Nonce(0)],
|
vec![Nonce(0), Nonce(0)],
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = public_transaction::WitnessSet::for_message(
|
let witness_set = public_transaction::WitnessSet::for_message(
|
||||||
&message,
|
&message,
|
||||||
@ -448,7 +458,9 @@ fn token_mint_fresh_authorized_public_recipient() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
state.transition_from_public_transaction(&tx, 0, 0).unwrap();
|
state
|
||||||
|
.transition_from_public_transaction(&tx, 0, 0)
|
||||||
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
state.get_account_by_id(Ids::token_definition()),
|
state.get_account_by_id(Ids::token_definition()),
|
||||||
@ -539,14 +551,14 @@ fn shielded_token_transfer(amount: u128, state: &mut V03State) -> Account {
|
|||||||
};
|
};
|
||||||
let (output, proof) = execute_and_prove(
|
let (output, proof) = execute_and_prove(
|
||||||
vec![sender, recipient],
|
vec![sender, recipient],
|
||||||
Program::serialize_instruction(instruction).unwrap(),
|
Program::serialize_instruction(instruction).expect("test setup should succeed"),
|
||||||
vec![0, 2],
|
vec![0, 2],
|
||||||
vec![(PrivateKeys::recipient_npk(), shared_secret)],
|
vec![(PrivateKeys::recipient_npk(), shared_secret)],
|
||||||
vec![],
|
vec![],
|
||||||
vec![None],
|
vec![None],
|
||||||
&token_program().into(),
|
&token_program().into(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let message = Message::try_from_circuit_output(
|
let message = Message::try_from_circuit_output(
|
||||||
vec![sender_id],
|
vec![sender_id],
|
||||||
@ -558,13 +570,13 @@ fn shielded_token_transfer(amount: u128, state: &mut V03State) -> Account {
|
|||||||
)],
|
)],
|
||||||
output,
|
output,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = WitnessSet::for_message(&message, proof, &[&Keys::holder_key()]);
|
let witness_set = WitnessSet::for_message(&message, proof, &[&Keys::holder_key()]);
|
||||||
let tx = PrivacyPreservingTransaction::new(message, witness_set);
|
let tx = PrivacyPreservingTransaction::new(message, witness_set);
|
||||||
state
|
state
|
||||||
.transition_from_privacy_preserving_transaction(&tx, 0, 0)
|
.transition_from_privacy_preserving_transaction(&tx, 0, 0)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
Account {
|
Account {
|
||||||
program_owner: Ids::token_program(),
|
program_owner: Ids::token_program(),
|
||||||
@ -636,7 +648,7 @@ fn token_private_transfer() {
|
|||||||
};
|
};
|
||||||
let (output, proof) = execute_and_prove(
|
let (output, proof) = execute_and_prove(
|
||||||
vec![sender_pre, new_recipient_pre],
|
vec![sender_pre, new_recipient_pre],
|
||||||
Program::serialize_instruction(instruction).unwrap(),
|
Program::serialize_instruction(instruction).expect("test setup should succeed"),
|
||||||
vec![1, 2],
|
vec![1, 2],
|
||||||
vec![
|
vec![
|
||||||
(sender_npk.clone(), shared_secret_1),
|
(sender_npk.clone(), shared_secret_1),
|
||||||
@ -646,7 +658,7 @@ fn token_private_transfer() {
|
|||||||
vec![state.get_proof_for_commitment(&sender_commitment), None],
|
vec![state.get_proof_for_commitment(&sender_commitment), None],
|
||||||
&token_program().into(),
|
&token_program().into(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let message = Message::try_from_circuit_output(
|
let message = Message::try_from_circuit_output(
|
||||||
vec![],
|
vec![],
|
||||||
@ -657,13 +669,13 @@ fn token_private_transfer() {
|
|||||||
],
|
],
|
||||||
output,
|
output,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = WitnessSet::for_message(&message, proof, &[]);
|
let witness_set = WitnessSet::for_message(&message, proof, &[]);
|
||||||
let tx = PrivacyPreservingTransaction::new(message, witness_set);
|
let tx = PrivacyPreservingTransaction::new(message, witness_set);
|
||||||
state
|
state
|
||||||
.transition_from_privacy_preserving_transaction(&tx, 0, 0)
|
.transition_from_privacy_preserving_transaction(&tx, 0, 0)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let sender_nonce_after =
|
let sender_nonce_after =
|
||||||
Nonce::private_account_nonce_init(&sender_npk).private_account_nonce_increment(&sender_nsk);
|
Nonce::private_account_nonce_init(&sender_npk).private_account_nonce_increment(&sender_nsk);
|
||||||
@ -725,14 +737,14 @@ fn token_deshielded_transfer() {
|
|||||||
};
|
};
|
||||||
let (output, proof) = execute_and_prove(
|
let (output, proof) = execute_and_prove(
|
||||||
vec![sender_pre, public_recipient_pre],
|
vec![sender_pre, public_recipient_pre],
|
||||||
Program::serialize_instruction(instruction).unwrap(),
|
Program::serialize_instruction(instruction).expect("test setup should succeed"),
|
||||||
vec![1, 0],
|
vec![1, 0],
|
||||||
vec![(sender_npk.clone(), shared_secret)],
|
vec![(sender_npk.clone(), shared_secret)],
|
||||||
vec![sender_nsk],
|
vec![sender_nsk],
|
||||||
vec![state.get_proof_for_commitment(&sender_commitment)],
|
vec![state.get_proof_for_commitment(&sender_commitment)],
|
||||||
&token_program().into(),
|
&token_program().into(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let message = Message::try_from_circuit_output(
|
let message = Message::try_from_circuit_output(
|
||||||
vec![public_recipient_id],
|
vec![public_recipient_id],
|
||||||
@ -740,13 +752,13 @@ fn token_deshielded_transfer() {
|
|||||||
vec![(sender_npk.clone(), sender_vpk, epk)],
|
vec![(sender_npk.clone(), sender_vpk, epk)],
|
||||||
output,
|
output,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
let witness_set = WitnessSet::for_message(&message, proof, &[]);
|
let witness_set = WitnessSet::for_message(&message, proof, &[]);
|
||||||
let tx = PrivacyPreservingTransaction::new(message, witness_set);
|
let tx = PrivacyPreservingTransaction::new(message, witness_set);
|
||||||
state
|
state
|
||||||
.transition_from_privacy_preserving_transaction(&tx, 0, 0)
|
.transition_from_privacy_preserving_transaction(&tx, 0, 0)
|
||||||
.unwrap();
|
.expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
state.get_account_by_id(public_recipient_id),
|
state.get_account_by_id(public_recipient_id),
|
||||||
|
|||||||
@ -3,6 +3,9 @@ name = "token_program"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc1", features = ["host"] }
|
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc1", features = ["host"] }
|
||||||
token_core = { path = "core" }
|
token_core = { path = "core" }
|
||||||
|
|||||||
@ -3,6 +3,9 @@ name = "token_core"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc1", features = ["host"] }
|
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc1", features = ["host"] }
|
||||||
borsh = { version = "1.5", features = ["derive"] }
|
borsh = { version = "1.5", features = ["derive"] }
|
||||||
|
|||||||
@ -3,6 +3,9 @@ name = "token-methods"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
risc0-build = "=3.0.5"
|
risc0-build = "=3.0.5"
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,32 @@ edition = "2021"
|
|||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
|
|
||||||
|
[lints.rust]
|
||||||
|
rust_2018_idioms = { level = "deny", priority = -1 }
|
||||||
|
unsafe_code = "forbid"
|
||||||
|
|
||||||
|
[lints.clippy]
|
||||||
|
all = { level = "deny", priority = -1 }
|
||||||
|
allow_attributes = "warn"
|
||||||
|
allow_attributes_without_reason = "deny"
|
||||||
|
arithmetic_side_effects = "deny"
|
||||||
|
as_conversions = "deny"
|
||||||
|
cast_possible_truncation = "deny"
|
||||||
|
cast_possible_wrap = "deny"
|
||||||
|
cast_precision_loss = "warn"
|
||||||
|
cast_sign_loss = "deny"
|
||||||
|
dbg_macro = "deny"
|
||||||
|
indexing_slicing = "deny"
|
||||||
|
integer_division = "warn"
|
||||||
|
large_enum_variant = "deny"
|
||||||
|
match_wildcard_for_single_variants = "warn"
|
||||||
|
module_name_repetitions = "allow"
|
||||||
|
similar_names = "allow"
|
||||||
|
todo = "deny"
|
||||||
|
unimplemented = "deny"
|
||||||
|
unwrap_used = "deny"
|
||||||
|
wildcard_enum_match_arm = "deny"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "token"
|
name = "token"
|
||||||
path = "src/bin/token.rs"
|
path = "src/bin/token.rs"
|
||||||
|
|||||||
@ -1,17 +1,25 @@
|
|||||||
#![no_main]
|
#![cfg_attr(not(test), no_main)]
|
||||||
|
|
||||||
use spel_framework::prelude::*;
|
use spel_framework::prelude::*;
|
||||||
use nssa_core::account::AccountWithMetadata;
|
use nssa_core::account::AccountWithMetadata;
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
risc0_zkvm::guest::entry!(main);
|
risc0_zkvm::guest::entry!(main);
|
||||||
|
|
||||||
#[lez_program(instruction = "token_core::Instruction")]
|
#[lez_program(instruction = "token_core::Instruction")]
|
||||||
mod token {
|
mod token {
|
||||||
#[allow(unused_imports)]
|
#[expect(
|
||||||
|
unused_imports,
|
||||||
|
reason = "SPEL instruction macro requires importing parent-scope handler types"
|
||||||
|
)]
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// Transfer tokens from sender to recipient.
|
/// Transfer tokens from sender to recipient.
|
||||||
/// Fresh public recipients must be explicitly authorized in the same transaction.
|
/// Fresh public recipients must be explicitly authorized in the same transaction.
|
||||||
|
#[expect(
|
||||||
|
deprecated,
|
||||||
|
reason = "token guest states-only wrapper remains until auto-claim migration is scoped"
|
||||||
|
)]
|
||||||
#[instruction]
|
#[instruction]
|
||||||
pub fn transfer(
|
pub fn transfer(
|
||||||
sender: AccountWithMetadata,
|
sender: AccountWithMetadata,
|
||||||
@ -27,6 +35,10 @@ mod token {
|
|||||||
|
|
||||||
/// Create a new fungible token definition without metadata.
|
/// Create a new fungible token definition without metadata.
|
||||||
/// Definition and holding targets must be uninitialized and authorized.
|
/// Definition and holding targets must be uninitialized and authorized.
|
||||||
|
#[expect(
|
||||||
|
deprecated,
|
||||||
|
reason = "token guest states-only wrapper remains until auto-claim migration is scoped"
|
||||||
|
)]
|
||||||
#[instruction]
|
#[instruction]
|
||||||
pub fn new_fungible_definition(
|
pub fn new_fungible_definition(
|
||||||
definition_target_account: AccountWithMetadata,
|
definition_target_account: AccountWithMetadata,
|
||||||
@ -46,6 +58,14 @@ mod token {
|
|||||||
|
|
||||||
/// Create a new fungible or non-fungible token definition with metadata.
|
/// Create a new fungible or non-fungible token definition with metadata.
|
||||||
/// Definition, holding, and metadata targets must be uninitialized and authorized.
|
/// Definition, holding, and metadata targets must be uninitialized and authorized.
|
||||||
|
#[expect(
|
||||||
|
clippy::boxed_local,
|
||||||
|
reason = "boxed metadata keeps the generated instruction ABI size bounded"
|
||||||
|
)]
|
||||||
|
#[expect(
|
||||||
|
deprecated,
|
||||||
|
reason = "token guest states-only wrapper remains until auto-claim migration is scoped"
|
||||||
|
)]
|
||||||
#[instruction]
|
#[instruction]
|
||||||
pub fn new_definition_with_metadata(
|
pub fn new_definition_with_metadata(
|
||||||
definition_target_account: AccountWithMetadata,
|
definition_target_account: AccountWithMetadata,
|
||||||
@ -67,6 +87,10 @@ mod token {
|
|||||||
|
|
||||||
/// Initialize a token holding account for a given token definition.
|
/// Initialize a token holding account for a given token definition.
|
||||||
/// The holding target must be uninitialized and authorized.
|
/// The holding target must be uninitialized and authorized.
|
||||||
|
#[expect(
|
||||||
|
deprecated,
|
||||||
|
reason = "token guest states-only wrapper remains until auto-claim migration is scoped"
|
||||||
|
)]
|
||||||
#[instruction]
|
#[instruction]
|
||||||
pub fn initialize_account(
|
pub fn initialize_account(
|
||||||
definition_account: AccountWithMetadata,
|
definition_account: AccountWithMetadata,
|
||||||
@ -81,6 +105,10 @@ mod token {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Burn tokens from the holder's account.
|
/// Burn tokens from the holder's account.
|
||||||
|
#[expect(
|
||||||
|
deprecated,
|
||||||
|
reason = "token guest states-only wrapper remains until auto-claim migration is scoped"
|
||||||
|
)]
|
||||||
#[instruction]
|
#[instruction]
|
||||||
pub fn burn(
|
pub fn burn(
|
||||||
definition_account: AccountWithMetadata,
|
definition_account: AccountWithMetadata,
|
||||||
@ -96,6 +124,10 @@ mod token {
|
|||||||
|
|
||||||
/// Mint new tokens to the holder's account.
|
/// Mint new tokens to the holder's account.
|
||||||
/// Fresh public holders must be explicitly authorized in the same transaction.
|
/// Fresh public holders must be explicitly authorized in the same transaction.
|
||||||
|
#[expect(
|
||||||
|
deprecated,
|
||||||
|
reason = "token guest states-only wrapper remains until auto-claim migration is scoped"
|
||||||
|
)]
|
||||||
#[instruction]
|
#[instruction]
|
||||||
pub fn mint(
|
pub fn mint(
|
||||||
definition_account: AccountWithMetadata,
|
definition_account: AccountWithMetadata,
|
||||||
@ -111,6 +143,10 @@ mod token {
|
|||||||
|
|
||||||
/// Print a new NFT from the master copy.
|
/// Print a new NFT from the master copy.
|
||||||
/// The printed copy target must be uninitialized and authorized.
|
/// The printed copy target must be uninitialized and authorized.
|
||||||
|
#[expect(
|
||||||
|
deprecated,
|
||||||
|
reason = "token guest states-only wrapper remains until auto-claim migration is scoped"
|
||||||
|
)]
|
||||||
#[instruction]
|
#[instruction]
|
||||||
pub fn print_nft(
|
pub fn print_nft(
|
||||||
master_account: AccountWithMetadata,
|
master_account: AccountWithMetadata,
|
||||||
|
|||||||
@ -40,7 +40,9 @@ pub fn print_nft(
|
|||||||
*print_balance > 1,
|
*print_balance > 1,
|
||||||
"Insufficient balance to print another NFT copy"
|
"Insufficient balance to print another NFT copy"
|
||||||
);
|
);
|
||||||
*print_balance -= 1;
|
*print_balance = print_balance
|
||||||
|
.checked_sub(1)
|
||||||
|
.expect("print balance must be greater than one after validation");
|
||||||
|
|
||||||
let mut master_account_post = master_account.account;
|
let mut master_account_post = master_account.account;
|
||||||
master_account_post.data = Data::from(&master_account_data);
|
master_account_post.data = Data::from(&master_account_data);
|
||||||
|
|||||||
@ -1,4 +1,8 @@
|
|||||||
#![cfg(test)]
|
#![cfg(test)]
|
||||||
|
#![expect(
|
||||||
|
clippy::arithmetic_side_effects,
|
||||||
|
reason = "test fixtures use fixed values to lock boundary behavior"
|
||||||
|
)]
|
||||||
|
|
||||||
use nssa_core::{
|
use nssa_core::{
|
||||||
account::{Account, AccountId, AccountWithMetadata, Data, Nonce},
|
account::{Account, AccountId, AccountWithMetadata, Data, Nonce},
|
||||||
@ -635,7 +639,8 @@ fn test_new_definition_with_valid_inputs_succeeds() {
|
|||||||
BalanceForTests::init_supply(),
|
BalanceForTests::init_supply(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let [definition_account, holding_account] = post_states.try_into().unwrap();
|
let [definition_account, holding_account] =
|
||||||
|
post_states.try_into().expect("test setup should succeed");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*definition_account.account(),
|
*definition_account.account(),
|
||||||
AccountForTests::definition_account_unclaimed().account
|
AccountForTests::definition_account_unclaimed().account
|
||||||
@ -679,7 +684,7 @@ fn test_transfer_with_valid_inputs_succeeds() {
|
|||||||
let sender = AccountForTests::holding_account_init();
|
let sender = AccountForTests::holding_account_init();
|
||||||
let recipient = AccountForTests::holding_account2_init();
|
let recipient = AccountForTests::holding_account2_init();
|
||||||
let post_states = transfer(sender, recipient, BalanceForTests::transfer_amount());
|
let post_states = transfer(sender, recipient, BalanceForTests::transfer_amount());
|
||||||
let [sender_post, recipient_post] = post_states.try_into().unwrap();
|
let [sender_post, recipient_post] = post_states.try_into().expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*sender_post.account(),
|
*sender_post.account(),
|
||||||
@ -714,7 +719,7 @@ fn test_transfer_with_master_nft_success() {
|
|||||||
let sender = AccountForTests::holding_account_master_nft();
|
let sender = AccountForTests::holding_account_master_nft();
|
||||||
let recipient = AccountForTests::holding_account_uninit();
|
let recipient = AccountForTests::holding_account_uninit();
|
||||||
let post_states = transfer(sender, recipient, BalanceForTests::printable_copies());
|
let post_states = transfer(sender, recipient, BalanceForTests::printable_copies());
|
||||||
let [sender_post, recipient_post] = post_states.try_into().unwrap();
|
let [sender_post, recipient_post] = post_states.try_into().expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*sender_post.account(),
|
*sender_post.account(),
|
||||||
@ -731,7 +736,7 @@ fn test_transfer_with_default_recipient_claims_recipient() {
|
|||||||
let sender = AccountForTests::holding_account_init();
|
let sender = AccountForTests::holding_account_init();
|
||||||
let recipient = AccountForTests::holding_account_uninit();
|
let recipient = AccountForTests::holding_account_uninit();
|
||||||
let post_states = transfer(sender, recipient, BalanceForTests::transfer_amount());
|
let post_states = transfer(sender, recipient, BalanceForTests::transfer_amount());
|
||||||
let [sender_post, recipient_post] = post_states.try_into().unwrap();
|
let [sender_post, recipient_post] = post_states.try_into().expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*sender_post.account(),
|
*sender_post.account(),
|
||||||
@ -758,7 +763,8 @@ fn test_token_initialize_account_succeeds() {
|
|||||||
let definition_account = AccountForTests::definition_account_auth();
|
let definition_account = AccountForTests::definition_account_auth();
|
||||||
let holding_account = AccountForTests::holding_account_uninit_auth();
|
let holding_account = AccountForTests::holding_account_uninit_auth();
|
||||||
let post_states = initialize_account(definition_account, holding_account);
|
let post_states = initialize_account(definition_account, holding_account);
|
||||||
let [definition_post, holding_post] = post_states.try_into().unwrap();
|
let [definition_post, holding_post] =
|
||||||
|
post_states.try_into().expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*definition_post.account(),
|
*definition_post.account(),
|
||||||
@ -847,7 +853,7 @@ fn test_burn_success() {
|
|||||||
BalanceForTests::burn_success(),
|
BalanceForTests::burn_success(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let [def_post, holding_post] = post_states.try_into().unwrap();
|
let [def_post, holding_post] = post_states.try_into().expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*def_post.account(),
|
*def_post.account(),
|
||||||
@ -917,7 +923,7 @@ fn test_mint_success() {
|
|||||||
BalanceForTests::mint_success(),
|
BalanceForTests::mint_success(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let [def_post, holding_post] = post_states.try_into().unwrap();
|
let [def_post, holding_post] = post_states.try_into().expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*def_post.account(),
|
*def_post.account(),
|
||||||
@ -941,7 +947,7 @@ fn test_mint_uninit_holding_success() {
|
|||||||
BalanceForTests::mint_success(),
|
BalanceForTests::mint_success(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let [def_post, holding_post] = post_states.try_into().unwrap();
|
let [def_post, holding_post] = post_states.try_into().expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*def_post.account(),
|
*def_post.account(),
|
||||||
@ -1013,7 +1019,8 @@ fn test_new_definition_with_metadata_success() {
|
|||||||
new_definition,
|
new_definition,
|
||||||
metadata,
|
metadata,
|
||||||
);
|
);
|
||||||
let [definition_post, holding_post, metadata_post] = post_states.try_into().unwrap();
|
let [definition_post, holding_post, metadata_post] =
|
||||||
|
post_states.try_into().expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(definition_post.required_claim(), Some(Claim::Authorized));
|
assert_eq!(definition_post.required_claim(), Some(Claim::Authorized));
|
||||||
assert_eq!(holding_post.required_claim(), Some(Claim::Authorized));
|
assert_eq!(holding_post.required_claim(), Some(Claim::Authorized));
|
||||||
@ -1246,7 +1253,8 @@ fn test_print_nft_success() {
|
|||||||
let printed_account = AccountForTests::holding_account_uninit_auth();
|
let printed_account = AccountForTests::holding_account_uninit_auth();
|
||||||
let post_states = print_nft(master_account, printed_account);
|
let post_states = print_nft(master_account, printed_account);
|
||||||
|
|
||||||
let [post_master_nft, post_printed] = post_states.try_into().unwrap();
|
let [post_master_nft, post_printed] =
|
||||||
|
post_states.try_into().expect("test setup should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*post_master_nft.account(),
|
*post_master_nft.account(),
|
||||||
|
|||||||
@ -3,6 +3,9 @@ name = "idl-gen"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "idl-gen"
|
name = "idl-gen"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|||||||
@ -10,7 +10,11 @@ fn main() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match spel_framework_core::idl_gen::generate_idl_from_file(&path) {
|
match spel_framework_core::idl_gen::generate_idl_from_file(&path) {
|
||||||
Ok(idl) => println!("{}", serde_json::to_string_pretty(&idl).unwrap()),
|
Ok(idl) => println!(
|
||||||
|
"{}",
|
||||||
|
serde_json::to_string_pretty(&idl)
|
||||||
|
.expect("serializing generated IDL to JSON should not fail")
|
||||||
|
),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Error: {e}");
|
eprintln!("Error: {e}");
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user