diff --git a/contracts/src/lib.rs b/contracts/src/lib.rs index 0f34397..367831f 100644 --- a/contracts/src/lib.rs +++ b/contracts/src/lib.rs @@ -2,7 +2,7 @@ #![allow(deprecated)] use soroban_sdk::{ - contract, contractimpl, contracttype, symbol_short, token, Address, Env, String, Vec, + contract, contractimpl, contracttype, symbol_short, token, Address, Env, IntoVal, String, Vec, }; mod test; @@ -145,7 +145,7 @@ impl KoloSavingsContract { /// Add a member to the group (Admin only) pub fn add_member(env: Env, new_member: Address) { let admin: Address = env.storage().instance().get(&DataKey::Admin).unwrap(); - admin.require_auth(); + admin.require_auth_for_args((new_member.clone(),).into_val(&env)); extend_instance_ttl(&env); let mut members: Vec
= env.storage().instance().get(&DataKey::Members).unwrap(); @@ -179,7 +179,7 @@ impl KoloSavingsContract { /// Refunds current cycle contribution if applicable. Panics if member already received payout. pub fn remove_member(env: Env, member_to_remove: Address) { let admin: Address = env.storage().instance().get(&DataKey::Admin).unwrap(); - admin.require_auth(); + admin.require_auth_for_args((member_to_remove.clone(),).into_val(&env)); extend_instance_ttl(&env); let mut members: Vec = env.storage().instance().get(&DataKey::Members).unwrap(); @@ -347,7 +347,7 @@ impl KoloSavingsContract { /// Withdraw payout (Admin triggers payout to the next member in queue) /// Enforces strictly deterministic rotational payout (Ajo/Esusu) order. - pub fn payout(env: Env) { + pub fn payout(env: Env, expected_recipient: Address) { let group_type: GroupType = env .storage() .instance() @@ -358,7 +358,7 @@ impl KoloSavingsContract { } let admin: Address = env.storage().instance().get(&DataKey::Admin).unwrap(); - admin.require_auth(); + admin.require_auth_for_args((expected_recipient.clone(),).into_val(&env)); extend_instance_ttl(&env); let members: Vec = env.storage().instance().get(&DataKey::Members).unwrap(); @@ -373,6 +373,9 @@ impl KoloSavingsContract { } let recipient: Address = members.get(next_index).unwrap(); + if recipient != expected_recipient { + panic!("Recipient mismatch"); + } let contribution_amount: i128 = env .storage() @@ -510,7 +513,7 @@ impl KoloSavingsContract { /// all members have received their payout and the admin triggers a new rotation. pub fn reset_cycle(env: Env) { let admin: Address = env.storage().instance().get(&DataKey::Admin).unwrap(); - admin.require_auth(); + admin.require_auth_for_args(().into_val(&env)); extend_instance_ttl(&env); let group_type: GroupType = env @@ -541,7 +544,7 @@ impl KoloSavingsContract { /// Call this after all members have received their payout to begin a new rotation. pub fn reset_rotation(env: Env) { let admin: Address = env.storage().instance().get(&DataKey::Admin).unwrap(); - admin.require_auth(); + admin.require_auth_for_args(().into_val(&env)); extend_instance_ttl(&env); env.storage() diff --git a/contracts/src/test.rs b/contracts/src/test.rs index d22e30b..ca5a294 100644 --- a/contracts/src/test.rs +++ b/contracts/src/test.rs @@ -521,7 +521,7 @@ fn test_remove_member_after_payout_panics() { client.contribute(&member1, &1000); client.contribute(&member2, &1000); - client.payout(); + client.payout(&member1); client.remove_member(&member1); } @@ -584,7 +584,7 @@ fn test_remove_member_adjusts_cycle_count() { client.contribute(&member2, &1000); - client.payout(); + client.payout(&member1); let contract_balance = token_client.balance(&contract_id); assert_eq!(contract_balance, 0); @@ -681,7 +681,7 @@ fn test_deterministic_payout_order() { client.contribute(&member1, &1000); client.contribute(&member2, &1000); assert_eq!(client.get_next_payout_recipient(), member0); - client.payout(); + client.payout(&member0); assert!(client.has_received_payout(&member0)); assert!(!client.has_received_payout(&member1)); assert!(!client.has_received_payout(&member2)); @@ -698,7 +698,7 @@ fn test_deterministic_payout_order() { client.contribute(&member1, &1000); client.contribute(&member2, &1000); assert_eq!(client.get_next_payout_recipient(), member1); - client.payout(); + client.payout(&member1); assert!(client.has_received_payout(&member1)); assert!(!client.has_received_payout(&member2)); // 10000 - 1000 (round1) - 1000 (round2) + 3000 (payout) = 11000 @@ -710,7 +710,7 @@ fn test_deterministic_payout_order() { client.contribute(&member1, &1000); client.contribute(&member2, &1000); assert_eq!(client.get_next_payout_recipient(), member2); - client.payout(); + client.payout(&member2); assert!(client.has_received_payout(&member2)); // 10000 - 1000*3 (3 rounds) + 3000 (payout) = 10000 assert_eq!(token_client.balance(&member2), 10000); @@ -756,7 +756,7 @@ fn test_queue_enforced_payout_order() { client.contribute(&member2, &1000); assert_eq!(client.get_next_payout_recipient(), member0); - client.payout(); + client.payout(&member0); assert!(client.has_received_payout(&member0)); assert!(!client.has_received_payout(&member2)); @@ -767,7 +767,7 @@ fn test_queue_enforced_payout_order() { client.contribute(&member2, &1000); assert_eq!(client.get_next_payout_recipient(), member1); - client.payout(); + client.payout(&member1); assert!(client.has_received_payout(&member1)); assert!(!client.has_received_payout(&member2)); @@ -778,7 +778,7 @@ fn test_queue_enforced_payout_order() { client.contribute(&member2, &1000); assert_eq!(client.get_next_payout_recipient(), member2); - client.payout(); + client.payout(&member2); assert!(client.has_received_payout(&member2)); } @@ -822,7 +822,7 @@ fn test_cycle_resets_and_starts_again() { client.contribute(&member1, &1000); client.contribute(&member2, &1000); assert_eq!(client.get_next_payout_recipient(), member0); - client.payout(); + client.payout(&member0); assert!(client.has_received_payout(&member0)); // Round 2: payout to member1 @@ -831,7 +831,7 @@ fn test_cycle_resets_and_starts_again() { client.contribute(&member1, &1000); client.contribute(&member2, &1000); assert_eq!(client.get_next_payout_recipient(), member1); - client.payout(); + client.payout(&member1); assert!(client.has_received_payout(&member1)); // Round 3: payout to member2 @@ -840,7 +840,7 @@ fn test_cycle_resets_and_starts_again() { client.contribute(&member1, &1000); client.contribute(&member2, &1000); assert_eq!(client.get_next_payout_recipient(), member2); - client.payout(); + client.payout(&member2); assert!(client.has_received_payout(&member2)); // --- Full reset: reset_rotation() resets NextPayoutIndex to 0 --- @@ -857,6 +857,55 @@ fn test_cycle_resets_and_starts_again() { client.contribute(&member1, &1000); client.contribute(&member2, &1000); assert_eq!(client.get_next_payout_recipient(), member0); - client.payout(); + client.payout(&member0); assert!(client.has_received_payout(&member0)); } + +#[test] +#[should_panic(expected = "Error(Auth, InvalidAction)")] +fn test_payout_wrong_recipient_auth_fails() { + let env = Env::default(); + + let contract_id = env.register_contract(None, KoloSavingsContract); + let client = KoloSavingsContractClient::new(&env, &contract_id); + + let admin = Address::generate(&env); + let token_admin = Address::generate(&env); + let token = env.register_stellar_asset_contract(token_admin.clone()); + let token_client = token::StellarAssetClient::new(&env, &token); + + // Initialize with mock all auths to easily bypass initialization auth + env.mock_all_auths(); + client.initialize( + &admin, + &token, + &String::from_str(&env, "Test Group"), + &1000i128, + &GroupType::Rotational, + &None, + &false, + &None, + ); + + let member0 = Address::generate(&env); + let member1 = Address::generate(&env); + client.add_member(&member0); + client.add_member(&member1); + + token_client.mint(&member0, &10000); + client.contribute(&member0, &1000); + + // We only explicitly mock the auth for payout with the WRONG recipient (member1) + env.mock_auths(&[soroban_sdk::testutils::MockAuth { + address: &admin, + invoke: &soroban_sdk::testutils::MockAuthInvoke { + contract: &contract_id, + fn_name: "payout", + args: (member1.clone(),).into_val(&env), + sub_invokes: &[], + }, + }]); + + // Calling it with member0 should fail because auth is for member1 + client.payout(&member0); +} diff --git a/contracts/test_snapshots/test/test_cycle_resets_and_starts_again.1.json b/contracts/test_snapshots/test/test_cycle_resets_and_starts_again.1.json index 0a88de7..04606e2 100644 --- a/contracts/test_snapshots/test/test_cycle_resets_and_starts_again.1.json +++ b/contracts/test_snapshots/test/test_cycle_resets_and_starts_again.1.json @@ -327,7 +327,11 @@ "contract_fn": { "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", "function_name": "payout", - "args": [] + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] } }, "sub_invocations": [] @@ -488,7 +492,11 @@ "contract_fn": { "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", "function_name": "payout", - "args": [] + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] } }, "sub_invocations": [] @@ -649,7 +657,11 @@ "contract_fn": { "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", "function_name": "payout", - "args": [] + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + ] } }, "sub_invocations": [] @@ -828,7 +840,11 @@ "contract_fn": { "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", "function_name": "payout", - "args": [] + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] } }, "sub_invocations": [] diff --git a/contracts/test_snapshots/test/test_deterministic_payout_order.1.json b/contracts/test_snapshots/test/test_deterministic_payout_order.1.json index ef60072..ed40c4a 100644 --- a/contracts/test_snapshots/test/test_deterministic_payout_order.1.json +++ b/contracts/test_snapshots/test/test_deterministic_payout_order.1.json @@ -327,7 +327,11 @@ "contract_fn": { "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", "function_name": "payout", - "args": [] + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] } }, "sub_invocations": [] @@ -492,7 +496,11 @@ "contract_fn": { "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", "function_name": "payout", - "args": [] + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] } }, "sub_invocations": [] @@ -655,7 +663,11 @@ "contract_fn": { "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", "function_name": "payout", - "args": [] + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + ] } }, "sub_invocations": [] diff --git a/contracts/test_snapshots/test/test_payout_wrong_recipient_auth_fails.1.json b/contracts/test_snapshots/test/test_payout_wrong_recipient_auth_fails.1.json new file mode 100644 index 0000000..5788168 --- /dev/null +++ b/contracts/test_snapshots/test/test_payout_wrong_recipient_auth_fails.1.json @@ -0,0 +1,844 @@ +{ + "generators": { + "address": 6, + "nonce": 1, + "mux_id": 0 + }, + "auth": [ + [], + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF", + { + "function": { + "contract_fn": { + "contract_address": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "initialize", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "address": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN" + }, + { + "string": "Test Group" + }, + { + "i128": "1000" + }, + { + "vec": [ + { + "symbol": "Rotational" + } + ] + }, + "void", + { + "bool": false + }, + "void" + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "add_member", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "add_member", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "i128": "10000" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "contribute", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "i128": "1000" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + }, + { + "i128": "1000" + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 27, + "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": [ + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF", + "balance": "0", + "seq_num": "0", + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + "live_until": null + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF", + "key": { + "ledger_key_nonce": { + "nonce": "801925984706572462" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Member" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "has_received_payout" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "last_contribution_cycle_id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "total_contributions" + }, + "val": { + "i128": "1000" + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 1036800 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Member" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "has_received_payout" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "last_contribution_cycle_id" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "total_contributions" + }, + "val": { + "i128": "0" + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "ContributionAmount" + } + ] + }, + "val": { + "i128": "1000" + } + }, + { + "key": { + "vec": [ + { + "symbol": "CurrentCycleId" + } + ] + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "vec": [ + { + "symbol": "CycleLengthLedgers" + } + ] + }, + "val": { + "u32": 518400 + } + }, + { + "key": { + "vec": [ + { + "symbol": "CycleMemberCount" + } + ] + }, + "val": { + "i128": "2" + } + }, + { + "key": { + "vec": [ + { + "symbol": "GroupType" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "Rotational" + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "LockUntilTarget" + } + ] + }, + "val": { + "bool": false + } + }, + { + "key": { + "vec": [ + { + "symbol": "Members" + } + ] + }, + "val": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Name" + } + ] + }, + "val": { + "string": "Test Group" + } + }, + { + "key": { + "vec": [ + { + "symbol": "NextPayoutIndex" + } + ] + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Token" + } + ] + }, + "val": { + "address": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 1036800 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + "live_until": 4095 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "1033654523790656264" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "4837995959683129791" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": "5541220902715666415" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": "2032731177588607455" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": "4270020994084947596" + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + "live_until": 6311999 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "1000" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": "9000" + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + "live_until": 518400 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "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:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000004" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + "live_until": 120960 + }, + { + "entry": { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + "live_until": 1036800 + } + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/test_snapshots/test/test_queue_enforced_payout_order.1.json b/contracts/test_snapshots/test/test_queue_enforced_payout_order.1.json index fcadf2e..4a4491b 100644 --- a/contracts/test_snapshots/test/test_queue_enforced_payout_order.1.json +++ b/contracts/test_snapshots/test/test_queue_enforced_payout_order.1.json @@ -327,7 +327,11 @@ "contract_fn": { "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", "function_name": "payout", - "args": [] + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] } }, "sub_invocations": [] @@ -489,7 +493,11 @@ "contract_fn": { "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", "function_name": "payout", - "args": [] + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] } }, "sub_invocations": [] @@ -651,7 +659,11 @@ "contract_fn": { "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", "function_name": "payout", - "args": [] + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + ] } }, "sub_invocations": [] diff --git a/contracts/test_snapshots/test/test_remove_member_adjusts_cycle_count.1.json b/contracts/test_snapshots/test/test_remove_member_adjusts_cycle_count.1.json index 621e944..33eea61 100644 --- a/contracts/test_snapshots/test/test_remove_member_adjusts_cycle_count.1.json +++ b/contracts/test_snapshots/test/test_remove_member_adjusts_cycle_count.1.json @@ -304,7 +304,11 @@ "contract_fn": { "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", "function_name": "payout", - "args": [] + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] } }, "sub_invocations": [] diff --git a/contracts/test_snapshots/test/test_remove_member_after_payout_panics.1.json b/contracts/test_snapshots/test/test_remove_member_after_payout_panics.1.json index 6733d3f..dbb8fb1 100644 --- a/contracts/test_snapshots/test/test_remove_member_after_payout_panics.1.json +++ b/contracts/test_snapshots/test/test_remove_member_after_payout_panics.1.json @@ -242,7 +242,11 @@ "contract_fn": { "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", "function_name": "payout", - "args": [] + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] } }, "sub_invocations": []