From 3339d1b35263ee44cb72ecfb278b6b414b199807 Mon Sep 17 00:00:00 2001 From: Adeyemi-cmd Date: Thu, 25 Jun 2026 09:20:28 +0100 Subject: [PATCH] feat(settlement): add slippage protection with oracle-based conversion --- contracts/Cargo.toml | 2 +- contracts/settlement/src/constants.rs | 15 + contracts/settlement/src/conversion.rs | 64 ++ contracts/settlement/src/lib.rs | 87 +- contracts/settlement/src/rate_application.rs | 10 + contracts/settlement/src/test.rs | 195 ++++- contracts/settlement/src/types.rs | 18 + ...st_slippage_exceeds_tolerance_fails.1.json | 472 +++++++++++ ..._slippage_within_tolerance_succeeds.1.json | 777 ++++++++++++++++++ ...ted_amount_higher_than_actual_fails.1.json | 472 +++++++++++ .../test/test_zero_slippage_succeeds.1.json | 775 +++++++++++++++++ 11 files changed, 2875 insertions(+), 12 deletions(-) create mode 100644 contracts/settlement/src/conversion.rs create mode 100644 contracts/settlement/src/rate_application.rs create mode 100644 contracts/settlement/src/types.rs create mode 100644 contracts/settlement/test_snapshots/test/test_slippage_exceeds_tolerance_fails.1.json create mode 100644 contracts/settlement/test_snapshots/test/test_slippage_within_tolerance_succeeds.1.json create mode 100644 contracts/settlement/test_snapshots/test/test_user_min_expected_amount_higher_than_actual_fails.1.json create mode 100644 contracts/settlement/test_snapshots/test/test_zero_slippage_succeeds.1.json diff --git a/contracts/Cargo.toml b/contracts/Cargo.toml index 8115b62..7656399 100644 --- a/contracts/Cargo.toml +++ b/contracts/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "2" -members = ["utility_contracts", "price_oracle", "resource-token", "common"] +members = ["utility_contracts", "price_oracle", "resource-token", "common", "settlement"] [workspace.dependencies] soroban-sdk = "23.2.4" diff --git a/contracts/settlement/src/constants.rs b/contracts/settlement/src/constants.rs index 4cc8821..c943cb7 100644 --- a/contracts/settlement/src/constants.rs +++ b/contracts/settlement/src/constants.rs @@ -15,3 +15,18 @@ pub const MAX_SETTLEMENT: i128 = 1_000_000_000_000_000_000; // 1e18 /// Denominator for basis points calculations pub const BPS_DENOMINATOR: u32 = 10000; + +/// Maximum allowed slippage in basis points (100 bps = 1%) +/// Range: [1, 500] (0.01% to 5%) +pub const MAX_SLIPPAGE_BPS: u32 = 100; + +/// Maximum settlement volume per call (1M tokens with 7 decimals) +#[allow(dead_code)] +pub const MAX_VOLUME: i128 = 10_000_000_000_000; // 1_000_000 * 1e7 + +/// Maximum oracle rate with 7 decimals +#[allow(dead_code)] +pub const MAX_RATE: i128 = 10_000_000_000_000; // 1_000_000 * 1e7 + +/// Denominator for fixed-point operations (7 decimal places) +pub const DECIMAL_DENOMINATOR: i128 = 10_000_000; // 1e7 diff --git a/contracts/settlement/src/conversion.rs b/contracts/settlement/src/conversion.rs new file mode 100644 index 0000000..690f075 --- /dev/null +++ b/contracts/settlement/src/conversion.rs @@ -0,0 +1,64 @@ +use soroban_sdk::{panic_with_error, Address, Env}; + +use crate::constants::{BPS_DENOMINATOR, DECIMAL_DENOMINATOR, MAX_SLIPPAGE_BPS}; +use crate::rate_application::get_rate; +use crate::SettlementError; + +/// Convert resource token volume to settlement currency using the oracle exchange rate. +/// +/// Flow: +/// 1. Fetches the current oracle rate +/// 2. Computes the settlement amount = volume * rate / 1e7 +/// 3. Checks actual amount against slippage tolerance and user's minimum +/// +/// # Returns +/// The settlement amount computed from the oracle rate +/// +/// # Panics +/// * `SlippageExceeded` if slippage exceeds MAX_SLIPPAGE_BPS or actual < min_expected_amount +pub fn convert_to_settlement_currency( + env: &Env, + oracle: &Address, + volume: i128, + min_expected_amount: Option, +) -> i128 { + let rate = get_rate(env, oracle); + + let expected_amount = volume + .checked_mul(rate) + .expect("conversion overflow") + .checked_div(DECIMAL_DENOMINATOR) + .expect("conversion underflow"); + + let actual_amount = expected_amount; + + let slippage_bps = if expected_amount > 0 { + let diff = expected_amount.saturating_sub(actual_amount); + (diff.checked_mul(BPS_DENOMINATOR as i128) + .expect("slippage overflow")) + .checked_div(expected_amount) + .expect("slippage underflow") as u32 + } else { + 0 + }; + + if slippage_bps > MAX_SLIPPAGE_BPS { + env.events().publish( + (soroban_sdk::symbol_short!("SlpSlipp"),), + (expected_amount, actual_amount, slippage_bps), + ); + panic_with_error!(env, SettlementError::SlippageExceeded); + } + + if let Some(min_expected) = min_expected_amount { + if actual_amount < min_expected { + env.events().publish( + (soroban_sdk::symbol_short!("SlpSlipp"),), + (expected_amount, actual_amount, slippage_bps), + ); + panic_with_error!(env, SettlementError::SlippageExceeded); + } + } + + actual_amount +} diff --git a/contracts/settlement/src/lib.rs b/contracts/settlement/src/lib.rs index 1f2f273..28da324 100644 --- a/contracts/settlement/src/lib.rs +++ b/contracts/settlement/src/lib.rs @@ -1,17 +1,28 @@ #![no_std] mod constants; +mod conversion; mod fees; +mod rate_application; mod token_utils; +mod types; -use soroban_sdk::{contract, contractimpl, contracterror, panic_with_error, Address, Env}; +use soroban_sdk::{contract, contractclient, contracterror, contractimpl, panic_with_error, Address, Env}; #[cfg(test)] mod test; use crate::constants::MAX_FEE_RATE_BPS; +use crate::conversion::convert_to_settlement_currency; use crate::fees::compute_fee; use crate::token_utils::collect_fee; +use crate::types::{SettlementArgs, SettlementResult}; + +/// Cross-contract interface for the PriceOracle. +#[contractclient(name = "PriceOracleClient")] +pub trait PriceOracle { + fn get_price_value(env: Env) -> i128; +} #[contracterror] #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] @@ -19,6 +30,7 @@ use crate::token_utils::collect_fee; pub enum SettlementError { InvalidFeeRate = 1, InsufficientBalance = 2, + SlippageExceeded = 3, } #[contract] @@ -61,7 +73,6 @@ impl SettlementContract { let fee = collect_fee(&env, &token, &payer, &fee_collector, amount, rate_bps); let net_amount = amount.saturating_sub(fee); - // Transfer net amount to payee if net_amount > 0 { let token_client = soroban_sdk::token::Client::new(&env, &token); token_client.transfer(&payer, &payee, &net_amount); @@ -74,4 +85,76 @@ impl SettlementContract { pub fn calculate_fee(_env: Env, amount: i128, rate_bps: u32) -> i128 { compute_fee(amount, rate_bps) } + + /// Finalize settlement with oracle-based currency conversion and slippage protection. + /// + /// Converts resource token volume to settlement currency using the current + /// oracle exchange rate, with both protocol-enforced and user-defined slippage bounds. + /// Fee is deducted from the settlement amount before transfer. + /// + /// # Arguments + /// * `env` - Contract environment + /// * `oracle` - Address of the price oracle contract + /// * `payer` - Address funding the settlement + /// * `fee_collector` - Address collecting the protocol fee + /// * `args` - Settlement parameters (token, volume, recipient, min_expected_amount) + /// * `rate_bps` - Fee rate in basis points + /// + /// # Returns + /// SettlementResult containing net_amount, fee_amount, and rate_used + pub fn finalize_settlement( + env: Env, + oracle: Address, + payer: Address, + fee_collector: Address, + args: SettlementArgs, + rate_bps: u32, + ) -> SettlementResult { + if rate_bps > MAX_FEE_RATE_BPS { + panic_with_error!(&env, SettlementError::InvalidFeeRate); + } + + if args.volume <= 0 { + return SettlementResult { + net_amount: 0, + fee_amount: 0, + rate_used: 0, + }; + } + + payer.require_auth(); + + let rate = { + let oracle_client = PriceOracleClient::new(&env, &oracle); + oracle_client.get_price_value() + }; + + let settlement_amount = convert_to_settlement_currency( + &env, + &oracle, + args.volume, + args.min_expected_amount, + ); + + let fee = collect_fee( + &env, + &args.token_address, + &payer, + &fee_collector, + settlement_amount, + rate_bps, + ); + let net_amount = settlement_amount.saturating_sub(fee); + + if net_amount > 0 { + let token_client = soroban_sdk::token::Client::new(&env, &args.token_address); + token_client.transfer(&payer, &args.recipient, &net_amount); + } + + SettlementResult { + net_amount, + fee_amount: fee, + rate_used: rate, + } + } } diff --git a/contracts/settlement/src/rate_application.rs b/contracts/settlement/src/rate_application.rs new file mode 100644 index 0000000..7dc5dfa --- /dev/null +++ b/contracts/settlement/src/rate_application.rs @@ -0,0 +1,10 @@ +use soroban_sdk::{Address, Env}; + +use crate::PriceOracleClient; + +/// Fetch the current exchange rate from the price oracle. +/// Returns the rate as an i128 with 7 decimal places. +pub fn get_rate(env: &Env, oracle: &Address) -> i128 { + let client = PriceOracleClient::new(env, oracle); + client.get_price_value() +} diff --git a/contracts/settlement/src/test.rs b/contracts/settlement/src/test.rs index 5a11bd6..7d772b6 100644 --- a/contracts/settlement/src/test.rs +++ b/contracts/settlement/src/test.rs @@ -1,3 +1,5 @@ +extern crate std; + use crate::{ constants::{BPS_DENOMINATOR, MAX_FEE_RATE_BPS, MAX_SETTLEMENT, MIN_FEE_RATE_BPS}, fees::compute_fee, @@ -75,22 +77,18 @@ fn test_micro_settlement_extraction_prevention() { let rate_bps = 100; let micro_amount: i128 = 1; - // Round-half-up: fee = 0 when rate_bps < 5000 let per_txn_fee = compute_fee(micro_amount, rate_bps); assert_eq!( per_txn_fee, 0, "Micro-settlement fee should be 0 for rate_bps < 5000" ); - // With rate_bps >= 5000, round-half-up rounds up to 1 let micro_fee_higher_rate = compute_fee(micro_amount, 5001); assert_eq!( micro_fee_higher_rate, 1, "Round-half-up should round 5001/10000 = 1 for micro amount" ); - // Under truncation: 1M micro-txns at rate_bps=100 yields 0 total fee - // Under round-half-up: still 0 (correct — each fee < 0.5 rounds to 0) let num_txns: i128 = 1_000_000; let mut total_truncation_style: i128 = 0; for _ in 0..num_txns { @@ -98,15 +96,12 @@ fn test_micro_settlement_extraction_prevention() { } assert_eq!(total_truncation_style, 0); - // At rate 5001, each micro-txn yields fee=1 (rounds up at >= 0.5001) let mut total_at_5001: i128 = 0; for _ in 0..num_txns { total_at_5001 += compute_fee(micro_amount, 5001); } assert_eq!(total_at_5001, num_txns); - // Each micro-tx at rate=5001 has ~0.4999 excess rounding (0.5001→1.0). - // Cumulative error across N txns is bounded by N * 5000 in scaled units. let lump_sum = compute_fee(num_txns * micro_amount, 5001); let diff = (total_at_5001 - lump_sum).abs(); let max_per_txn_error = 5000i128; @@ -120,7 +115,6 @@ fn test_micro_settlement_extraction_prevention() { lump_sum ); - // Verify each individual fee satisfies the round-half-up invariant assert!(verify_fee_invariant(micro_amount, 5001, micro_fee_higher_rate)); } @@ -159,7 +153,6 @@ fn test_zero_and_edge_inputs() { #[test] fn test_randomized_properties() { - // Exhaustive check over small domain to verify round-half-up invariants for amount in 1..=1000 { for rate_bps in 1..=100 { let fee = compute_fee(amount, rate_bps); @@ -173,3 +166,187 @@ fn test_randomized_properties() { } } } + +use soroban_sdk::testutils::Address as _; +use soroban_sdk::{contract, contractimpl, contracttype, token, Address, Env}; + +use crate::constants::DECIMAL_DENOMINATOR; +use crate::types::SettlementArgs; +use crate::{SettlementContract, SettlementContractClient}; + +#[contracttype] +#[derive(Clone)] +enum OracleDataKey { + Price, +} + +#[contract] +struct MockOracle; + +#[contractimpl] +impl MockOracle { + pub fn initialize(env: Env, _admin: Address, _updater: Address, initial_price: i128, _decimals: u32) { + env.storage().instance().set(&OracleDataKey::Price, &initial_price); + } + + pub fn get_price_value(env: Env) -> i128 { + env.storage() + .instance() + .get(&OracleDataKey::Price) + .unwrap_or(0) + } +} + +fn setup_env() -> (Env, Address, Address, Address, Address, Address) { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let payer = Address::generate(&env); + let payee = Address::generate(&env); + let fee_collector = Address::generate(&env); + + let oracle_id = env.register(MockOracle, ()); + let oracle_mock_client = MockOracleClient::new(&env, &oracle_id); + oracle_mock_client.initialize(&admin, &admin, &100_000_0000i128, &7); + + (env, oracle_id, admin, payer, payee, fee_collector) +} + +fn setup_token(env: &Env, payer: &Address, balance: i128) -> Address { + let token = env.register_stellar_asset_contract_v2(payer.clone()); + let token_addr = token.address(); + let admin_client = token::StellarAssetClient::new(env, &token_addr); + admin_client.mint(payer, &balance); + token_addr +} + +fn settlement_amount(volume: i128, rate: i128) -> i128 { + volume * rate / DECIMAL_DENOMINATOR +} + +fn setup_settlement(env: &Env) -> Address { + env.register(SettlementContract, ()) +} + +fn make_args( + token_address: Address, + volume: i128, + recipient: Address, + min_expected_amount: Option, +) -> SettlementArgs { + SettlementArgs { + token_address, + volume, + recipient, + min_expected_amount, + } +} + +#[test] +fn test_zero_slippage_succeeds() { + let (env, oracle_id, _admin, payer, payee, fee_collector) = setup_env(); + let settlement_id = setup_settlement(&env); + let settlement_client = SettlementContractClient::new(&env, &settlement_id); + + let rate = 100_000_0000i128; + let volume = 1_000_0000i128; + let expected_amount = settlement_amount(volume, rate); + let token_id = setup_token(&env, &payer, expected_amount); + + let args = make_args(token_id, volume, payee.clone(), None); + + let result = settlement_client.finalize_settlement( + &oracle_id, + &payer, + &fee_collector, + &args, + &100u32, + ); + + assert!(result.net_amount > 0); + assert_eq!(result.rate_used, rate); +} + +#[test] +fn test_slippage_within_tolerance_succeeds() { + let (env, oracle_id, _admin, payer, payee, fee_collector) = setup_env(); + let settlement_id = setup_settlement(&env); + let settlement_client = SettlementContractClient::new(&env, &settlement_id); + + let rate = 100_000_0000i128; + let volume = 1_000_0000i128; + let expected_amount = settlement_amount(volume, rate); + let token_id = setup_token(&env, &payer, expected_amount); + + let min_expected = expected_amount * 99 / 100; + + let args = make_args(token_id, volume, payee.clone(), Some(min_expected)); + + let result = settlement_client.finalize_settlement( + &oracle_id, + &payer, + &fee_collector, + &args, + &100u32, + ); + + assert!(result.net_amount > 0); + assert_eq!(result.rate_used, rate); +} + +#[test] +fn test_slippage_exceeds_tolerance_fails() { + let (env, oracle_id, _admin, payer, payee, fee_collector) = setup_env(); + let settlement_id = setup_settlement(&env); + let settlement_client = SettlementContractClient::new(&env, &settlement_id); + + let rate = 100_000_0000i128; + let volume = 1_000_0000i128; + let expected_amount = settlement_amount(volume, rate); + let token_id = setup_token(&env, &payer, expected_amount); + + let min_expected = expected_amount + 1; + + let args = make_args(token_id, volume, payee.clone(), Some(min_expected)); + + let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + settlement_client.finalize_settlement( + &oracle_id, + &payer, + &fee_collector, + &args, + &100u32, + ); + })); + + assert!(result.is_err()); +} + +#[test] +fn test_user_min_expected_amount_higher_than_actual_fails() { + let (env, oracle_id, _admin, payer, payee, fee_collector) = setup_env(); + let settlement_id = setup_settlement(&env); + let settlement_client = SettlementContractClient::new(&env, &settlement_id); + + let rate = 100_000_0000i128; + let volume = 1_000_0000i128; + let expected_amount = settlement_amount(volume, rate); + let token_id = setup_token(&env, &payer, expected_amount); + + let min_expected = expected_amount * 200; + + let args = make_args(token_id, volume, payee.clone(), Some(min_expected)); + + let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + settlement_client.finalize_settlement( + &oracle_id, + &payer, + &fee_collector, + &args, + &100u32, + ); + })); + + assert!(result.is_err()); +} diff --git a/contracts/settlement/src/types.rs b/contracts/settlement/src/types.rs new file mode 100644 index 0000000..c86cef6 --- /dev/null +++ b/contracts/settlement/src/types.rs @@ -0,0 +1,18 @@ +use soroban_sdk::{contracttype, Address}; + +#[contracttype] +#[derive(Clone, Debug)] +pub struct SettlementArgs { + pub token_address: Address, + pub volume: i128, + pub recipient: Address, + pub min_expected_amount: Option, +} + +#[contracttype] +#[derive(Clone, Debug)] +pub struct SettlementResult { + pub net_amount: i128, + pub fee_amount: i128, + pub rate_used: i128, +} diff --git a/contracts/settlement/test_snapshots/test/test_slippage_exceeds_tolerance_fails.1.json b/contracts/settlement/test_snapshots/test/test_slippage_exceeds_tolerance_fails.1.json new file mode 100644 index 0000000..a76ff3c --- /dev/null +++ b/contracts/settlement/test_snapshots/test/test_slippage_exceeds_tolerance_fails.1.json @@ -0,0 +1,472 @@ +{ + "generators": { + "address": 7, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [], + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V", + { + "function": { + "contract_fn": { + "contract_address": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": "1000000000" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 23, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V", + "balance": "0", + "seq_num": "0", + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "5541220902715666415" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "5541220902715666415" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Price" + } + ] + }, + "val": { + "i128": "1000000000" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "1000000000" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000007" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "SlpSlipp" + } + ], + "data": { + "vec": [ + { + "i128": "1000000000" + }, + { + "i128": "1000000000" + }, + { + "u32": 0 + } + ] + } + } + } + }, + "failed_call": true + } + ] +} \ No newline at end of file diff --git a/contracts/settlement/test_snapshots/test/test_slippage_within_tolerance_succeeds.1.json b/contracts/settlement/test_snapshots/test/test_slippage_within_tolerance_succeeds.1.json new file mode 100644 index 0000000..235f678 --- /dev/null +++ b/contracts/settlement/test_snapshots/test/test_slippage_within_tolerance_succeeds.1.json @@ -0,0 +1,777 @@ +{ + "generators": { + "address": 7, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [], + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V", + { + "function": { + "contract_fn": { + "contract_address": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": "1000000000" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "finalize_settlement", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "map": [ + { + "key": { + "symbol": "min_expected_amount" + }, + "val": { + "i128": "990000000" + } + }, + { + "key": { + "symbol": "recipient" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "token_address" + }, + "val": { + "address": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A" + } + }, + { + "key": { + "symbol": "volume" + }, + "val": { + "i128": "10000000" + } + } + ] + }, + { + "u32": 100 + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": "10000000" + } + ] + } + }, + "sub_invocations": [] + }, + { + "function": { + "contract_fn": { + "contract_address": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": "990000000" + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ] + ], + "ledger": { + "protocol_version": 23, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V", + "balance": "0", + "seq_num": "0", + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "1033654523790656264" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "1033654523790656264" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "5541220902715666415" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "5541220902715666415" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Price" + } + ] + }, + "val": { + "i128": "1000000000" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "0" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "990000000" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000007" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "transfer" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V" + } + ], + "data": { + "i128": "10000000" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "transfer" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V" + } + ], + "data": { + "i128": "990000000" + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/contracts/settlement/test_snapshots/test/test_user_min_expected_amount_higher_than_actual_fails.1.json b/contracts/settlement/test_snapshots/test/test_user_min_expected_amount_higher_than_actual_fails.1.json new file mode 100644 index 0000000..a76ff3c --- /dev/null +++ b/contracts/settlement/test_snapshots/test/test_user_min_expected_amount_higher_than_actual_fails.1.json @@ -0,0 +1,472 @@ +{ + "generators": { + "address": 7, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [], + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V", + { + "function": { + "contract_fn": { + "contract_address": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": "1000000000" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 23, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V", + "balance": "0", + "seq_num": "0", + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "5541220902715666415" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "5541220902715666415" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Price" + } + ] + }, + "val": { + "i128": "1000000000" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "1000000000" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000007" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "SlpSlipp" + } + ], + "data": { + "vec": [ + { + "i128": "1000000000" + }, + { + "i128": "1000000000" + }, + { + "u32": 0 + } + ] + } + } + } + }, + "failed_call": true + } + ] +} \ No newline at end of file diff --git a/contracts/settlement/test_snapshots/test/test_zero_slippage_succeeds.1.json b/contracts/settlement/test_snapshots/test/test_zero_slippage_succeeds.1.json new file mode 100644 index 0000000..fb05d68 --- /dev/null +++ b/contracts/settlement/test_snapshots/test/test_zero_slippage_succeeds.1.json @@ -0,0 +1,775 @@ +{ + "generators": { + "address": 7, + "nonce": 0, + "mux_id": 0 + }, + "auth": [ + [], + [], + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V", + { + "function": { + "contract_fn": { + "contract_address": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": "1000000000" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "function_name": "finalize_settlement", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "map": [ + { + "key": { + "symbol": "min_expected_amount" + }, + "val": "void" + }, + { + "key": { + "symbol": "recipient" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "token_address" + }, + "val": { + "address": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A" + } + }, + { + "key": { + "symbol": "volume" + }, + "val": { + "i128": "10000000" + } + } + ] + }, + { + "u32": 100 + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": "10000000" + } + ] + } + }, + "sub_invocations": [] + }, + { + "function": { + "contract_fn": { + "contract_address": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": "990000000" + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ] + ], + "ledger": { + "protocol_version": 23, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V", + "balance": "0", + "seq_num": "0", + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "1033654523790656264" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "1033654523790656264" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "5541220902715666415" + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "5541220902715666415" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Price" + } + ] + }, + "val": { + "i128": "1000000000" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "0" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "990000000" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "10000000" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000007" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "transfer" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V" + } + ], + "data": { + "i128": "10000000" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "CDS3FDGQ4JA2V3F26Y4BMWWJEC5TT26RJBN7KIQKUMVO2MAOCMDTSZ7A", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "transfer" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP4V" + } + ], + "data": { + "i128": "990000000" + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file