From 8b777d03ef4130cb33f8337066895213626226c7 Mon Sep 17 00:00:00 2001 From: ZeePearl56 Date: Wed, 26 Aug 2026 14:36:03 +0100 Subject: [PATCH] feat(admin): implement approve_upgrade voting for WASM upgrade proposals Adds approve_upgrade, letting an admin-pool member cast a weighted vote on a Pending UpgradeProposal. The proposal transitions to Approved as soon as the tally reaches its snapshotted quorum, mirroring the existing approve_proposal / timelock-snapshot pattern already in this module. Voting is rejected once the proposal is no longer Pending (including past its voting-window expiry), and a voter cannot cast a second vote on the same proposal. Resolves #654. --- contracts/admin/src/lib.rs | 308 ++++++++++++ ...eaches_quorum_and_flips_to_approved.1.json | 458 ++++++++++++++++++ ...e_upgrade_records_vote_below_quorum.1.json | 395 +++++++++++++++ ...e_rejects_already_approved_proposal.1.json | 325 +++++++++++++ ...rove_upgrade_rejects_duplicate_vote.1.json | 395 +++++++++++++++ ...ove_upgrade_rejects_non_pool_member.1.json | 325 +++++++++++++ ...pgrade_rejects_nonexistent_proposal.1.json | 222 +++++++++ ...e_upgrade_rejects_vote_after_expiry.1.json | 325 +++++++++++++ 8 files changed, 2753 insertions(+) create mode 100644 contracts/admin/test_snapshots/tests/test_approve_upgrade_reaches_quorum_and_flips_to_approved.1.json create mode 100644 contracts/admin/test_snapshots/tests/test_approve_upgrade_records_vote_below_quorum.1.json create mode 100644 contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_already_approved_proposal.1.json create mode 100644 contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_duplicate_vote.1.json create mode 100644 contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_non_pool_member.1.json create mode 100644 contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_nonexistent_proposal.1.json create mode 100644 contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_vote_after_expiry.1.json diff --git a/contracts/admin/src/lib.rs b/contracts/admin/src/lib.rs index 7064536b..e703cf87 100644 --- a/contracts/admin/src/lib.rs +++ b/contracts/admin/src/lib.rs @@ -195,6 +195,13 @@ pub enum AdminError { /// The mandatory timelock delay has not elapsed yet: the current ledger /// timestamp is still before the proposal's recorded unlock time. TimelockActive = 10, + /// A WASM upgrade proposal with the supplied ID does not exist. + UpgradeProposalNotFound = 12, + /// The proposal is not in a state that accepts votes (it is `Approved`, + /// `Executed`, `Cancelled`, `Expired`, or its voting window has closed). + ProposalNotPending = 13, + /// The caller already cast a vote on this upgrade proposal. + DuplicateVote = 14, } /// Storage keys for the access-control layer. @@ -1275,6 +1282,79 @@ pub fn execute_upgrade( Ok(()) } +/// Casts `voter`'s approval on a pending [`UpgradeProposal`]. Resolves issue +/// #654. +/// +/// Once the weighted tally of unique votes reaches the proposal's snapshotted +/// [`UpgradeProposal::quorum`], the proposal transitions from `Pending` to +/// `Approved` in the same call — mirroring the existing [`approve_proposal`] +/// / [`_start_timelock_if_quorate`] pattern, so quorum is always detected at +/// the exact vote that completes it rather than lazily on a later read. +/// +/// # Authorization & Guarantees +/// +/// - `voter` must authorize the call and be a member of the admin pool +/// ([`get_admin_pool`]). +/// - The proposal must exist and currently be [`ProposalStatus::Pending`]; +/// voting on an `Approved`, `Executed`, `Cancelled` or `Expired` proposal +/// is rejected, as is voting after `expires_at` has passed. +/// - Each voter may cast at most one vote per proposal (checked-effects: the +/// duplicate check reads `votes` before it is written). +/// +/// # Errors +/// +/// Returns [`AdminError::UnauthorizedRole`] if `voter` is not an admin-pool +/// member, [`AdminError::UpgradeProposalNotFound`] if no proposal exists +/// under `proposal_id`, [`AdminError::ProposalNotPending`] if the proposal is +/// not currently pending votes, or [`AdminError::DuplicateVote`] if `voter` +/// already voted on this proposal. +/// +/// @notice Records `voter`'s approval of upgrade proposal `proposal_id`, advancing it to `Approved` once quorum is reached. +/// @dev Requires pool membership and authorization. Each voter carries weight `1` and may vote at most once per proposal. +/// @param env The Soroban environment. +/// @param voter The admin-pool member casting the vote. +/// @param proposal_id The ID of the upgrade proposal to vote on. +/// @return `Ok(())` on success, or one of the [`AdminError`] variants listed above. +pub fn approve_upgrade(env: &Env, voter: Address, proposal_id: u64) -> Result<(), AdminError> { + voter.require_auth(); + + let pool = get_admin_pool(env); + if !pool.contains(&voter) { + return Err(AdminError::UnauthorizedRole); + } + + let key = AdminKey::UpgradeProposal(proposal_id); + let mut proposal: UpgradeProposal = env + .storage() + .persistent() + .get(&key) + .ok_or(AdminError::UpgradeProposalNotFound)?; + + if proposal.status != ProposalStatus::Pending || env.ledger().timestamp() >= proposal.expires_at + { + return Err(AdminError::ProposalNotPending); + } + if proposal.votes.contains_key(voter.clone()) { + return Err(AdminError::DuplicateVote); + } + + proposal.votes.set(voter, 1); + + let tally: u64 = proposal + .votes + .values() + .into_iter() + .map(|weight| weight as u64) + .sum(); + if tally >= proposal.quorum { + proposal.status = ProposalStatus::Approved; + } + + env.storage().persistent().set(&key, &proposal); + extend_storage_ttl_for_key(env, &key); + Ok(()) +} + #[cfg(test)] mod tests { use super::*; @@ -1368,6 +1448,14 @@ mod tests { super::get_proposal_unlock_time(&env, proposal_id) } + pub fn approve_upgrade( + env: Env, + voter: Address, + proposal_id: u64, + ) -> Result<(), AdminError> { + super::approve_upgrade(&env, voter, proposal_id) + } + pub fn require_super_admin(env: Env, address: Address) { super::require_super_admin(&env, &address); } @@ -3669,4 +3757,224 @@ mod tests { ScVal::try_from_val(&env, &expected_counter).unwrap() ); } + + // ── approve_upgrade (#654) ────────────────────────────────────────────── + + fn seed_upgrade_proposal( + env: &Env, + contract_id: &Address, + proposal_id: u64, + proposal: &UpgradeProposal, + ) { + env.as_contract(contract_id, || { + env.storage() + .persistent() + .set(&AdminKey::UpgradeProposal(proposal_id), proposal); + }); + } + + fn read_upgrade_proposal( + env: &Env, + contract_id: &Address, + proposal_id: u64, + ) -> UpgradeProposal { + env.as_contract(contract_id, || { + env.storage() + .persistent() + .get(&AdminKey::UpgradeProposal(proposal_id)) + .unwrap() + }) + } + + #[test] + fn test_approve_upgrade_records_vote_below_quorum() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(AdminContract, ()); + let client = AdminContractClient::new(&env, &contract_id); + let admin = Address::generate(&env); + let voter1 = Address::generate(&env); + let voter2 = Address::generate(&env); + let target = Address::generate(&env); + + client.set_admin(&admin); + client.set_admin_pool(&vec![&env, voter1.clone(), voter2.clone()], &2); + + let proposal = UpgradeProposal { + proposer: voter1.clone(), + targets: vec![&env, target], + votes: Map::new(&env), + quorum: 2, + status: ProposalStatus::Pending, + expires_at: env.ledger().timestamp() + 1_000, + }; + seed_upgrade_proposal(&env, &contract_id, 1, &proposal); + + client.approve_upgrade(&voter1, &1); + + let stored = read_upgrade_proposal(&env, &contract_id, 1); + assert_eq!(stored.status, ProposalStatus::Pending); + assert_eq!(stored.votes.len(), 1); + assert_eq!(stored.votes.get(voter1).unwrap(), 1); + } + + #[test] + fn test_approve_upgrade_reaches_quorum_and_flips_to_approved() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(AdminContract, ()); + let client = AdminContractClient::new(&env, &contract_id); + let admin = Address::generate(&env); + let voter1 = Address::generate(&env); + let voter2 = Address::generate(&env); + let target = Address::generate(&env); + + client.set_admin(&admin); + client.set_admin_pool(&vec![&env, voter1.clone(), voter2.clone()], &2); + + let proposal = UpgradeProposal { + proposer: voter1.clone(), + targets: vec![&env, target], + votes: Map::new(&env), + quorum: 2, + status: ProposalStatus::Pending, + expires_at: env.ledger().timestamp() + 1_000, + }; + seed_upgrade_proposal(&env, &contract_id, 1, &proposal); + + client.approve_upgrade(&voter1, &1); + client.approve_upgrade(&voter2, &1); + + let stored = read_upgrade_proposal(&env, &contract_id, 1); + assert_eq!(stored.status, ProposalStatus::Approved); + } + + #[test] + fn test_approve_upgrade_rejects_non_pool_member() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(AdminContract, ()); + let client = AdminContractClient::new(&env, &contract_id); + let admin = Address::generate(&env); + let voter1 = Address::generate(&env); + let stranger = Address::generate(&env); + let target = Address::generate(&env); + + client.set_admin(&admin); + client.set_admin_pool(&vec![&env, voter1.clone()], &1); + + let proposal = UpgradeProposal { + proposer: voter1.clone(), + targets: vec![&env, target], + votes: Map::new(&env), + quorum: 1, + status: ProposalStatus::Pending, + expires_at: env.ledger().timestamp() + 1_000, + }; + seed_upgrade_proposal(&env, &contract_id, 1, &proposal); + + let result = client.try_approve_upgrade(&stranger, &1); + assert_eq!(result, Err(Ok(AdminError::UnauthorizedRole))); + } + + #[test] + fn test_approve_upgrade_rejects_duplicate_vote() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(AdminContract, ()); + let client = AdminContractClient::new(&env, &contract_id); + let admin = Address::generate(&env); + let voter1 = Address::generate(&env); + let voter2 = Address::generate(&env); + let target = Address::generate(&env); + + client.set_admin(&admin); + client.set_admin_pool(&vec![&env, voter1.clone(), voter2.clone()], &2); + + let proposal = UpgradeProposal { + proposer: voter1.clone(), + targets: vec![&env, target], + votes: Map::new(&env), + quorum: 2, + status: ProposalStatus::Pending, + expires_at: env.ledger().timestamp() + 1_000, + }; + seed_upgrade_proposal(&env, &contract_id, 1, &proposal); + + client.approve_upgrade(&voter1, &1); + let result = client.try_approve_upgrade(&voter1, &1); + assert_eq!(result, Err(Ok(AdminError::DuplicateVote))); + } + + #[test] + fn test_approve_upgrade_rejects_nonexistent_proposal() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(AdminContract, ()); + let client = AdminContractClient::new(&env, &contract_id); + let admin = Address::generate(&env); + let voter1 = Address::generate(&env); + + client.set_admin(&admin); + client.set_admin_pool(&vec![&env, voter1.clone()], &1); + + let result = client.try_approve_upgrade(&voter1, &99); + assert_eq!(result, Err(Ok(AdminError::UpgradeProposalNotFound))); + } + + #[test] + fn test_approve_upgrade_rejects_already_approved_proposal() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(AdminContract, ()); + let client = AdminContractClient::new(&env, &contract_id); + let admin = Address::generate(&env); + let voter1 = Address::generate(&env); + let target = Address::generate(&env); + + client.set_admin(&admin); + client.set_admin_pool(&vec![&env, voter1.clone()], &1); + + let proposal = UpgradeProposal { + proposer: voter1.clone(), + targets: vec![&env, target], + votes: Map::new(&env), + quorum: 1, + status: ProposalStatus::Approved, + expires_at: env.ledger().timestamp() + 1_000, + }; + seed_upgrade_proposal(&env, &contract_id, 1, &proposal); + + let result = client.try_approve_upgrade(&voter1, &1); + assert_eq!(result, Err(Ok(AdminError::ProposalNotPending))); + } + + #[test] + fn test_approve_upgrade_rejects_vote_after_expiry() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(AdminContract, ()); + let client = AdminContractClient::new(&env, &contract_id); + let admin = Address::generate(&env); + let voter1 = Address::generate(&env); + let target = Address::generate(&env); + + client.set_admin(&admin); + client.set_admin_pool(&vec![&env, voter1.clone()], &1); + + let proposal = UpgradeProposal { + proposer: voter1.clone(), + targets: vec![&env, target], + votes: Map::new(&env), + quorum: 1, + status: ProposalStatus::Pending, + expires_at: env.ledger().timestamp(), + }; + seed_upgrade_proposal(&env, &contract_id, 1, &proposal); + + env.ledger().with_mut(|li| li.timestamp += 1); + + let result = client.try_approve_upgrade(&voter1, &1); + assert_eq!(result, Err(Ok(AdminError::ProposalNotPending))); + } } diff --git a/contracts/admin/test_snapshots/tests/test_approve_upgrade_reaches_quorum_and_flips_to_approved.1.json b/contracts/admin/test_snapshots/tests/test_approve_upgrade_reaches_quorum_and_flips_to_approved.1.json new file mode 100644 index 00000000..0815b43a --- /dev/null +++ b/contracts/admin/test_snapshots/tests/test_approve_upgrade_reaches_quorum_and_flips_to_approved.1.json @@ -0,0 +1,458 @@ +{ + "generators": { + "address": 5, + "nonce": 0 + }, + "auth": [ + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "set_admin_pool", + "args": [ + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + { + "u32": 2 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "approve_upgrade", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "u64": 1 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "approve_upgrade", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "u64": 1 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "RoleMask" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "RoleMask" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "u32": 1 + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "UpgradeProposal" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "UpgradeProposal" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "expires_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "proposer" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "quorum" + }, + "val": { + "u64": 2 + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "vec": [ + { + "symbol": "Approved" + } + ] + } + }, + { + "key": { + "symbol": "targets" + }, + "val": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + }, + { + "key": { + "symbol": "votes" + }, + "val": { + "map": [ + { + "key": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + "val": { + "u32": 1 + } + } + ] + } + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "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": "AdminPool" + } + ] + }, + "val": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Threshold" + } + ] + }, + "val": { + "u32": 2 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/admin/test_snapshots/tests/test_approve_upgrade_records_vote_below_quorum.1.json b/contracts/admin/test_snapshots/tests/test_approve_upgrade_records_vote_below_quorum.1.json new file mode 100644 index 00000000..48824bda --- /dev/null +++ b/contracts/admin/test_snapshots/tests/test_approve_upgrade_records_vote_below_quorum.1.json @@ -0,0 +1,395 @@ +{ + "generators": { + "address": 5, + "nonce": 0 + }, + "auth": [ + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "set_admin_pool", + "args": [ + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + { + "u32": 2 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "approve_upgrade", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "u64": 1 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "RoleMask" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "RoleMask" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "u32": 1 + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "UpgradeProposal" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "UpgradeProposal" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "expires_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "proposer" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "quorum" + }, + "val": { + "u64": 2 + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "vec": [ + { + "symbol": "Pending" + } + ] + } + }, + { + "key": { + "symbol": "targets" + }, + "val": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + }, + { + "key": { + "symbol": "votes" + }, + "val": { + "map": [ + { + "key": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + "val": { + "u32": 1 + } + } + ] + } + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "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": "AdminPool" + } + ] + }, + "val": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Threshold" + } + ] + }, + "val": { + "u32": 2 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_already_approved_proposal.1.json b/contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_already_approved_proposal.1.json new file mode 100644 index 00000000..8bf212d7 --- /dev/null +++ b/contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_already_approved_proposal.1.json @@ -0,0 +1,325 @@ +{ + "generators": { + "address": 4, + "nonce": 0 + }, + "auth": [ + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "set_admin_pool", + "args": [ + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + { + "u32": 1 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "RoleMask" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "RoleMask" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "u32": 1 + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "UpgradeProposal" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "UpgradeProposal" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "expires_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "proposer" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "quorum" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "vec": [ + { + "symbol": "Approved" + } + ] + } + }, + { + "key": { + "symbol": "targets" + }, + "val": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + }, + { + "key": { + "symbol": "votes" + }, + "val": { + "map": [] + } + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "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": "AdminPool" + } + ] + }, + "val": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Threshold" + } + ] + }, + "val": { + "u32": 1 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_duplicate_vote.1.json b/contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_duplicate_vote.1.json new file mode 100644 index 00000000..48824bda --- /dev/null +++ b/contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_duplicate_vote.1.json @@ -0,0 +1,395 @@ +{ + "generators": { + "address": 5, + "nonce": 0 + }, + "auth": [ + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "set_admin_pool", + "args": [ + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + { + "u32": 2 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "approve_upgrade", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "u64": 1 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "RoleMask" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "RoleMask" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "u32": 1 + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "UpgradeProposal" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "UpgradeProposal" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "expires_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "proposer" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "quorum" + }, + "val": { + "u64": 2 + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "vec": [ + { + "symbol": "Pending" + } + ] + } + }, + { + "key": { + "symbol": "targets" + }, + "val": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + }, + { + "key": { + "symbol": "votes" + }, + "val": { + "map": [ + { + "key": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + "val": { + "u32": 1 + } + } + ] + } + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "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": "AdminPool" + } + ] + }, + "val": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Threshold" + } + ] + }, + "val": { + "u32": 2 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_non_pool_member.1.json b/contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_non_pool_member.1.json new file mode 100644 index 00000000..e9d9e768 --- /dev/null +++ b/contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_non_pool_member.1.json @@ -0,0 +1,325 @@ +{ + "generators": { + "address": 5, + "nonce": 0 + }, + "auth": [ + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "set_admin_pool", + "args": [ + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + { + "u32": 1 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "RoleMask" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "RoleMask" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "u32": 1 + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "UpgradeProposal" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "UpgradeProposal" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "expires_at" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "proposer" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "quorum" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "vec": [ + { + "symbol": "Pending" + } + ] + } + }, + { + "key": { + "symbol": "targets" + }, + "val": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + }, + { + "key": { + "symbol": "votes" + }, + "val": { + "map": [] + } + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "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": "AdminPool" + } + ] + }, + "val": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Threshold" + } + ] + }, + "val": { + "u32": 1 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_nonexistent_proposal.1.json b/contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_nonexistent_proposal.1.json new file mode 100644 index 00000000..23613751 --- /dev/null +++ b/contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_nonexistent_proposal.1.json @@ -0,0 +1,222 @@ +{ + "generators": { + "address": 3, + "nonce": 0 + }, + "auth": [ + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "set_admin_pool", + "args": [ + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + { + "u32": 1 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 22, + "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": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "RoleMask" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "RoleMask" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "u32": 1 + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "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": "AdminPool" + } + ] + }, + "val": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Threshold" + } + ] + }, + "val": { + "u32": 1 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_vote_after_expiry.1.json b/contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_vote_after_expiry.1.json new file mode 100644 index 00000000..20f45e2a --- /dev/null +++ b/contracts/admin/test_snapshots/tests/test_approve_upgrade_rejects_vote_after_expiry.1.json @@ -0,0 +1,325 @@ +{ + "generators": { + "address": 4, + "nonce": 0 + }, + "auth": [ + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "set_admin_pool", + "args": [ + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + { + "u32": 1 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 1, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "RoleMask" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "RoleMask" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "u32": 1 + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "UpgradeProposal" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "UpgradeProposal" + }, + { + "u64": 1 + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "expires_at" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "proposer" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "quorum" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "vec": [ + { + "symbol": "Pending" + } + ] + } + }, + { + "key": { + "symbol": "targets" + }, + "val": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + }, + { + "key": { + "symbol": "votes" + }, + "val": { + "map": [] + } + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "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": "AdminPool" + } + ] + }, + "val": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Threshold" + } + ] + }, + "val": { + "u32": 1 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file