diff --git a/.github/workflows/aptos-framework-test.yaml b/.github/workflows/aptos-framework-test.yaml index e1a2535ecfa17..e903df2105810 100644 --- a/.github/workflows/aptos-framework-test.yaml +++ b/.github/workflows/aptos-framework-test.yaml @@ -3,12 +3,10 @@ name: Run aptos framework checks on: push: branches: - - master - - integrate_consensus_key + - dev pull_request: branches: - - master - - integrate_consensus_key + - dev env: CARGO_TERM_COLOR: always diff --git a/aptos-move/e2e-move-tests/src/supra_governance.rs b/aptos-move/e2e-move-tests/src/supra_governance.rs index 66fc91ac78487..485a39da0c391 100644 --- a/aptos-move/e2e-move-tests/src/supra_governance.rs +++ b/aptos-move/e2e-move-tests/src/supra_governance.rs @@ -5,11 +5,10 @@ use crate::harness::MoveHarness; use aptos_cached_packages::aptos_stdlib; use aptos_language_e2e_tests::account::Account; use aptos_types::{ - account_address::AccountAddress, move_utils::MemberId, state_store::table::TableHandle, + account_address::AccountAddress, state_store::table::TableHandle, transaction::TransactionStatus, }; use serde::{Deserialize, Serialize}; -use std::str::FromStr; #[derive(Deserialize, Serialize)] struct PartialVotingProposals { @@ -27,10 +26,9 @@ struct VotingRecordsV2 { pub votes: TableHandle, } -pub fn create_proposal_v2( +pub fn supra_create_proposal_v2( harness: &mut MoveHarness, account: &Account, - stake_pool: AccountAddress, execution_hash: Vec, metadata_location: Vec, metadata_hash: Vec, @@ -38,8 +36,7 @@ pub fn create_proposal_v2( ) -> TransactionStatus { harness.run_transaction_payload( account, - aptos_stdlib::supra_governance_create_proposal_v2( - stake_pool, + aptos_stdlib::supra_governance_supra_create_proposal_v2( execution_hash, metadata_location, metadata_hash, @@ -48,37 +45,17 @@ pub fn create_proposal_v2( ) } -pub fn partial_vote( +pub fn supra_vote( harness: &mut MoveHarness, account: &Account, - stake_pool: AccountAddress, proposal_id: u64, - voting_power: u64, should_pass: bool, ) -> TransactionStatus { harness.run_transaction_payload( account, - aptos_stdlib::supra_governance_partial_vote( - stake_pool, + aptos_stdlib::supra_governance_supra_vote( proposal_id, - voting_power, should_pass, ), ) } - -pub fn get_remaining_voting_power( - harness: &mut MoveHarness, - stake_pool: AccountAddress, - proposal_id: u64, -) -> u64 { - let fun = MemberId::from_str("0x1::supra_governance::get_remaining_voting_power").unwrap(); - let res = harness - .execute_view_function(fun, vec![], vec![ - bcs::to_bytes(&stake_pool).unwrap(), - bcs::to_bytes(&proposal_id).unwrap(), - ]) - .values - .unwrap(); - bcs::from_bytes::(&res[0]).unwrap() -} diff --git a/aptos-move/e2e-move-tests/src/tests/vote.data/enable_partial_governance_voting/sources/main.move b/aptos-move/e2e-move-tests/src/tests/vote.data/enable_partial_governance_voting/sources/main.move index da2f5dcaf5e6b..cd45120d82d2a 100644 --- a/aptos-move/e2e-move-tests/src/tests/vote.data/enable_partial_governance_voting/sources/main.move +++ b/aptos-move/e2e-move-tests/src/tests/vote.data/enable_partial_governance_voting/sources/main.move @@ -4,7 +4,6 @@ script { fun main(core_resources: &signer) { let framework_signer = supra_governance::get_signer_testnet_only(core_resources, @supra_framework); - supra_governance::initialize_partial_voting(&framework_signer); let feature = features::get_partial_governance_voting(); features::change_feature_flags_for_next_epoch(&framework_signer, vector[feature], vector[]); supra_governance::force_end_epoch(&framework_signer); diff --git a/aptos-move/e2e-move-tests/src/tests/vote.rs b/aptos-move/e2e-move-tests/src/tests/vote.rs index db50e38f71cc3..4f1adc35be5c8 100644 --- a/aptos-move/e2e-move-tests/src/tests/vote.rs +++ b/aptos-move/e2e-move-tests/src/tests/vote.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - supra_governance::*, assert_abort, assert_success, increase_lockup, setup_staking, + supra_governance::*, assert_abort, assert_success, tests::common, MoveHarness, }; use aptos_types::account_address::AccountAddress; @@ -18,47 +18,30 @@ fn build_scripts() -> BTreeMap> { } #[test] -fn test_vote() { +fn test_supra_vote() { // Genesis starts with one validator with index 0 let mut harness = MoveHarness::new(); - let validator_1 = harness.new_account_at(AccountAddress::from_hex_literal("0x123").unwrap()); - let validator_2 = harness.new_account_at(AccountAddress::from_hex_literal("0x234").unwrap()); - let validator_1_address = *validator_1.address(); - let validator_2_address = *validator_2.address(); - - let stake_amount_1 = 25_000_000; - assert_success!(setup_staking(&mut harness, &validator_1, stake_amount_1)); - assert_success!(increase_lockup(&mut harness, &validator_1)); - let stake_amount_2 = 25_000_000; - assert_success!(setup_staking(&mut harness, &validator_2, stake_amount_2)); - assert_success!(increase_lockup(&mut harness, &validator_2)); + let proposer = harness.new_account_at(AccountAddress::from_hex_literal("0xdd2").unwrap()); + let voter = harness.new_account_at(AccountAddress::from_hex_literal("0xdd1").unwrap()); let mut proposal_id: u64 = 0; - assert_success!(create_proposal_v2( + assert_success!(supra_create_proposal_v2( &mut harness, - &validator_2, - validator_2_address, + &proposer, vec![1], vec![], vec![], true )); - // Voters can vote on a partial voting proposal but argument voting_power will be ignored. - assert_success!(partial_vote( + // Voters can vote on a voting proposal. + assert_success!(supra_vote( &mut harness, - &validator_1, - validator_1_address, + &voter, proposal_id, - 100, true )); - // No remaining voting power. - assert_eq!( - get_remaining_voting_power(&mut harness, validator_1_address, proposal_id), - 0 - ); - // Enable partial governance voting. In production it requires governance. + // Enable partial governance voting. In production, it requires governance. let core_resources = harness.new_account_at(AccountAddress::from_hex_literal("0xA550C18").unwrap()); let script_code = PROPOSAL_SCRIPTS @@ -69,21 +52,18 @@ fn test_vote() { // If a voter has already voted on a proposal before partial voting is enabled, the voter cannot vote on the proposal again. assert_abort!( - partial_vote( + supra_vote( &mut harness, - &validator_1, - validator_1_address, + &voter, proposal_id, - 100, true ), - 0x10005 + 0x8000D ); - assert_success!(create_proposal_v2( + assert_success!(supra_create_proposal_v2( &mut harness, - &validator_1, - validator_1_address, + &voter, vec![1], vec![], vec![], @@ -93,63 +73,27 @@ fn test_vote() { // Cannot vote on a non-exist proposal. let wrong_proposal_id: u64 = 2; assert_abort!( - partial_vote( + supra_vote( &mut harness, - &validator_1, - validator_1_address, + &voter, wrong_proposal_id, - 100, true ), 25863 ); proposal_id = 1; - assert_eq!( - get_remaining_voting_power(&mut harness, validator_1_address, proposal_id), - stake_amount_1 - ); - assert_eq!( - get_remaining_voting_power(&mut harness, validator_2_address, proposal_id), - stake_amount_1 - ); - // A voter can vote on a proposal multiple times with both Yes/No. - assert_success!(partial_vote( + assert_success!(supra_vote( &mut harness, - &validator_1, - validator_1_address, + &voter, proposal_id, - 100, true )); - assert_eq!( - get_remaining_voting_power(&mut harness, validator_1_address, proposal_id), - stake_amount_1 - 100 - ); - assert_success!(partial_vote( + assert_success!(supra_vote( &mut harness, - &validator_1, - validator_1_address, + &voter, proposal_id, - 1000, false )); - assert_eq!( - get_remaining_voting_power(&mut harness, validator_1_address, proposal_id), - stake_amount_1 - 1100 - ); - // A voter cannot use voting power more than it has. - assert_success!(partial_vote( - &mut harness, - &validator_1, - validator_1_address, - proposal_id, - stake_amount_1, - true - )); - assert_eq!( - get_remaining_voting_power(&mut harness, validator_1_address, proposal_id), - 0 - ); } diff --git a/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs b/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs index 95e14d7809b0a..06ecafca49e60 100644 --- a/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs +++ b/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs @@ -270,17 +270,6 @@ pub enum EntryFunctionCall { delegator_address: AccountAddress, }, - /// A voter could create a governance proposal by this function. To successfully create a proposal, the voter's - /// voting power in THIS delegation pool must be not less than the minimum required voting power specified in - /// `supra_governance.move`. - DelegationPoolCreateProposal { - pool_address: AccountAddress, - execution_hash: Vec, - metadata_location: Vec, - metadata_hash: Vec, - is_multi_step_proposal: bool, - }, - /// Allows a delegator to delegate its voting power to a voter. If this delegator already has a delegated voter, /// this change won't take effects until the next lockup period. DelegationPoolDelegateVotingPower { @@ -361,18 +350,6 @@ pub enum EntryFunctionCall { new_commission_percentage: u64, }, - /// Vote on a proposal with a voter's voting power. To successfully vote, the following conditions must be met: - /// 1. The voting period of the proposal hasn't ended. - /// 2. The delegation pool's lockup period ends after the voting period of the proposal. - /// 3. The voter still has spare voting power on this proposal. - /// 4. The delegation pool never votes on the proposal before enabling partial governance voting. - DelegationPoolVote { - pool_address: AccountAddress, - proposal_id: u64, - voting_power: u64, - should_pass: bool, - }, - /// Withdraw `amount` of owned inactive stake from the delegation pool at `pool_address`. DelegationPoolWithdraw { pool_address: AccountAddress, @@ -639,17 +616,6 @@ pub enum EntryFunctionCall { code: Vec>, }, - /// A voter could create a governance proposal by this function. To successfully create a proposal, the voter's - /// voting power in THIS delegation pool must be not less than the minimum required voting power specified in - /// `supra_governance.move`. - PboDelegationPoolCreateProposal { - pool_address: AccountAddress, - execution_hash: Vec, - metadata_location: Vec, - metadata_hash: Vec, - is_multi_step_proposal: bool, - }, - /// Allows a delegator to delegate its voting power to a voter. If this delegator already has a delegated voter, /// this change won't take effects until the next lockup period. PboDelegationPoolDelegateVotingPower { @@ -715,18 +681,6 @@ pub enum EntryFunctionCall { new_commission_percentage: u64, }, - /// Vote on a proposal with a voter's voting power. To successfully vote, the following conditions must be met: - /// 1. The voting period of the proposal hasn't ended. - /// 2. The delegation pool's lockup period ends after the voting period of the proposal. - /// 3. The voter still has spare voting power on this proposal. - /// 4. The delegation pool never votes on the proposal before enabling partial governance voting. - PboDelegationPoolVote { - pool_address: AccountAddress, - proposal_id: u64, - voting_power: u64, - should_pass: bool, - }, - /// Withdraw `amount` of owned inactive stake from the delegation pool at `pool_address`. PboDelegationPoolWithdraw { pool_address: AccountAddress, @@ -1012,50 +966,10 @@ pub enum EntryFunctionCall { amount: u64, }, - SupraGovernanceAddApprovedScriptHashScript { - proposal_id: u64, - }, - SupraGovernanceAddSupraApprovedScriptHashScript { proposal_id: u64, }, - /// Batch vote on proposal with proposal_id and specified voting power from multiple stake_pools. - SupraGovernanceBatchPartialVote { - stake_pools: Vec, - proposal_id: u64, - voting_power: u64, - should_pass: bool, - }, - - /// Vote on proposal with proposal_id and all voting power from multiple stake_pools. - SupraGovernanceBatchVote { - stake_pools: Vec, - proposal_id: u64, - should_pass: bool, - }, - - /// Create a single-step proposal with the backing `stake_pool`. - /// @param execution_hash Required. This is the hash of the resolution script. When the proposal is resolved, - /// only the exact script with matching hash can be successfully executed. - SupraGovernanceCreateProposal { - stake_pool: AccountAddress, - execution_hash: Vec, - metadata_location: Vec, - metadata_hash: Vec, - }, - - /// Create a single-step or multi-step proposal with the backing `stake_pool`. - /// @param execution_hash Required. This is the hash of the resolution script. When the proposal is resolved, - /// only the exact script with matching hash can be successfully executed. - SupraGovernanceCreateProposalV2 { - stake_pool: AccountAddress, - execution_hash: Vec, - metadata_location: Vec, - metadata_hash: Vec, - is_multi_step_proposal: bool, - }, - /// Change epoch immediately. /// If `RECONFIGURE_WITH_DKG` is enabled and we are in the middle of a DKG, /// stop waiting for DKG and enter the new epoch without randomness. @@ -1068,14 +982,6 @@ pub enum EntryFunctionCall { /// where the core resources account exists and has been granted power to mint Aptos coins. SupraGovernanceForceEndEpochTestOnly {}, - /// Vote on proposal with `proposal_id` and specified voting power from `stake_pool`. - SupraGovernancePartialVote { - stake_pool: AccountAddress, - proposal_id: u64, - voting_power: u64, - should_pass: bool, - }, - /// Manually reconfigure. Called at the end of a governance txn that alters on-chain configs. /// /// WARNING: this function always ensures a reconfiguration starts, but when the reconfiguration finishes depends. @@ -1112,13 +1018,6 @@ pub enum EntryFunctionCall { should_pass: bool, }, - /// Vote on proposal with `proposal_id` and all voting power from `stake_pool`. - SupraGovernanceVote { - stake_pool: AccountAddress, - proposal_id: u64, - should_pass: bool, - }, - TransactionFeeConvertToAptosFaBurnRef {}, /// Used in on-chain governances to update the major version for the next epoch. @@ -1475,19 +1374,6 @@ impl EntryFunctionCall { DelegationPoolAllowlistDelegator { delegator_address } => { delegation_pool_allowlist_delegator(delegator_address) }, - DelegationPoolCreateProposal { - pool_address, - execution_hash, - metadata_location, - metadata_hash, - is_multi_step_proposal, - } => delegation_pool_create_proposal( - pool_address, - execution_hash, - metadata_location, - metadata_hash, - is_multi_step_proposal, - ), DelegationPoolDelegateVotingPower { pool_address, new_voter, @@ -1537,12 +1423,6 @@ impl EntryFunctionCall { DelegationPoolUpdateCommissionPercentage { new_commission_percentage, } => delegation_pool_update_commission_percentage(new_commission_percentage), - DelegationPoolVote { - pool_address, - proposal_id, - voting_power, - should_pass, - } => delegation_pool_vote(pool_address, proposal_id, voting_power, should_pass), DelegationPoolWithdraw { pool_address, amount, @@ -1733,19 +1613,6 @@ impl EntryFunctionCall { metadata_serialized, code, } => object_code_deployment_publish(metadata_serialized, code), - PboDelegationPoolCreateProposal { - pool_address, - execution_hash, - metadata_location, - metadata_hash, - is_multi_step_proposal, - } => pbo_delegation_pool_create_proposal( - pool_address, - execution_hash, - metadata_location, - metadata_hash, - is_multi_step_proposal, - ), PboDelegationPoolDelegateVotingPower { pool_address, new_voter, @@ -1781,12 +1648,6 @@ impl EntryFunctionCall { PboDelegationPoolUpdateCommissionPercentage { new_commission_percentage, } => pbo_delegation_pool_update_commission_percentage(new_commission_percentage), - PboDelegationPoolVote { - pool_address, - proposal_id, - voting_power, - should_pass, - } => pbo_delegation_pool_vote(pool_address, proposal_id, voting_power, should_pass), PboDelegationPoolWithdraw { pool_address, amount, @@ -1950,60 +1811,11 @@ impl EntryFunctionCall { SupraCoinClaimMintCapability {} => supra_coin_claim_mint_capability(), SupraCoinDelegateMintCapability { to } => supra_coin_delegate_mint_capability(to), SupraCoinMint { dst_addr, amount } => supra_coin_mint(dst_addr, amount), - SupraGovernanceAddApprovedScriptHashScript { proposal_id } => { - supra_governance_add_approved_script_hash_script(proposal_id) - }, SupraGovernanceAddSupraApprovedScriptHashScript { proposal_id } => { supra_governance_add_supra_approved_script_hash_script(proposal_id) }, - SupraGovernanceBatchPartialVote { - stake_pools, - proposal_id, - voting_power, - should_pass, - } => supra_governance_batch_partial_vote( - stake_pools, - proposal_id, - voting_power, - should_pass, - ), - SupraGovernanceBatchVote { - stake_pools, - proposal_id, - should_pass, - } => supra_governance_batch_vote(stake_pools, proposal_id, should_pass), - SupraGovernanceCreateProposal { - stake_pool, - execution_hash, - metadata_location, - metadata_hash, - } => supra_governance_create_proposal( - stake_pool, - execution_hash, - metadata_location, - metadata_hash, - ), - SupraGovernanceCreateProposalV2 { - stake_pool, - execution_hash, - metadata_location, - metadata_hash, - is_multi_step_proposal, - } => supra_governance_create_proposal_v2( - stake_pool, - execution_hash, - metadata_location, - metadata_hash, - is_multi_step_proposal, - ), SupraGovernanceForceEndEpoch {} => supra_governance_force_end_epoch(), SupraGovernanceForceEndEpochTestOnly {} => supra_governance_force_end_epoch_test_only(), - SupraGovernancePartialVote { - stake_pool, - proposal_id, - voting_power, - should_pass, - } => supra_governance_partial_vote(stake_pool, proposal_id, voting_power, should_pass), SupraGovernanceReconfigure {} => supra_governance_reconfigure(), SupraGovernanceSupraCreateProposal { execution_hash, @@ -2029,11 +1841,6 @@ impl EntryFunctionCall { proposal_id, should_pass, } => supra_governance_supra_vote(proposal_id, should_pass), - SupraGovernanceVote { - stake_pool, - proposal_id, - should_pass, - } => supra_governance_vote(stake_pool, proposal_id, should_pass), TransactionFeeConvertToAptosFaBurnRef {} => { transaction_fee_convert_to_aptos_fa_burn_ref() }, @@ -2781,36 +2588,6 @@ pub fn delegation_pool_allowlist_delegator( )) } -/// A voter could create a governance proposal by this function. To successfully create a proposal, the voter's -/// voting power in THIS delegation pool must be not less than the minimum required voting power specified in -/// `supra_governance.move`. -pub fn delegation_pool_create_proposal( - pool_address: AccountAddress, - execution_hash: Vec, - metadata_location: Vec, - metadata_hash: Vec, - is_multi_step_proposal: bool, -) -> TransactionPayload { - TransactionPayload::EntryFunction(EntryFunction::new( - ModuleId::new( - AccountAddress::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ]), - ident_str!("delegation_pool").to_owned(), - ), - ident_str!("create_proposal").to_owned(), - vec![], - vec![ - bcs::to_bytes(&pool_address).unwrap(), - bcs::to_bytes(&execution_hash).unwrap(), - bcs::to_bytes(&metadata_location).unwrap(), - bcs::to_bytes(&metadata_hash).unwrap(), - bcs::to_bytes(&is_multi_step_proposal).unwrap(), - ], - )) -} - /// Allows a delegator to delegate its voting power to a voter. If this delegator already has a delegated voter, /// this change won't take effects until the next lockup period. pub fn delegation_pool_delegate_voting_power( @@ -3076,36 +2853,6 @@ pub fn delegation_pool_update_commission_percentage( )) } -/// Vote on a proposal with a voter's voting power. To successfully vote, the following conditions must be met: -/// 1. The voting period of the proposal hasn't ended. -/// 2. The delegation pool's lockup period ends after the voting period of the proposal. -/// 3. The voter still has spare voting power on this proposal. -/// 4. The delegation pool never votes on the proposal before enabling partial governance voting. -pub fn delegation_pool_vote( - pool_address: AccountAddress, - proposal_id: u64, - voting_power: u64, - should_pass: bool, -) -> TransactionPayload { - TransactionPayload::EntryFunction(EntryFunction::new( - ModuleId::new( - AccountAddress::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ]), - ident_str!("delegation_pool").to_owned(), - ), - ident_str!("vote").to_owned(), - vec![], - vec![ - bcs::to_bytes(&pool_address).unwrap(), - bcs::to_bytes(&proposal_id).unwrap(), - bcs::to_bytes(&voting_power).unwrap(), - bcs::to_bytes(&should_pass).unwrap(), - ], - )) -} - /// Withdraw `amount` of owned inactive stake from the delegation pool at `pool_address`. pub fn delegation_pool_withdraw(pool_address: AccountAddress, amount: u64) -> TransactionPayload { TransactionPayload::EntryFunction(EntryFunction::new( @@ -3862,36 +3609,6 @@ pub fn object_code_deployment_publish( )) } -/// A voter could create a governance proposal by this function. To successfully create a proposal, the voter's -/// voting power in THIS delegation pool must be not less than the minimum required voting power specified in -/// `supra_governance.move`. -pub fn pbo_delegation_pool_create_proposal( - pool_address: AccountAddress, - execution_hash: Vec, - metadata_location: Vec, - metadata_hash: Vec, - is_multi_step_proposal: bool, -) -> TransactionPayload { - TransactionPayload::EntryFunction(EntryFunction::new( - ModuleId::new( - AccountAddress::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ]), - ident_str!("pbo_delegation_pool").to_owned(), - ), - ident_str!("create_proposal").to_owned(), - vec![], - vec![ - bcs::to_bytes(&pool_address).unwrap(), - bcs::to_bytes(&execution_hash).unwrap(), - bcs::to_bytes(&metadata_location).unwrap(), - bcs::to_bytes(&metadata_hash).unwrap(), - bcs::to_bytes(&is_multi_step_proposal).unwrap(), - ], - )) -} - /// Allows a delegator to delegate its voting power to a voter. If this delegator already has a delegated voter, /// this change won't take effects until the next lockup period. pub fn pbo_delegation_pool_delegate_voting_power( @@ -4093,36 +3810,6 @@ pub fn pbo_delegation_pool_update_commission_percentage( )) } -/// Vote on a proposal with a voter's voting power. To successfully vote, the following conditions must be met: -/// 1. The voting period of the proposal hasn't ended. -/// 2. The delegation pool's lockup period ends after the voting period of the proposal. -/// 3. The voter still has spare voting power on this proposal. -/// 4. The delegation pool never votes on the proposal before enabling partial governance voting. -pub fn pbo_delegation_pool_vote( - pool_address: AccountAddress, - proposal_id: u64, - voting_power: u64, - should_pass: bool, -) -> TransactionPayload { - TransactionPayload::EntryFunction(EntryFunction::new( - ModuleId::new( - AccountAddress::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ]), - ident_str!("pbo_delegation_pool").to_owned(), - ), - ident_str!("vote").to_owned(), - vec![], - vec![ - bcs::to_bytes(&pool_address).unwrap(), - bcs::to_bytes(&proposal_id).unwrap(), - bcs::to_bytes(&voting_power).unwrap(), - bcs::to_bytes(&should_pass).unwrap(), - ], - )) -} - /// Withdraw `amount` of owned inactive stake from the delegation pool at `pool_address`. pub fn pbo_delegation_pool_withdraw( pool_address: AccountAddress, @@ -5051,21 +4738,6 @@ pub fn supra_coin_mint(dst_addr: AccountAddress, amount: u64) -> TransactionPayl )) } -pub fn supra_governance_add_approved_script_hash_script(proposal_id: u64) -> TransactionPayload { - TransactionPayload::EntryFunction(EntryFunction::new( - ModuleId::new( - AccountAddress::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ]), - ident_str!("supra_governance").to_owned(), - ), - ident_str!("add_approved_script_hash_script").to_owned(), - vec![], - vec![bcs::to_bytes(&proposal_id).unwrap()], - )) -} - pub fn supra_governance_add_supra_approved_script_hash_script( proposal_id: u64, ) -> TransactionPayload { @@ -5083,114 +4755,6 @@ pub fn supra_governance_add_supra_approved_script_hash_script( )) } -/// Batch vote on proposal with proposal_id and specified voting power from multiple stake_pools. -pub fn supra_governance_batch_partial_vote( - stake_pools: Vec, - proposal_id: u64, - voting_power: u64, - should_pass: bool, -) -> TransactionPayload { - TransactionPayload::EntryFunction(EntryFunction::new( - ModuleId::new( - AccountAddress::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ]), - ident_str!("supra_governance").to_owned(), - ), - ident_str!("batch_partial_vote").to_owned(), - vec![], - vec![ - bcs::to_bytes(&stake_pools).unwrap(), - bcs::to_bytes(&proposal_id).unwrap(), - bcs::to_bytes(&voting_power).unwrap(), - bcs::to_bytes(&should_pass).unwrap(), - ], - )) -} - -/// Vote on proposal with proposal_id and all voting power from multiple stake_pools. -pub fn supra_governance_batch_vote( - stake_pools: Vec, - proposal_id: u64, - should_pass: bool, -) -> TransactionPayload { - TransactionPayload::EntryFunction(EntryFunction::new( - ModuleId::new( - AccountAddress::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ]), - ident_str!("supra_governance").to_owned(), - ), - ident_str!("batch_vote").to_owned(), - vec![], - vec![ - bcs::to_bytes(&stake_pools).unwrap(), - bcs::to_bytes(&proposal_id).unwrap(), - bcs::to_bytes(&should_pass).unwrap(), - ], - )) -} - -/// Create a single-step proposal with the backing `stake_pool`. -/// @param execution_hash Required. This is the hash of the resolution script. When the proposal is resolved, -/// only the exact script with matching hash can be successfully executed. -pub fn supra_governance_create_proposal( - stake_pool: AccountAddress, - execution_hash: Vec, - metadata_location: Vec, - metadata_hash: Vec, -) -> TransactionPayload { - TransactionPayload::EntryFunction(EntryFunction::new( - ModuleId::new( - AccountAddress::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ]), - ident_str!("supra_governance").to_owned(), - ), - ident_str!("create_proposal").to_owned(), - vec![], - vec![ - bcs::to_bytes(&stake_pool).unwrap(), - bcs::to_bytes(&execution_hash).unwrap(), - bcs::to_bytes(&metadata_location).unwrap(), - bcs::to_bytes(&metadata_hash).unwrap(), - ], - )) -} - -/// Create a single-step or multi-step proposal with the backing `stake_pool`. -/// @param execution_hash Required. This is the hash of the resolution script. When the proposal is resolved, -/// only the exact script with matching hash can be successfully executed. -pub fn supra_governance_create_proposal_v2( - stake_pool: AccountAddress, - execution_hash: Vec, - metadata_location: Vec, - metadata_hash: Vec, - is_multi_step_proposal: bool, -) -> TransactionPayload { - TransactionPayload::EntryFunction(EntryFunction::new( - ModuleId::new( - AccountAddress::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ]), - ident_str!("supra_governance").to_owned(), - ), - ident_str!("create_proposal_v2").to_owned(), - vec![], - vec![ - bcs::to_bytes(&stake_pool).unwrap(), - bcs::to_bytes(&execution_hash).unwrap(), - bcs::to_bytes(&metadata_location).unwrap(), - bcs::to_bytes(&metadata_hash).unwrap(), - bcs::to_bytes(&is_multi_step_proposal).unwrap(), - ], - )) -} - /// Change epoch immediately. /// If `RECONFIGURE_WITH_DKG` is enabled and we are in the middle of a DKG, /// stop waiting for DKG and enter the new epoch without randomness. @@ -5229,32 +4793,6 @@ pub fn supra_governance_force_end_epoch_test_only() -> TransactionPayload { )) } -/// Vote on proposal with `proposal_id` and specified voting power from `stake_pool`. -pub fn supra_governance_partial_vote( - stake_pool: AccountAddress, - proposal_id: u64, - voting_power: u64, - should_pass: bool, -) -> TransactionPayload { - TransactionPayload::EntryFunction(EntryFunction::new( - ModuleId::new( - AccountAddress::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ]), - ident_str!("supra_governance").to_owned(), - ), - ident_str!("partial_vote").to_owned(), - vec![], - vec![ - bcs::to_bytes(&stake_pool).unwrap(), - bcs::to_bytes(&proposal_id).unwrap(), - bcs::to_bytes(&voting_power).unwrap(), - bcs::to_bytes(&should_pass).unwrap(), - ], - )) -} - /// Manually reconfigure. Called at the end of a governance txn that alters on-chain configs. /// /// WARNING: this function always ensures a reconfiguration starts, but when the reconfiguration finishes depends. @@ -5352,30 +4890,6 @@ pub fn supra_governance_supra_vote(proposal_id: u64, should_pass: bool) -> Trans )) } -/// Vote on proposal with `proposal_id` and all voting power from `stake_pool`. -pub fn supra_governance_vote( - stake_pool: AccountAddress, - proposal_id: u64, - should_pass: bool, -) -> TransactionPayload { - TransactionPayload::EntryFunction(EntryFunction::new( - ModuleId::new( - AccountAddress::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ]), - ident_str!("supra_governance").to_owned(), - ), - ident_str!("vote").to_owned(), - vec![], - vec![ - bcs::to_bytes(&stake_pool).unwrap(), - bcs::to_bytes(&proposal_id).unwrap(), - bcs::to_bytes(&should_pass).unwrap(), - ], - )) -} - pub fn transaction_fee_convert_to_aptos_fa_burn_ref() -> TransactionPayload { TransactionPayload::EntryFunction(EntryFunction::new( ModuleId::new( @@ -6298,22 +5812,6 @@ mod decoder { } } - pub fn delegation_pool_create_proposal( - payload: &TransactionPayload, - ) -> Option { - if let TransactionPayload::EntryFunction(script) = payload { - Some(EntryFunctionCall::DelegationPoolCreateProposal { - pool_address: bcs::from_bytes(script.args().get(0)?).ok()?, - execution_hash: bcs::from_bytes(script.args().get(1)?).ok()?, - metadata_location: bcs::from_bytes(script.args().get(2)?).ok()?, - metadata_hash: bcs::from_bytes(script.args().get(3)?).ok()?, - is_multi_step_proposal: bcs::from_bytes(script.args().get(4)?).ok()?, - }) - } else { - None - } - } - pub fn delegation_pool_delegate_voting_power( payload: &TransactionPayload, ) -> Option { @@ -6484,19 +5982,6 @@ mod decoder { } } - pub fn delegation_pool_vote(payload: &TransactionPayload) -> Option { - if let TransactionPayload::EntryFunction(script) = payload { - Some(EntryFunctionCall::DelegationPoolVote { - pool_address: bcs::from_bytes(script.args().get(0)?).ok()?, - proposal_id: bcs::from_bytes(script.args().get(1)?).ok()?, - voting_power: bcs::from_bytes(script.args().get(2)?).ok()?, - should_pass: bcs::from_bytes(script.args().get(3)?).ok()?, - }) - } else { - None - } - } - pub fn delegation_pool_withdraw(payload: &TransactionPayload) -> Option { if let TransactionPayload::EntryFunction(script) = payload { Some(EntryFunctionCall::DelegationPoolWithdraw { @@ -6932,22 +6417,6 @@ mod decoder { } } - pub fn pbo_delegation_pool_create_proposal( - payload: &TransactionPayload, - ) -> Option { - if let TransactionPayload::EntryFunction(script) = payload { - Some(EntryFunctionCall::PboDelegationPoolCreateProposal { - pool_address: bcs::from_bytes(script.args().get(0)?).ok()?, - execution_hash: bcs::from_bytes(script.args().get(1)?).ok()?, - metadata_location: bcs::from_bytes(script.args().get(2)?).ok()?, - metadata_hash: bcs::from_bytes(script.args().get(3)?).ok()?, - is_multi_step_proposal: bcs::from_bytes(script.args().get(4)?).ok()?, - }) - } else { - None - } - } - pub fn pbo_delegation_pool_delegate_voting_power( payload: &TransactionPayload, ) -> Option { @@ -7079,19 +6548,6 @@ mod decoder { } } - pub fn pbo_delegation_pool_vote(payload: &TransactionPayload) -> Option { - if let TransactionPayload::EntryFunction(script) = payload { - Some(EntryFunctionCall::PboDelegationPoolVote { - pool_address: bcs::from_bytes(script.args().get(0)?).ok()?, - proposal_id: bcs::from_bytes(script.args().get(1)?).ok()?, - voting_power: bcs::from_bytes(script.args().get(2)?).ok()?, - should_pass: bcs::from_bytes(script.args().get(3)?).ok()?, - }) - } else { - None - } - } - pub fn pbo_delegation_pool_withdraw(payload: &TransactionPayload) -> Option { if let TransactionPayload::EntryFunction(script) = payload { Some(EntryFunctionCall::PboDelegationPoolWithdraw { @@ -7643,20 +7099,6 @@ mod decoder { } } - pub fn supra_governance_add_approved_script_hash_script( - payload: &TransactionPayload, - ) -> Option { - if let TransactionPayload::EntryFunction(script) = payload { - Some( - EntryFunctionCall::SupraGovernanceAddApprovedScriptHashScript { - proposal_id: bcs::from_bytes(script.args().get(0)?).ok()?, - }, - ) - } else { - None - } - } - pub fn supra_governance_add_supra_approved_script_hash_script( payload: &TransactionPayload, ) -> Option { @@ -7671,64 +7113,6 @@ mod decoder { } } - pub fn supra_governance_batch_partial_vote( - payload: &TransactionPayload, - ) -> Option { - if let TransactionPayload::EntryFunction(script) = payload { - Some(EntryFunctionCall::SupraGovernanceBatchPartialVote { - stake_pools: bcs::from_bytes(script.args().get(0)?).ok()?, - proposal_id: bcs::from_bytes(script.args().get(1)?).ok()?, - voting_power: bcs::from_bytes(script.args().get(2)?).ok()?, - should_pass: bcs::from_bytes(script.args().get(3)?).ok()?, - }) - } else { - None - } - } - - pub fn supra_governance_batch_vote(payload: &TransactionPayload) -> Option { - if let TransactionPayload::EntryFunction(script) = payload { - Some(EntryFunctionCall::SupraGovernanceBatchVote { - stake_pools: bcs::from_bytes(script.args().get(0)?).ok()?, - proposal_id: bcs::from_bytes(script.args().get(1)?).ok()?, - should_pass: bcs::from_bytes(script.args().get(2)?).ok()?, - }) - } else { - None - } - } - - pub fn supra_governance_create_proposal( - payload: &TransactionPayload, - ) -> Option { - if let TransactionPayload::EntryFunction(script) = payload { - Some(EntryFunctionCall::SupraGovernanceCreateProposal { - stake_pool: bcs::from_bytes(script.args().get(0)?).ok()?, - execution_hash: bcs::from_bytes(script.args().get(1)?).ok()?, - metadata_location: bcs::from_bytes(script.args().get(2)?).ok()?, - metadata_hash: bcs::from_bytes(script.args().get(3)?).ok()?, - }) - } else { - None - } - } - - pub fn supra_governance_create_proposal_v2( - payload: &TransactionPayload, - ) -> Option { - if let TransactionPayload::EntryFunction(script) = payload { - Some(EntryFunctionCall::SupraGovernanceCreateProposalV2 { - stake_pool: bcs::from_bytes(script.args().get(0)?).ok()?, - execution_hash: bcs::from_bytes(script.args().get(1)?).ok()?, - metadata_location: bcs::from_bytes(script.args().get(2)?).ok()?, - metadata_hash: bcs::from_bytes(script.args().get(3)?).ok()?, - is_multi_step_proposal: bcs::from_bytes(script.args().get(4)?).ok()?, - }) - } else { - None - } - } - pub fn supra_governance_force_end_epoch( payload: &TransactionPayload, ) -> Option { @@ -7749,21 +7133,6 @@ mod decoder { } } - pub fn supra_governance_partial_vote( - payload: &TransactionPayload, - ) -> Option { - if let TransactionPayload::EntryFunction(script) = payload { - Some(EntryFunctionCall::SupraGovernancePartialVote { - stake_pool: bcs::from_bytes(script.args().get(0)?).ok()?, - proposal_id: bcs::from_bytes(script.args().get(1)?).ok()?, - voting_power: bcs::from_bytes(script.args().get(2)?).ok()?, - should_pass: bcs::from_bytes(script.args().get(3)?).ok()?, - }) - } else { - None - } - } - pub fn supra_governance_reconfigure(payload: &TransactionPayload) -> Option { if let TransactionPayload::EntryFunction(_script) = payload { Some(EntryFunctionCall::SupraGovernanceReconfigure {}) @@ -7812,18 +7181,6 @@ mod decoder { } } - pub fn supra_governance_vote(payload: &TransactionPayload) -> Option { - if let TransactionPayload::EntryFunction(script) = payload { - Some(EntryFunctionCall::SupraGovernanceVote { - stake_pool: bcs::from_bytes(script.args().get(0)?).ok()?, - proposal_id: bcs::from_bytes(script.args().get(1)?).ok()?, - should_pass: bcs::from_bytes(script.args().get(2)?).ok()?, - }) - } else { - None - } - } - pub fn transaction_fee_convert_to_aptos_fa_burn_ref( payload: &TransactionPayload, ) -> Option { @@ -8286,10 +7643,6 @@ static SCRIPT_FUNCTION_DECODER_MAP: once_cell::sync::Lazyuse 0x1::staking_config; use 0x1::supra_account; use 0x1::supra_coin; -use 0x1::supra_governance; use 0x1::table; use 0x1::table_with_length; use 0x1::timestamp; @@ -1678,26 +1673,6 @@ Delegation pool owner capability does not exist at the provided account. - - -The voter does not have sufficient stake to create a proposal. - - -
const EINSUFFICIENT_PROPOSER_STAKE: u64 = 15;
-
- - - - - -The voter does not have any voting power on this proposal. - - -
const ENO_VOTING_POWER: u64 = 16;
-
- - - The stake pool has already voted on the proposal before enabling partial governance voting on this delegation pool. @@ -1808,6 +1783,16 @@ Delegator's pending_inactive balance cannot be less than + +The voter does not have sufficient stake to create a proposal. + + +
const EINSUFFICIENT_PROPOSER_STAKE: u64 = 15;
+
+ + + Commission percentage has to be between 0 and MAX_FEE - 100%. @@ -1828,6 +1813,16 @@ There is not enough active stake on the stake pool to unlock< + + +The voter does not have any voting power on this proposal. + + +
const ENO_VOTING_POWER: u64 = 16;
+
+ + + Changing beneficiaries for operators is not supported. @@ -2496,46 +2491,6 @@ latest state. - - - - -## Function `calculate_and_update_remaining_voting_power` - -Return the remaining voting power of a delegator in a delegation pool on a proposal. This function syncs DelegationPool to the -latest state. - - -
#[view]
-public fun calculate_and_update_remaining_voting_power(pool_address: address, voter_address: address, proposal_id: u64): u64
-
- - - -
-Implementation - - -
public fun calculate_and_update_remaining_voting_power(
-    pool_address: address,
-    voter_address: address,
-    proposal_id: u64
-): u64 acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage {
-    assert_partial_governance_voting_enabled(pool_address);
-    // If the whole stake pool has no voting power(e.g. it has already voted before partial
-    // governance voting flag is enabled), the delegator also has no voting power.
-    if (supra_governance::get_remaining_voting_power(pool_address, proposal_id) == 0) {
-        return 0
-    };
-
-    let total_voting_power = calculate_and_update_voter_total_voting_power(pool_address, voter_address);
-    let governance_records = borrow_global<GovernanceRecords>(pool_address);
-    total_voting_power - get_used_voting_power(governance_records, voter_address, proposal_id)
-}
-
- - -
@@ -2913,161 +2868,6 @@ The existing voter will be replaced. The function is permissionless. - - - - -## Function `vote` - -Vote on a proposal with a voter's voting power. To successfully vote, the following conditions must be met: -1. The voting period of the proposal hasn't ended. -2. The delegation pool's lockup period ends after the voting period of the proposal. -3. The voter still has spare voting power on this proposal. -4. The delegation pool never votes on the proposal before enabling partial governance voting. - - -
public entry fun vote(voter: &signer, pool_address: address, proposal_id: u64, voting_power: u64, should_pass: bool)
-
- - - -
-Implementation - - -
public entry fun vote(
-    voter: &signer,
-    pool_address: address,
-    proposal_id: u64,
-    voting_power: u64,
-    should_pass: bool
-) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage {
-    assert_partial_governance_voting_enabled(pool_address);
-    // synchronize delegation and stake pools before any user operation.
-    synchronize_delegation_pool(pool_address);
-
-    let voter_address = signer::address_of(voter);
-    let remaining_voting_power = calculate_and_update_remaining_voting_power(
-        pool_address,
-        voter_address,
-        proposal_id
-    );
-    if (voting_power > remaining_voting_power) {
-        voting_power = remaining_voting_power;
-    };
-    assert!(voting_power > 0, error::invalid_argument(ENO_VOTING_POWER));
-
-    let governance_records = borrow_global_mut<GovernanceRecords>(pool_address);
-    // Check a edge case during the transient period of enabling partial governance voting.
-    assert_and_update_proposal_used_voting_power(governance_records, pool_address, proposal_id, voting_power);
-    let used_voting_power = borrow_mut_used_voting_power(governance_records, voter_address, proposal_id);
-    *used_voting_power = *used_voting_power + voting_power;
-
-    let pool_signer = retrieve_stake_pool_owner(borrow_global<DelegationPool>(pool_address));
-    supra_governance::partial_vote(&pool_signer, pool_address, proposal_id, voting_power, should_pass);
-
-    if (features::module_event_migration_enabled()) {
-        event::emit(
-            Vote {
-                voter: voter_address,
-                proposal_id,
-                delegation_pool: pool_address,
-                num_votes: voting_power,
-                should_pass,
-            }
-        );
-    };
-
-    event::emit_event(
-        &mut governance_records.vote_events,
-        VoteEvent {
-            voter: voter_address,
-            proposal_id,
-            delegation_pool: pool_address,
-            num_votes: voting_power,
-            should_pass,
-        }
-    );
-}
-
- - - -
- - - -## Function `create_proposal` - -A voter could create a governance proposal by this function. To successfully create a proposal, the voter's -voting power in THIS delegation pool must be not less than the minimum required voting power specified in -supra_governance.move. - - -
public entry fun create_proposal(voter: &signer, pool_address: address, execution_hash: vector<u8>, metadata_location: vector<u8>, metadata_hash: vector<u8>, is_multi_step_proposal: bool)
-
- - - -
-Implementation - - -
public entry fun create_proposal(
-    voter: &signer,
-    pool_address: address,
-    execution_hash: vector<u8>,
-    metadata_location: vector<u8>,
-    metadata_hash: vector<u8>,
-    is_multi_step_proposal: bool,
-) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage {
-    assert_partial_governance_voting_enabled(pool_address);
-
-    // synchronize delegation and stake pools before any user operation
-    synchronize_delegation_pool(pool_address);
-
-    let voter_addr = signer::address_of(voter);
-    let pool = borrow_global<DelegationPool>(pool_address);
-    let governance_records = borrow_global_mut<GovernanceRecords>(pool_address);
-    let total_voting_power = calculate_and_update_delegated_votes(pool, governance_records, voter_addr);
-    assert!(
-        total_voting_power >= supra_governance::get_required_proposer_stake(),
-        error::invalid_argument(EINSUFFICIENT_PROPOSER_STAKE));
-    let pool_signer = retrieve_stake_pool_owner(borrow_global<DelegationPool>(pool_address));
-    let proposal_id = supra_governance::create_proposal_v2_impl(
-        &pool_signer,
-        pool_address,
-        execution_hash,
-        metadata_location,
-        metadata_hash,
-        is_multi_step_proposal,
-    );
-
-    let governance_records = borrow_global_mut<GovernanceRecords>(pool_address);
-
-    if (features::module_event_migration_enabled()) {
-        event::emit(
-            CreateProposal {
-                proposal_id,
-                voter: voter_addr,
-                delegation_pool: pool_address,
-            }
-        );
-    };
-
-    event::emit_event(
-        &mut governance_records.create_proposal_events,
-        CreateProposalEvent {
-            proposal_id,
-            voter: voter_addr,
-            delegation_pool: pool_address,
-        }
-    );
-}
-
- - -
@@ -5131,50 +4931,6 @@ shares pools, assign commission to operator and eventually prepare delegation po - - - - -## Function `assert_and_update_proposal_used_voting_power` - - - -
fun assert_and_update_proposal_used_voting_power(governance_records: &mut delegation_pool::GovernanceRecords, pool_address: address, proposal_id: u64, voting_power: u64)
-
- - - -
-Implementation - - -
inline fun assert_and_update_proposal_used_voting_power(
-    governance_records: &mut GovernanceRecords, pool_address: address, proposal_id: u64, voting_power: u64
-) {
-    let stake_pool_remaining_voting_power = supra_governance::get_remaining_voting_power(pool_address, proposal_id);
-    let stake_pool_used_voting_power = supra_governance::get_voting_power(
-        pool_address
-    ) - stake_pool_remaining_voting_power;
-    let proposal_used_voting_power = smart_table::borrow_mut_with_default(
-        &mut governance_records.votes_per_proposal,
-        proposal_id,
-        0
-    );
-    // A edge case: Before enabling partial governance voting on a delegation pool, the delegation pool has
-    // a voter which can vote with all voting power of this delegation pool. If the voter votes on a proposal after
-    // partial governance voting flag is enabled, the delegation pool doesn't have enough voting power on this
-    // proposal for all the delegators. To be fair, no one can vote on this proposal through this delegation pool.
-    // To detect this case, check if the stake pool had used voting power not through delegation_pool module.
-    assert!(
-        stake_pool_used_voting_power == *proposal_used_voting_power,
-        error::invalid_argument(EALREADY_VOTED_BEFORE_ENABLE_PARTIAL_VOTING)
-    );
-    *proposal_used_voting_power = *proposal_used_voting_power + voting_power;
-}
-
- - -
diff --git a/aptos-move/framework/supra-framework/doc/multisig_voting.md b/aptos-move/framework/supra-framework/doc/multisig_voting.md index 40a2bd7075bfb..82e0482fe5ad7 100644 --- a/aptos-move/framework/supra-framework/doc/multisig_voting.md +++ b/aptos-move/framework/supra-framework/doc/multisig_voting.md @@ -595,6 +595,16 @@ Cannot vote if the specified multi-step proposal is in execution. + + +Not a multisig owner authorized to vote. + + +
const ENOT_MULTISIG_OWNER: u64 = 16;
+
+ + + Proposal cannot be resolved more than once @@ -675,121 +685,111 @@ If we call - -Voting forum has already been registered. - - -
const EVOTING_FORUM_ALREADY_REGISTERED: u64 = 6;
-
- - - - + -Key used to track if the multi-step proposal is in execution / resolving in progress. +Threshold should not exceeds voters -
const IS_MULTI_STEP_PROPOSAL_IN_EXECUTION_KEY: vector<u8> = [73, 83, 95, 77, 85, 76, 84, 73, 95, 83, 84, 69, 80, 95, 80, 82, 79, 80, 79, 83, 65, 76, 95, 73, 78, 95, 69, 88, 69, 67, 85, 84, 73, 79, 78];
+
const ETHRESHOLD_EXCEEDS_VOTERS: u64 = 15;
 
- + -Key used to track if the proposal is multi-step +Threshold value must be greater than 1 -
const IS_MULTI_STEP_PROPOSAL_KEY: vector<u8> = [73, 83, 95, 77, 85, 76, 84, 73, 95, 83, 84, 69, 80, 95, 80, 82, 79, 80, 79, 83, 65, 76, 95, 75, 69, 89];
+
const ETHRESHOLD_MUST_BE_GREATER_THAN_ONE: u64 = 17;
 
- + -Proposal has failed because either the min vote threshold is not met or majority voted no. +Cannot vote duplicate -
const PROPOSAL_STATE_FAILED: u64 = 3;
+
const EVOTE_DUPLICATE_VOTE: u64 = 13;
 
- + -ProposalStateEnum representing proposal state. +Vote is overflow -
const PROPOSAL_STATE_PENDING: u64 = 0;
+
const EVOTE_OVERFLOW: u64 = 14;
 
- + +Voting forum has already been registered. -
const PROPOSAL_STATE_SUCCEEDED: u64 = 1;
+
const EVOTING_FORUM_ALREADY_REGISTERED: u64 = 6;
 
- + -Key used to track the resolvable time in the proposal's metadata. +Key used to track if the multi-step proposal is in execution / resolving in progress. -
const RESOLVABLE_TIME_METADATA_KEY: vector<u8> = [82, 69, 83, 79, 76, 86, 65, 66, 76, 69, 95, 84, 73, 77, 69, 95, 77, 69, 84, 65, 68, 65, 84, 65, 95, 75, 69, 89];
+
const IS_MULTI_STEP_PROPOSAL_IN_EXECUTION_KEY: vector<u8> = [73, 83, 95, 77, 85, 76, 84, 73, 95, 83, 84, 69, 80, 95, 80, 82, 79, 80, 79, 83, 65, 76, 95, 73, 78, 95, 69, 88, 69, 67, 85, 84, 73, 79, 78];
 
- + -Not a multisig owner authorized to vote. +Key used to track if the proposal is multi-step -
const ENOT_MULTISIG_OWNER: u64 = 16;
+
const IS_MULTI_STEP_PROPOSAL_KEY: vector<u8> = [73, 83, 95, 77, 85, 76, 84, 73, 95, 83, 84, 69, 80, 95, 80, 82, 79, 80, 79, 83, 65, 76, 95, 75, 69, 89];
 
- + -Threshold should not exceeds voters +Proposal has failed because either the min vote threshold is not met or majority voted no. -
const ETHRESHOLD_EXCEEDS_VOTERS: u64 = 15;
+
const PROPOSAL_STATE_FAILED: u64 = 3;
 
- + -Threshold value must be greater than 1 +ProposalStateEnum representing proposal state. -
const ETHRESHOLD_MUST_BE_GREATER_THAN_ONE: u64 = 17;
+
const PROPOSAL_STATE_PENDING: u64 = 0;
 
- + -Cannot vote duplicate -
const EVOTE_DUPLICATE_VOTE: u64 = 13;
+
const PROPOSAL_STATE_SUCCEEDED: u64 = 1;
 
- + -Vote is overflow +Key used to track the resolvable time in the proposal's metadata. -
const EVOTE_OVERFLOW: u64 = 14;
+
const RESOLVABLE_TIME_METADATA_KEY: vector<u8> = [82, 69, 83, 79, 76, 86, 65, 66, 76, 69, 95, 84, 73, 77, 69, 95, 77, 69, 84, 65, 68, 65, 84, 65, 95, 75, 69, 89];
 
diff --git a/aptos-move/framework/supra-framework/doc/pbo_delegation_pool.md b/aptos-move/framework/supra-framework/doc/pbo_delegation_pool.md index 3197d905365c6..54cc2f75c0011 100644 --- a/aptos-move/framework/supra-framework/doc/pbo_delegation_pool.md +++ b/aptos-move/framework/supra-framework/doc/pbo_delegation_pool.md @@ -154,7 +154,6 @@ transferred to A - [Function `get_add_stake_fee`](#0x1_pbo_delegation_pool_get_add_stake_fee) - [Function `can_withdraw_pending_inactive`](#0x1_pbo_delegation_pool_can_withdraw_pending_inactive) - [Function `calculate_and_update_voter_total_voting_power`](#0x1_pbo_delegation_pool_calculate_and_update_voter_total_voting_power) -- [Function `calculate_and_update_remaining_voting_power`](#0x1_pbo_delegation_pool_calculate_and_update_remaining_voting_power) - [Function `calculate_and_update_delegator_voter`](#0x1_pbo_delegation_pool_calculate_and_update_delegator_voter) - [Function `get_expected_stake_pool_address`](#0x1_pbo_delegation_pool_get_expected_stake_pool_address) - [Function `min_remaining_secs_for_commission_change`](#0x1_pbo_delegation_pool_min_remaining_secs_for_commission_change) @@ -162,8 +161,6 @@ transferred to A - [Function `get_admin`](#0x1_pbo_delegation_pool_get_admin) - [Function `beneficiary_for_operator`](#0x1_pbo_delegation_pool_beneficiary_for_operator) - [Function `enable_partial_governance_voting`](#0x1_pbo_delegation_pool_enable_partial_governance_voting) -- [Function `vote`](#0x1_pbo_delegation_pool_vote) -- [Function `create_proposal`](#0x1_pbo_delegation_pool_create_proposal) - [Function `assert_owner_cap_exists`](#0x1_pbo_delegation_pool_assert_owner_cap_exists) - [Function `assert_delegation_pool_exists`](#0x1_pbo_delegation_pool_assert_delegation_pool_exists) - [Function `assert_min_active_balance`](#0x1_pbo_delegation_pool_assert_min_active_balance) @@ -210,7 +207,6 @@ transferred to A - [Function `redeem_inactive_shares`](#0x1_pbo_delegation_pool_redeem_inactive_shares) - [Function `calculate_stake_pool_drift`](#0x1_pbo_delegation_pool_calculate_stake_pool_drift) - [Function `synchronize_delegation_pool`](#0x1_pbo_delegation_pool_synchronize_delegation_pool) -- [Function `assert_and_update_proposal_used_voting_power`](#0x1_pbo_delegation_pool_assert_and_update_proposal_used_voting_power) - [Function `update_governance_records_for_buy_in_active_shares`](#0x1_pbo_delegation_pool_update_governance_records_for_buy_in_active_shares) - [Function `update_governance_records_for_buy_in_pending_inactive_shares`](#0x1_pbo_delegation_pool_update_governance_records_for_buy_in_pending_inactive_shares) - [Function `update_governanace_records_for_redeem_active_shares`](#0x1_pbo_delegation_pool_update_governanace_records_for_redeem_active_shares) @@ -237,7 +233,6 @@ transferred to A use 0x1::staking_config; use 0x1::supra_account; use 0x1::supra_coin; -use 0x1::supra_governance; use 0x1::table; use 0x1::table_with_length; use 0x1::timestamp; @@ -1297,26 +1292,6 @@ Delegation pool owner capability does not exist at the provided account. - - -The voter does not have sufficient stake to create a proposal. - - -
const EINSUFFICIENT_PROPOSER_STAKE: u64 = 15;
-
- - - - - -The voter does not have any voting power on this proposal. - - -
const ENO_VOTING_POWER: u64 = 16;
-
- - - The stake pool has already voted on the proposal before enabling partial governance voting on this delegation pool. @@ -1377,6 +1352,16 @@ Delegator's pending_inactive balance cannot be less than + +The voter does not have sufficient stake to create a proposal. + + +
const EINSUFFICIENT_PROPOSER_STAKE: u64 = 15;
+
+ + + Commission percentage has to be between 0 and MAX_FEE - 100%. @@ -1397,6 +1382,16 @@ There is not enough active stake on the stake pool to unlock< + + +The voter does not have any voting power on this proposal. + + +
const ENO_VOTING_POWER: u64 = 16;
+
+ + + Chaning beneficiaries for operators is not supported. @@ -2185,46 +2180,6 @@ latest state. - - - - -## Function `calculate_and_update_remaining_voting_power` - -Return the remaining voting power of a delegator in a delegation pool on a proposal. This function syncs DelegationPool to the -latest state. - - -
#[view]
-public fun calculate_and_update_remaining_voting_power(pool_address: address, voter_address: address, proposal_id: u64): u64
-
- - - -
-Implementation - - -
public fun calculate_and_update_remaining_voting_power(
-    pool_address: address, voter_address: address, proposal_id: u64
-): u64 acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage {
-    assert_partial_governance_voting_enabled(pool_address);
-    // If the whole stake pool has no voting power(e.g. it has already voted before partial
-    // governance voting flag is enabled), the delegator also has no voting power.
-    if (supra_governance::get_remaining_voting_power(pool_address, proposal_id) == 0) {
-        return 0
-    };
-
-    let total_voting_power = calculate_and_update_voter_total_voting_power(pool_address,
-        voter_address);
-    let governance_records = borrow_global<GovernanceRecords>(pool_address);
-    total_voting_power - get_used_voting_power(governance_records, voter_address,
-        proposal_id)
-}
-
- - -
@@ -2580,136 +2535,6 @@ THe existing voter will be replaced. The function is permissionless. - - - - -## Function `vote` - -Vote on a proposal with a voter's voting power. To successfully vote, the following conditions must be met: -1. The voting period of the proposal hasn't ended. -2. The delegation pool's lockup period ends after the voting period of the proposal. -3. The voter still has spare voting power on this proposal. -4. The delegation pool never votes on the proposal before enabling partial governance voting. - - -
public entry fun vote(voter: &signer, pool_address: address, proposal_id: u64, voting_power: u64, should_pass: bool)
-
- - - -
-Implementation - - -
public entry fun vote(
-    voter: &signer,
-    pool_address: address,
-    proposal_id: u64,
-    voting_power: u64,
-    should_pass: bool
-) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage {
-    assert_partial_governance_voting_enabled(pool_address);
-    // synchronize delegation and stake pools before any user operation.
-    synchronize_delegation_pool(pool_address);
-
-    let voter_address = signer::address_of(voter);
-    let remaining_voting_power = calculate_and_update_remaining_voting_power(
-        pool_address, voter_address, proposal_id
-    );
-    if (voting_power > remaining_voting_power) {
-        voting_power = remaining_voting_power;
-    };
-    assert!(voting_power > 0, error::invalid_argument(ENO_VOTING_POWER));
-
-    let governance_records = borrow_global_mut<GovernanceRecords>(pool_address);
-    // Check a edge case during the transient period of enabling partial governance voting.
-    assert_and_update_proposal_used_voting_power(governance_records, pool_address,
-        proposal_id, voting_power);
-    let used_voting_power = borrow_mut_used_voting_power(governance_records,
-        voter_address, proposal_id);
-    *used_voting_power = *used_voting_power + voting_power;
-
-    let pool_signer = retrieve_stake_pool_owner(borrow_global<DelegationPool>(
-            pool_address
-        ));
-    supra_governance::partial_vote(&pool_signer, pool_address, proposal_id, voting_power,
-        should_pass);
-
-    event::emit_event(&mut governance_records.vote_events,
-        VoteEvent {
-            voter: voter_address,
-            proposal_id,
-            delegation_pool: pool_address,
-            num_votes: voting_power,
-            should_pass,
-        }
-    );
-}
-
- - - -
- - - -## Function `create_proposal` - -A voter could create a governance proposal by this function. To successfully create a proposal, the voter's -voting power in THIS delegation pool must be not less than the minimum required voting power specified in -supra_governance.move. - - -
public entry fun create_proposal(voter: &signer, pool_address: address, execution_hash: vector<u8>, metadata_location: vector<u8>, metadata_hash: vector<u8>, is_multi_step_proposal: bool)
-
- - - -
-Implementation - - -
public entry fun create_proposal(
-    voter: &signer,
-    pool_address: address,
-    execution_hash: vector<u8>,
-    metadata_location: vector<u8>,
-    metadata_hash: vector<u8>,
-    is_multi_step_proposal: bool,
-) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage {
-    assert_partial_governance_voting_enabled(pool_address);
-
-    // synchronize delegation and stake pools before any user operation
-    synchronize_delegation_pool(pool_address);
-
-    let voter_addr = signer::address_of(voter);
-    let pool = borrow_global<DelegationPool>(pool_address);
-    let governance_records = borrow_global_mut<GovernanceRecords>(pool_address);
-    let total_voting_power = calculate_and_update_delegated_votes(pool,
-        governance_records, voter_addr);
-    assert!(total_voting_power >= supra_governance::get_required_proposer_stake(),
-        error::invalid_argument(EINSUFFICIENT_PROPOSER_STAKE));
-    let pool_signer = retrieve_stake_pool_owner(borrow_global<DelegationPool>(
-            pool_address
-        ));
-    let proposal_id = supra_governance::create_proposal_v2_impl(&pool_signer,
-        pool_address,
-        execution_hash,
-        metadata_location,
-        metadata_hash,
-        is_multi_step_proposal,
-    );
-
-    let governance_records = borrow_global_mut<GovernanceRecords>(pool_address);
-    event::emit_event(&mut governance_records.create_proposal_events,
-        CreateProposalEvent { proposal_id, voter: voter_addr, delegation_pool: pool_address, }
-    );
-}
-
- - -
@@ -4609,49 +4434,6 @@ shares pools, assign commission to operator and eventually prepare delegation po - - - - -## Function `assert_and_update_proposal_used_voting_power` - - - -
fun assert_and_update_proposal_used_voting_power(governance_records: &mut pbo_delegation_pool::GovernanceRecords, pool_address: address, proposal_id: u64, voting_power: u64)
-
- - - -
-Implementation - - -
inline fun assert_and_update_proposal_used_voting_power(
-    governance_records: &mut GovernanceRecords,
-    pool_address: address,
-    proposal_id: u64,
-    voting_power: u64
-) {
-    let stake_pool_remaining_voting_power = supra_governance::get_remaining_voting_power(
-        pool_address, proposal_id
-    );
-    let stake_pool_used_voting_power = supra_governance::get_voting_power(pool_address)
-        - stake_pool_remaining_voting_power;
-    let proposal_used_voting_power = smart_table::borrow_mut_with_default(&mut governance_records
-        .votes_per_proposal, proposal_id, 0);
-    // A edge case: Before enabling partial governance voting on a delegation pool, the delegation pool has
-    // a voter which can vote with all voting power of this delegation pool. If the voter votes on a proposal after
-    // partial governance voting flag is enabled, the delegation pool doesn't have enough voting power on this
-    // proposal for all the delegators. To be fair, no one can vote on this proposal through this delegation pool.
-    // To detect this case, check if the stake pool had used voting power not through delegation_pool module.
-    assert!(stake_pool_used_voting_power == *proposal_used_voting_power,
-        error::invalid_argument(EALREADY_VOTED_BEFORE_ENABLE_PARTIAL_VOTING));
-    *proposal_used_voting_power = *proposal_used_voting_power + voting_power;
-}
-
- - -
diff --git a/aptos-move/framework/supra-framework/doc/supra_governance.md b/aptos-move/framework/supra-framework/doc/supra_governance.md index 3daebf8e0570c..dde5086352a7d 100644 --- a/aptos-move/framework/supra-framework/doc/supra_governance.md +++ b/aptos-move/framework/supra-framework/doc/supra_governance.md @@ -17,18 +17,7 @@ on a proposal multiple times as long as the total voting power of these votes do - [Resource `GovernanceResponsbility`](#0x1_supra_governance_GovernanceResponsbility) -- [Resource `GovernanceConfig`](#0x1_supra_governance_GovernanceConfig) -- [Struct `RecordKey`](#0x1_supra_governance_RecordKey) -- [Resource `VotingRecords`](#0x1_supra_governance_VotingRecords) -- [Resource `VotingRecordsV2`](#0x1_supra_governance_VotingRecordsV2) - [Resource `ApprovedExecutionHashes`](#0x1_supra_governance_ApprovedExecutionHashes) -- [Resource `GovernanceEvents`](#0x1_supra_governance_GovernanceEvents) -- [Struct `CreateProposalEvent`](#0x1_supra_governance_CreateProposalEvent) -- [Struct `VoteEvent`](#0x1_supra_governance_VoteEvent) -- [Struct `UpdateConfigEvent`](#0x1_supra_governance_UpdateConfigEvent) -- [Struct `CreateProposal`](#0x1_supra_governance_CreateProposal) -- [Struct `Vote`](#0x1_supra_governance_Vote) -- [Struct `UpdateConfig`](#0x1_supra_governance_UpdateConfig) - [Resource `SupraGovernanceConfig`](#0x1_supra_governance_SupraGovernanceConfig) - [Resource `SupraGovernanceEvents`](#0x1_supra_governance_SupraGovernanceEvents) - [Struct `SupraCreateProposalEvent`](#0x1_supra_governance_SupraCreateProposalEvent) @@ -39,75 +28,47 @@ on a proposal multiple times as long as the total voting power of these votes do - [Struct `SupraUpdateConfig`](#0x1_supra_governance_SupraUpdateConfig) - [Constants](#@Constants_0) - [Function `store_signer_cap`](#0x1_supra_governance_store_signer_cap) -- [Function `old_initialize`](#0x1_supra_governance_old_initialize) - [Function `initialize`](#0x1_supra_governance_initialize) -- [Function `update_governance_config`](#0x1_supra_governance_update_governance_config) - [Function `update_supra_governance_config`](#0x1_supra_governance_update_supra_governance_config) -- [Function `initialize_partial_voting`](#0x1_supra_governance_initialize_partial_voting) - [Function `get_voting_duration_secs`](#0x1_supra_governance_get_voting_duration_secs) - [Function `get_min_voting_threshold`](#0x1_supra_governance_get_min_voting_threshold) -- [Function `get_required_proposer_stake`](#0x1_supra_governance_get_required_proposer_stake) -- [Function `has_entirely_voted`](#0x1_supra_governance_has_entirely_voted) -- [Function `get_remaining_voting_power`](#0x1_supra_governance_get_remaining_voting_power) -- [Function `create_proposal`](#0x1_supra_governance_create_proposal) -- [Function `create_proposal_v2`](#0x1_supra_governance_create_proposal_v2) -- [Function `create_proposal_v2_impl`](#0x1_supra_governance_create_proposal_v2_impl) +- [Function `get_voters_list`](#0x1_supra_governance_get_voters_list) - [Function `supra_create_proposal`](#0x1_supra_governance_supra_create_proposal) - [Function `supra_create_proposal_v2`](#0x1_supra_governance_supra_create_proposal_v2) - [Function `supra_create_proposal_v2_impl`](#0x1_supra_governance_supra_create_proposal_v2_impl) -- [Function `batch_vote`](#0x1_supra_governance_batch_vote) -- [Function `batch_partial_vote`](#0x1_supra_governance_batch_partial_vote) -- [Function `vote`](#0x1_supra_governance_vote) -- [Function `partial_vote`](#0x1_supra_governance_partial_vote) -- [Function `vote_internal`](#0x1_supra_governance_vote_internal) - [Function `supra_vote`](#0x1_supra_governance_supra_vote) - [Function `supra_vote_internal`](#0x1_supra_governance_supra_vote_internal) -- [Function `add_approved_script_hash_script`](#0x1_supra_governance_add_approved_script_hash_script) - [Function `add_supra_approved_script_hash_script`](#0x1_supra_governance_add_supra_approved_script_hash_script) -- [Function `add_approved_script_hash`](#0x1_supra_governance_add_approved_script_hash) - [Function `add_supra_approved_script_hash`](#0x1_supra_governance_add_supra_approved_script_hash) -- [Function `resolve`](#0x1_supra_governance_resolve) - [Function `supra_resolve`](#0x1_supra_governance_supra_resolve) -- [Function `resolve_multi_step_proposal`](#0x1_supra_governance_resolve_multi_step_proposal) - [Function `resolve_supra_multi_step_proposal`](#0x1_supra_governance_resolve_supra_multi_step_proposal) -- [Function `remove_approved_hash`](#0x1_supra_governance_remove_approved_hash) - [Function `remove_supra_approved_hash`](#0x1_supra_governance_remove_supra_approved_hash) - [Function `reconfigure`](#0x1_supra_governance_reconfigure) - [Function `force_end_epoch`](#0x1_supra_governance_force_end_epoch) - [Function `force_end_epoch_test_only`](#0x1_supra_governance_force_end_epoch_test_only) - [Function `toggle_features`](#0x1_supra_governance_toggle_features) - [Function `get_signer_testnet_only`](#0x1_supra_governance_get_signer_testnet_only) -- [Function `get_voting_power`](#0x1_supra_governance_get_voting_power) - [Function `get_signer`](#0x1_supra_governance_get_signer) - [Function `create_proposal_metadata`](#0x1_supra_governance_create_proposal_metadata) -- [Function `assert_voting_initialization`](#0x1_supra_governance_assert_voting_initialization) - [Function `initialize_for_verification`](#0x1_supra_governance_initialize_for_verification)
use 0x1::account;
-use 0x1::coin;
 use 0x1::consensus_config;
 use 0x1::error;
 use 0x1::event;
 use 0x1::features;
 use 0x1::governance_proposal;
-use 0x1::math64;
 use 0x1::multisig_voting;
-use 0x1::option;
 use 0x1::randomness_config;
 use 0x1::reconfiguration_with_dkg;
 use 0x1::signer;
 use 0x1::simple_map;
-use 0x1::smart_table;
-use 0x1::stake;
-use 0x1::staking_config;
 use 0x1::string;
 use 0x1::supra_coin;
 use 0x1::system_addresses;
-use 0x1::table;
 use 0x1::timestamp;
 use 0x1::vector;
-use 0x1::voting;
 
@@ -140,54 +101,15 @@ Store the SignerCapabilities of accounts under the on-chain governance's control - - -## Resource `GovernanceConfig` - -Configurations of the AptosGovernance, set during Genesis and can be updated by the same process offered -by this AptosGovernance module. - - -
struct GovernanceConfig has key
-
- - - -
-Fields - - -
-
-min_voting_threshold: u128 -
-
- -
-
-required_proposer_stake: u64 -
-
- -
-
-voting_duration_secs: u64 -
-
- -
-
- - -
- - + -## Struct `RecordKey` +## Resource `ApprovedExecutionHashes` +Used to track which execution script hashes have been approved by governance. +This is required to bypass cases where the execution scripts exceed the size limit imposed by mempool. -
struct RecordKey has copy, drop, store
+
struct ApprovedExecutionHashes has key
 
@@ -198,13 +120,7 @@ by this AptosGovernance module.
-stake_pool: address -
-
- -
-
-proposal_id: u64 +hashes: simple_map::SimpleMap<u64, vector<u8>>
@@ -214,14 +130,15 @@ by this AptosGovernance module. - + -## Resource `VotingRecords` +## Resource `SupraGovernanceConfig` -Records to track the proposals each stake pool has been used to vote on. +Configurations of the SupraGovernance, set during Genesis and can be updated by the same process offered +by this SupraGovernance module. -
struct VotingRecords has key
+
struct SupraGovernanceConfig has key
 
@@ -232,64 +149,19 @@ Records to track the proposals each stake pool has been used to vote on.
-votes: table::Table<supra_governance::RecordKey, bool> +voting_duration_secs: u64
-
- - - - - - -## Resource `VotingRecordsV2` - -Records to track the voting power usage of each stake pool on each proposal. - - -
struct VotingRecordsV2 has key
-
- - - -
-Fields - - -
-votes: smart_table::SmartTable<supra_governance::RecordKey, u64> +min_voting_threshold: u64
-
- - -
- - - -## Resource `ApprovedExecutionHashes` - -Used to track which execution script hashes have been approved by governance. -This is required to bypass cases where the execution scripts exceed the size limit imposed by mempool. - - -
struct ApprovedExecutionHashes has key
-
- - - -
-Fields - - -
-hashes: simple_map::SimpleMap<u64, vector<u8>> +voters: vector<address>
@@ -299,14 +171,14 @@ This is required to bypass cases where the execution scripts exceed the size lim
- + -## Resource `GovernanceEvents` +## Resource `SupraGovernanceEvents` -Events generated by interactions with the AptosGovernance module. +Events generated by interactions with the SupraGovernance module. -
struct GovernanceEvents has key
+
struct SupraGovernanceEvents has key
 
@@ -317,19 +189,19 @@ Events generated by interactions with the AptosGovernance module.
-create_proposal_events: event::EventHandle<supra_governance::CreateProposalEvent> +create_proposal_events: event::EventHandle<supra_governance::SupraCreateProposalEvent>
-update_config_events: event::EventHandle<supra_governance::UpdateConfigEvent> +update_config_events: event::EventHandle<supra_governance::SupraUpdateConfigEvent>
-vote_events: event::EventHandle<supra_governance::VoteEvent> +vote_events: event::EventHandle<supra_governance::SupraVoteEvent>
@@ -339,14 +211,14 @@ Events generated by interactions with the AptosGovernance module. - + -## Struct `CreateProposalEvent` +## Struct `SupraCreateProposalEvent` Event emitted when a proposal is created. -
struct CreateProposalEvent has drop, store
+
struct SupraCreateProposalEvent has drop, store
 
@@ -361,12 +233,6 @@ Event emitted when a proposal is created.
-
-
-stake_pool: address -
-
-
proposal_id: u64 @@ -391,14 +257,14 @@ Event emitted when a proposal is created. - + -## Struct `VoteEvent` +## Struct `SupraUpdateConfigEvent` -Event emitted when there's a vote on a proposa; +Event emitted when the governance configs are updated. -
struct VoteEvent has drop, store
+
struct SupraUpdateConfigEvent has drop, store
 
@@ -409,31 +275,19 @@ Event emitted when there's a vote on a proposa;
-proposal_id: u64 -
-
- -
-
-voter: address -
-
- -
-
-stake_pool: address +voting_duration_secs: u64
-num_votes: u64 +min_voting_threshold: u64
-should_pass: bool +voters: vector<address>
@@ -443,14 +297,14 @@ Event emitted when there's a vote on a proposa; - + -## Struct `UpdateConfigEvent` +## Struct `SupraVoteEvent` -Event emitted when the governance configs are updated. +Event emitted when there's a vote on a proposa; -
struct UpdateConfigEvent has drop, store
+
struct SupraVoteEvent has drop, store
 
@@ -461,19 +315,19 @@ Event emitted when the governance configs are updated.
-min_voting_threshold: u128 +proposal_id: u64
-required_proposer_stake: u64 +voter: address
-voting_duration_secs: u64 +should_pass: bool
@@ -483,15 +337,15 @@ Event emitted when the governance configs are updated. - + -## Struct `CreateProposal` +## Struct `SupraCreateProposal` Event emitted when a proposal is created.
#[event]
-struct CreateProposal has drop, store
+struct SupraCreateProposal has drop, store
 
@@ -506,12 +360,6 @@ Event emitted when a proposal is created.
-
-
-stake_pool: address -
-
-
proposal_id: u64 @@ -536,15 +384,15 @@ Event emitted when a proposal is created. - + -## Struct `Vote` +## Struct `SupraVote` Event emitted when there's a vote on a proposa;
#[event]
-struct Vote has drop, store
+struct SupraVote has drop, store
 
@@ -565,18 +413,6 @@ Event emitted when there's a vote on a proposa;
-
-
-stake_pool: address -
-
- -
-
-num_votes: u64 -
-
-
should_pass: bool @@ -589,15 +425,15 @@ Event emitted when there's a vote on a proposa; - + -## Struct `UpdateConfig` +## Struct `SupraUpdateConfig` Event emitted when the governance configs are updated.
#[event]
-struct UpdateConfig has drop, store
+struct SupraUpdateConfig has drop, store
 
@@ -608,19 +444,19 @@ Event emitted when the governance configs are updated.
-min_voting_threshold: u128 +voting_duration_secs: u64
-required_proposer_stake: u64 +min_voting_threshold: u64
-voting_duration_secs: u64 +voters: vector<address>
@@ -630,1173 +466,164 @@ Event emitted when the governance configs are updated. - + -## Resource `SupraGovernanceConfig` +## Constants -Configurations of the SupraGovernance, set during Genesis and can be updated by the same process offered -by this SupraGovernance module. + + + +Threshold should not exceeds voters -
struct SupraGovernanceConfig has key
+
const ETHRESHOLD_EXCEEDS_VOTERS: u64 = 17;
 
-
-Fields + +Threshold value must be greater than 1 -
-
-voting_duration_secs: u64 -
-
-
-
-min_voting_threshold: u64 -
-
+
const ETHRESHOLD_MUST_BE_GREATER_THAN_ONE: u64 = 18;
+
-
-
-voters: vector<address> -
-
-
-
+ -
+This matches the same enum const in voting. We have to duplicate it as Move doesn't have support for enums yet. - -## Resource `SupraGovernanceEvents` +
const PROPOSAL_STATE_SUCCEEDED: u64 = 1;
+
-Events generated by interactions with the SupraGovernance module. -
struct SupraGovernanceEvents has key
-
+ +The account does not have permission to propose or vote -
-Fields +
const EACCOUNT_NOT_AUTHORIZED: u64 = 15;
+
-
-
-create_proposal_events: event::EventHandle<supra_governance::SupraCreateProposalEvent> -
-
-
-
-update_config_events: event::EventHandle<supra_governance::SupraUpdateConfigEvent> -
-
+ -
-
-vote_events: event::EventHandle<supra_governance::SupraVoteEvent> -
-
+Metadata hash cannot be longer than 256 chars -
-
+
const EMETADATA_HASH_TOO_LONG: u64 = 10;
+
-
- -## Struct `SupraCreateProposalEvent` + -Event emitted when a proposal is created. +Metadata location cannot be longer than 256 chars -
struct SupraCreateProposalEvent has drop, store
+
const EMETADATA_LOCATION_TOO_LONG: u64 = 9;
 
-
-Fields + +Proposal is expired -
-
-proposer: address -
-
- -
-
-proposal_id: u64 -
-
- -
-
-execution_hash: vector<u8> -
-
- -
-
-proposal_metadata: simple_map::SimpleMap<string::String, vector<u8>> -
-
- -
-
- - -
- - - -## Struct `SupraUpdateConfigEvent` - -Event emitted when the governance configs are updated. - - -
struct SupraUpdateConfigEvent has drop, store
-
- - - -
-Fields - - -
-
-voting_duration_secs: u64 -
-
- -
-
-min_voting_threshold: u64 -
-
- -
-
-voters: vector<address> -
-
- -
-
- - -
- - - -## Struct `SupraVoteEvent` - -Event emitted when there's a vote on a proposa; - - -
struct SupraVoteEvent has drop, store
-
- - - -
-Fields - - -
-
-proposal_id: u64 -
-
- -
-
-voter: address -
-
- -
-
-should_pass: bool -
-
- -
-
- - -
- - - -## Struct `SupraCreateProposal` - -Event emitted when a proposal is created. - - -
#[event]
-struct SupraCreateProposal has drop, store
-
- - - -
-Fields - - -
-
-proposer: address -
-
- -
-
-proposal_id: u64 -
-
- -
-
-execution_hash: vector<u8> -
-
- -
-
-proposal_metadata: simple_map::SimpleMap<string::String, vector<u8>> -
-
- -
-
- - -
- - - -## Struct `SupraVote` - -Event emitted when there's a vote on a proposa; - - -
#[event]
-struct SupraVote has drop, store
-
- - - -
-Fields - - -
-
-proposal_id: u64 -
-
- -
-
-voter: address -
-
- -
-
-should_pass: bool -
-
- -
-
- - -
- - - -## Struct `SupraUpdateConfig` - -Event emitted when the governance configs are updated. - - -
#[event]
-struct SupraUpdateConfig has drop, store
-
- - - -
-Fields - - -
-
-voting_duration_secs: u64 -
-
- -
-
-min_voting_threshold: u64 -
-
- -
-
-voters: vector<address> -
-
- -
-
- - -
- - - -## Constants - - - - - - -
const MAX_U64: u64 = 18446744073709551615;
-
- - - - - -This matches the same enum const in voting. We have to duplicate it as Move doesn't have support for enums yet. - - -
const PROPOSAL_STATE_SUCCEEDED: u64 = 1;
-
- - - - - -Threshold should not exceeds voters - - -
const ETHRESHOLD_EXCEEDS_VOTERS: u64 = 17;
-
- - - - - -Threshold value must be greater than 1 - - -
const ETHRESHOLD_MUST_BE_GREATER_THAN_ONE: u64 = 18;
-
- - - - - -The account does not have permission to propose or vote - - -
const EACCOUNT_NOT_AUTHORIZED: u64 = 15;
-
- - - - - -The specified stake pool has already been used to vote on the same proposal - - -
const EALREADY_VOTED: u64 = 4;
-
- - - - - -The specified stake pool does not have sufficient stake to create a proposal - - -
const EINSUFFICIENT_PROPOSER_STAKE: u64 = 1;
-
- - - - - -The specified stake pool does not have long enough remaining lockup to create a proposal or vote - - -
const EINSUFFICIENT_STAKE_LOCKUP: u64 = 3;
-
- - - - - -Metadata hash cannot be longer than 256 chars - - -
const EMETADATA_HASH_TOO_LONG: u64 = 10;
-
- - - - - -Metadata location cannot be longer than 256 chars - - -
const EMETADATA_LOCATION_TOO_LONG: u64 = 9;
-
- - - - - -This account is not the designated voter of the specified stake pool - - -
const ENOT_DELEGATED_VOTER: u64 = 2;
-
- - - - - -The proposal in the argument is not a partial voting proposal. - - -
const ENOT_PARTIAL_VOTING_PROPOSAL: u64 = 14;
-
- - - - - -The specified stake pool must be part of the validator set - - -
const ENO_VOTING_POWER: u64 = 5;
-
- - - - - -Partial voting feature hasn't been properly initialized. - - -
const EPARTIAL_VOTING_NOT_INITIALIZED: u64 = 13;
-
- - - - - -Proposal is expired - - -
const EPROPOSAL_IS_EXPIRE: u64 = 16;
-
- - - - - -Proposal is not ready to be resolved. Waiting on time or votes - - -
const EPROPOSAL_NOT_RESOLVABLE_YET: u64 = 6;
-
- - - - - -The proposal has not been resolved yet - - -
const EPROPOSAL_NOT_RESOLVED_YET: u64 = 8;
-
- - - - - -Account is not authorized to call this function. - - -
const EUNAUTHORIZED: u64 = 11;
-
- - - - - -The stake pool is using voting power more than it has. - - -
const EVOTING_POWER_OVERFLOW: u64 = 12;
-
- - - - - - - -
const METADATA_HASH_KEY: vector<u8> = [109, 101, 116, 97, 100, 97, 116, 97, 95, 104, 97, 115, 104];
-
- - - - - -Proposal metadata attribute keys. - - -
const METADATA_LOCATION_KEY: vector<u8> = [109, 101, 116, 97, 100, 97, 116, 97, 95, 108, 111, 99, 97, 116, 105, 111, 110];
-
- - - - - -## Function `store_signer_cap` - -Can be called during genesis or by the governance itself. -Stores the signer capability for a given address. - - -
public fun store_signer_cap(supra_framework: &signer, signer_address: address, signer_cap: account::SignerCapability)
-
- - - -
-Implementation - - -
public fun store_signer_cap(
-    supra_framework: &signer,
-    signer_address: address,
-    signer_cap: SignerCapability,
-) acquires GovernanceResponsbility {
-    system_addresses::assert_supra_framework(supra_framework);
-    system_addresses::assert_framework_reserved(signer_address);
-
-    if (!exists<GovernanceResponsbility>(@supra_framework)) {
-        move_to(
-            supra_framework,
-            GovernanceResponsbility { signer_caps: simple_map::create<address, SignerCapability>() }
-        );
-    };
-
-    let signer_caps = &mut borrow_global_mut<GovernanceResponsbility>(@supra_framework).signer_caps;
-    simple_map::add(signer_caps, signer_address, signer_cap);
-}
-
- - - -
- - - -## Function `old_initialize` - - - -
fun old_initialize(supra_framework: &signer, min_voting_threshold: u128, required_proposer_stake: u64, voting_duration_secs: u64)
-
- - - -
-Implementation - - -
fun old_initialize(
-    supra_framework: &signer,
-    min_voting_threshold: u128,
-    required_proposer_stake: u64,
-    voting_duration_secs: u64,
-) {
-    system_addresses::assert_supra_framework(supra_framework);
-
-    voting::register<GovernanceProposal>(supra_framework);
-    move_to(supra_framework, GovernanceConfig {
-        voting_duration_secs,
-        min_voting_threshold,
-        required_proposer_stake,
-    });
-    move_to(supra_framework, GovernanceEvents {
-        create_proposal_events: account::new_event_handle<CreateProposalEvent>(supra_framework),
-        update_config_events: account::new_event_handle<UpdateConfigEvent>(supra_framework),
-        vote_events: account::new_event_handle<VoteEvent>(supra_framework),
-    });
-    move_to(supra_framework, VotingRecords {
-        votes: table::new(),
-    });
-    move_to(supra_framework, ApprovedExecutionHashes {
-        hashes: simple_map::create<u64, vector<u8>>()
-    });
-}
-
- - - -
- - - -## Function `initialize` - -Initializes the state for Aptos Governance. Can only be called during Genesis with a signer -for the supra_framework (0x1) account. -This function is private because it's called directly from the vm. - - -
fun initialize(supra_framework: &signer, voting_duration_secs: u64, min_voting_threshold: u64, voters: vector<address>)
-
- - - -
-Implementation - - -
fun initialize(
-    supra_framework: &signer,
-    voting_duration_secs: u64,
-    min_voting_threshold: u64,
-    voters: vector<address>,
-) {
-    multisig_voting::register<GovernanceProposal>(supra_framework);
-
-    assert!(vector::length(&voters) >= min_voting_threshold && min_voting_threshold > vector::length(&voters) / 2, error::invalid_argument(ETHRESHOLD_EXCEEDS_VOTERS));
-    assert!(min_voting_threshold > 1, error::invalid_argument(ETHRESHOLD_MUST_BE_GREATER_THAN_ONE));
-
-    move_to(supra_framework, SupraGovernanceConfig {
-        voting_duration_secs,
-        min_voting_threshold,
-        voters,
-    });
-    move_to(supra_framework, SupraGovernanceEvents {
-        create_proposal_events: account::new_event_handle<SupraCreateProposalEvent>(supra_framework),
-        update_config_events: account::new_event_handle<SupraUpdateConfigEvent>(supra_framework),
-        vote_events: account::new_event_handle<SupraVoteEvent>(supra_framework),
-    });
-    move_to(supra_framework, ApprovedExecutionHashes {
-        hashes: simple_map::create<u64, vector<u8>>(),
-    })
-}
-
- - - -
- - - -## Function `update_governance_config` - -Update the governance configurations. This can only be called as part of resolving a proposal in this same -AptosGovernance. - - -
public fun update_governance_config(supra_framework: &signer, min_voting_threshold: u128, required_proposer_stake: u64, voting_duration_secs: u64)
-
- - - -
-Implementation - - -
public fun update_governance_config(
-    supra_framework: &signer,
-    min_voting_threshold: u128,
-    required_proposer_stake: u64,
-    voting_duration_secs: u64,
-) acquires GovernanceConfig, GovernanceEvents {
-    system_addresses::assert_supra_framework(supra_framework);
-
-    let governance_config = borrow_global_mut<GovernanceConfig>(@supra_framework);
-    governance_config.voting_duration_secs = voting_duration_secs;
-    governance_config.min_voting_threshold = min_voting_threshold;
-    governance_config.required_proposer_stake = required_proposer_stake;
-
-    if (std::features::module_event_migration_enabled()) {
-        event::emit(
-            UpdateConfig {
-                min_voting_threshold,
-                required_proposer_stake,
-                voting_duration_secs
-            },
-        )
-    };
-    let events = borrow_global_mut<GovernanceEvents>(@supra_framework);
-    event::emit_event<UpdateConfigEvent>(
-        &mut events.update_config_events,
-        UpdateConfigEvent {
-            min_voting_threshold,
-            required_proposer_stake,
-            voting_duration_secs
-        },
-    );
-}
-
- - - -
- - -## Function `update_supra_governance_config` - - - -
public fun update_supra_governance_config(supra_framework: &signer, voting_duration_secs: u64, min_voting_threshold: u64, voters: vector<address>)
-
- - - -
-Implementation - - -
public fun update_supra_governance_config(
-    supra_framework: &signer,
-    voting_duration_secs: u64,
-    min_voting_threshold: u64,
-    voters: vector<address>,
-) acquires SupraGovernanceConfig, SupraGovernanceEvents {
-    system_addresses::assert_supra_framework(supra_framework);
-
-    assert!(vector::length(&voters) >= min_voting_threshold && min_voting_threshold > vector::length(&voters) / 2, error::invalid_argument(ETHRESHOLD_EXCEEDS_VOTERS));
-    assert!(min_voting_threshold > 1, error::invalid_argument(ETHRESHOLD_MUST_BE_GREATER_THAN_ONE));
-
-    let supra_governance_config = borrow_global_mut<SupraGovernanceConfig>(@supra_framework);
-    supra_governance_config.voting_duration_secs = voting_duration_secs;
-    supra_governance_config.min_voting_threshold = min_voting_threshold;
-    supra_governance_config.voters = voters;
-
-    if (std::features::module_event_migration_enabled()) {
-        event::emit(
-            SupraUpdateConfig {
-                min_voting_threshold,
-                voting_duration_secs,
-                voters,
-            },
-        )
-    };
-    let events = borrow_global_mut<SupraGovernanceEvents>(@supra_framework);
-    event::emit_event<SupraUpdateConfigEvent>(
-        &mut events.update_config_events,
-        SupraUpdateConfigEvent {
-            min_voting_threshold,
-            voting_duration_secs,
-            voters,
-        },
-    );
-}
-
- - - -
- - - -## Function `initialize_partial_voting` - -Initializes the state for Aptos Governance partial voting. Can only be called through Aptos governance -proposals with a signer for the supra_framework (0x1) account. - - -
public fun initialize_partial_voting(supra_framework: &signer)
-
- - - -
-Implementation - - -
public fun initialize_partial_voting(
-    supra_framework: &signer,
-) {
-    system_addresses::assert_supra_framework(supra_framework);
-
-    move_to(supra_framework, VotingRecordsV2 {
-        votes: smart_table::new(),
-    });
-}
-
- - - -
- - - -## Function `get_voting_duration_secs` - - - -
#[view]
-public fun get_voting_duration_secs(): u64
-
- - - -
-Implementation - - -
public fun get_voting_duration_secs(): u64 acquires GovernanceConfig {
-    borrow_global<GovernanceConfig>(@supra_framework).voting_duration_secs
-}
-
- - - -
- - - -## Function `get_min_voting_threshold` - - - -
#[view]
-public fun get_min_voting_threshold(): u128
-
- - - -
-Implementation - - -
public fun get_min_voting_threshold(): u128 acquires GovernanceConfig {
-    borrow_global<GovernanceConfig>(@supra_framework).min_voting_threshold
-}
-
- - - -
- - - -## Function `get_required_proposer_stake` - - - -
#[view]
-public fun get_required_proposer_stake(): u64
-
- - - -
-Implementation - - -
public fun get_required_proposer_stake(): u64 acquires GovernanceConfig {
-    borrow_global<GovernanceConfig>(@supra_framework).required_proposer_stake
-}
+
const EPROPOSAL_IS_EXPIRE: u64 = 16;
 
-
- - - -## Function `has_entirely_voted` - -Return true if a stake pool has already voted on a proposal before partial governance voting is enabled. - - -
#[view]
-public fun has_entirely_voted(stake_pool: address, proposal_id: u64): bool
-
- - + -
-Implementation +Proposal is not ready to be resolved. Waiting on time or votes -
public fun has_entirely_voted(stake_pool: address, proposal_id: u64): bool acquires VotingRecords {
-    let record_key = RecordKey {
-        stake_pool,
-        proposal_id,
-    };
-    // If a stake pool has already voted on a proposal before partial governance voting is enabled,
-    // there is a record in VotingRecords.
-    let voting_records = borrow_global<VotingRecords>(@supra_framework);
-    table::contains(&voting_records.votes, record_key)
-}
+
const EPROPOSAL_NOT_RESOLVABLE_YET: u64 = 6;
 
-
- - - -## Function `get_remaining_voting_power` + -Return remaining voting power of a stake pool on a proposal. -Note: a stake pool's voting power on a proposal could increase over time(e.g. rewards/new stake). +The proposal has not been resolved yet -
#[view]
-public fun get_remaining_voting_power(stake_pool: address, proposal_id: u64): u64
+
const EPROPOSAL_NOT_RESOLVED_YET: u64 = 8;
 
-
-Implementation - + -
public fun get_remaining_voting_power(
-    stake_pool: address,
-    proposal_id: u64
-): u64 acquires VotingRecords, VotingRecordsV2 {
-    assert_voting_initialization();
+Account is not authorized to call this function.
 
-    let proposal_expiration = voting::get_proposal_expiration_secs<GovernanceProposal>(
-        @supra_framework,
-        proposal_id
-    );
-    let lockup_until = stake::get_lockup_secs(stake_pool);
-    // The voter's stake needs to be locked up at least as long as the proposal's expiration.
-    // Also no one can vote on a expired proposal.
-    if (proposal_expiration > lockup_until || timestamp::now_seconds() > proposal_expiration) {
-        return 0
-    };
 
-    // If a stake pool has already voted on a proposal before partial governance voting is enabled, the stake pool
-    // cannot vote on the proposal even after partial governance voting is enabled.
-    if (has_entirely_voted(stake_pool, proposal_id)) {
-        return 0
-    };
-    let record_key = RecordKey {
-        stake_pool,
-        proposal_id,
-    };
-    let used_voting_power = 0u64;
-    if (features::partial_governance_voting_enabled()) {
-        let voting_records_v2 = borrow_global<VotingRecordsV2>(@supra_framework);
-        used_voting_power = *smart_table::borrow_with_default(&voting_records_v2.votes, record_key, &0);
-    };
-    get_voting_power(stake_pool) - used_voting_power
-}
+
const EUNAUTHORIZED: u64 = 11;
 
-
- - - -## Function `create_proposal` - -Create a single-step proposal with the backing stake_pool. -@param execution_hash Required. This is the hash of the resolution script. When the proposal is resolved, -only the exact script with matching hash can be successfully executed. - - -
public entry fun create_proposal(proposer: &signer, stake_pool: address, execution_hash: vector<u8>, metadata_location: vector<u8>, metadata_hash: vector<u8>)
-
- - + -
-Implementation -
public entry fun create_proposal(
-    proposer: &signer,
-    stake_pool: address,
-    execution_hash: vector<u8>,
-    metadata_location: vector<u8>,
-    metadata_hash: vector<u8>,
-) acquires GovernanceConfig, GovernanceEvents {
-    create_proposal_v2(proposer, stake_pool, execution_hash, metadata_location, metadata_hash, false);
-}
+
const METADATA_HASH_KEY: vector<u8> = [109, 101, 116, 97, 100, 97, 116, 97, 95, 104, 97, 115, 104];
 
-
- - - -## Function `create_proposal_v2` - -Create a single-step or multi-step proposal with the backing stake_pool. -@param execution_hash Required. This is the hash of the resolution script. When the proposal is resolved, -only the exact script with matching hash can be successfully executed. - - -
public entry fun create_proposal_v2(proposer: &signer, stake_pool: address, execution_hash: vector<u8>, metadata_location: vector<u8>, metadata_hash: vector<u8>, is_multi_step_proposal: bool)
-
- - + -
-Implementation +Proposal metadata attribute keys. -
public entry fun create_proposal_v2(
-    proposer: &signer,
-    stake_pool: address,
-    execution_hash: vector<u8>,
-    metadata_location: vector<u8>,
-    metadata_hash: vector<u8>,
-    is_multi_step_proposal: bool,
-) acquires GovernanceConfig, GovernanceEvents {
-    create_proposal_v2_impl(
-        proposer,
-        stake_pool,
-        execution_hash,
-        metadata_location,
-        metadata_hash,
-        is_multi_step_proposal
-    );
-}
+
const METADATA_LOCATION_KEY: vector<u8> = [109, 101, 116, 97, 100, 97, 116, 97, 95, 108, 111, 99, 97, 116, 105, 111, 110];
 
-
- - - -## Function `create_proposal_v2_impl` - -Create a single-step or multi-step proposal with the backing stake_pool. -@param execution_hash Required. This is the hash of the resolution script. When the proposal is resolved, -only the exact script with matching hash can be successfully executed. -Return proposal_id when a proposal is successfully created. - - -
public fun create_proposal_v2_impl(proposer: &signer, stake_pool: address, execution_hash: vector<u8>, metadata_location: vector<u8>, metadata_hash: vector<u8>, is_multi_step_proposal: bool): u64
-
- + +## Function `store_signer_cap` -
-Implementation +Can be called during genesis or by the governance itself. +Stores the signer capability for a given address. -
public fun create_proposal_v2_impl(
-    proposer: &signer,
-    stake_pool: address,
-    execution_hash: vector<u8>,
-    metadata_location: vector<u8>,
-    metadata_hash: vector<u8>,
-    is_multi_step_proposal: bool,
-): u64 acquires GovernanceConfig, GovernanceEvents {
-    let proposer_address = signer::address_of(proposer);
-    assert!(
-        stake::get_delegated_voter(stake_pool) == proposer_address,
-        error::invalid_argument(ENOT_DELEGATED_VOTER)
-    );
+
public fun store_signer_cap(supra_framework: &signer, signer_address: address, signer_cap: account::SignerCapability)
+
- // The proposer's stake needs to be at least the required bond amount. - let governance_config = borrow_global<GovernanceConfig>(@supra_framework); - let stake_balance = get_voting_power(stake_pool); - assert!( - stake_balance >= governance_config.required_proposer_stake, - error::invalid_argument(EINSUFFICIENT_PROPOSER_STAKE), - ); - // The proposer's stake needs to be locked up at least as long as the proposal's voting period. - let current_time = timestamp::now_seconds(); - let proposal_expiration = current_time + governance_config.voting_duration_secs; - assert!( - stake::get_lockup_secs(stake_pool) >= proposal_expiration, - error::invalid_argument(EINSUFFICIENT_STAKE_LOCKUP), - ); - // Create and validate proposal metadata. - let proposal_metadata = create_proposal_metadata(metadata_location, metadata_hash); +
+Implementation - // We want to allow early resolution of proposals if more than 50% of the total supply of the network coins - // has voted. This doesn't take into subsequent inflation/deflation (rewards are issued every epoch and gas fees - // are burnt after every transaction), but inflation/delation is very unlikely to have a major impact on total - // supply during the voting period. - let total_voting_token_supply = coin::supply<SupraCoin>(); - let early_resolution_vote_threshold = option::none<u128>(); - if (option::is_some(&total_voting_token_supply)) { - let total_supply = *option::borrow(&total_voting_token_supply); - // 50% + 1 to avoid rounding errors. - early_resolution_vote_threshold = option::some(total_supply / 2 + 1); - }; - let proposal_id = voting::create_proposal_v2( - proposer_address, - @supra_framework, - governance_proposal::create_proposal(), - execution_hash, - governance_config.min_voting_threshold, - proposal_expiration, - early_resolution_vote_threshold, - proposal_metadata, - is_multi_step_proposal, - ); +
public fun store_signer_cap(
+    supra_framework: &signer,
+    signer_address: address,
+    signer_cap: SignerCapability,
+) acquires GovernanceResponsbility {
+    system_addresses::assert_supra_framework(supra_framework);
+    system_addresses::assert_framework_reserved(signer_address);
 
-    if (std::features::module_event_migration_enabled()) {
-        event::emit(
-            CreateProposal {
-                proposal_id,
-                proposer: proposer_address,
-                stake_pool,
-                execution_hash,
-                proposal_metadata,
-            },
+    if (!exists<GovernanceResponsbility>(@supra_framework)) {
+        move_to(
+            supra_framework,
+            GovernanceResponsbility { signer_caps: simple_map::create<address, SignerCapability>() }
         );
     };
-    let events = borrow_global_mut<GovernanceEvents>(@supra_framework);
-    event::emit_event<CreateProposalEvent>(
-        &mut events.create_proposal_events,
-        CreateProposalEvent {
-            proposal_id,
-            proposer: proposer_address,
-            stake_pool,
-            execution_hash,
-            proposal_metadata,
-        },
-    );
-    proposal_id
+
+    let signer_caps = &mut borrow_global_mut<GovernanceResponsbility>(@supra_framework).signer_caps;
+    simple_map::add(signer_caps, signer_address, signer_cap);
 }
 
@@ -1804,16 +631,16 @@ Return proposal_id when a proposal is successfully created.
- + -## Function `supra_create_proposal` +## Function `initialize` -Create a single-step proposal with the backing stake_pool. -@param execution_hash Required. This is the hash of the resolution script. When the proposal is resolved, -only the exact script with matching hash can be successfully executed. +Initializes the state for Aptos Governance. Can only be called during Genesis with a signer +for the supra_framework (0x1) account. +This function is private because it's called directly from the vm. -
public entry fun supra_create_proposal(proposer: &signer, execution_hash: vector<u8>, metadata_location: vector<u8>, metadata_hash: vector<u8>)
+
fun initialize(supra_framework: &signer, voting_duration_secs: u64, min_voting_threshold: u64, voters: vector<address>)
 
@@ -1822,13 +649,30 @@ only the exact script with matching hash can be successfully executed. Implementation -
public entry fun supra_create_proposal(
-    proposer: &signer,
-    execution_hash: vector<u8>,
-    metadata_location: vector<u8>,
-    metadata_hash: vector<u8>,
-) acquires SupraGovernanceConfig, SupraGovernanceEvents {
-    supra_create_proposal_v2(proposer, execution_hash, metadata_location, metadata_hash, false);
+
fun initialize(
+    supra_framework: &signer,
+    voting_duration_secs: u64,
+    min_voting_threshold: u64,
+    voters: vector<address>,
+) {
+    multisig_voting::register<GovernanceProposal>(supra_framework);
+
+    assert!(vector::length(&voters) >= min_voting_threshold && min_voting_threshold > vector::length(&voters) / 2, error::invalid_argument(ETHRESHOLD_EXCEEDS_VOTERS));
+    assert!(min_voting_threshold > 1, error::invalid_argument(ETHRESHOLD_MUST_BE_GREATER_THAN_ONE));
+
+    move_to(supra_framework, SupraGovernanceConfig {
+        voting_duration_secs,
+        min_voting_threshold,
+        voters,
+    });
+    move_to(supra_framework, SupraGovernanceEvents {
+        create_proposal_events: account::new_event_handle<SupraCreateProposalEvent>(supra_framework),
+        update_config_events: account::new_event_handle<SupraUpdateConfigEvent>(supra_framework),
+        vote_events: account::new_event_handle<SupraVoteEvent>(supra_framework),
+    });
+    move_to(supra_framework, ApprovedExecutionHashes {
+        hashes: simple_map::create<u64, vector<u8>>(),
+    })
 }
 
@@ -1836,16 +680,15 @@ only the exact script with matching hash can be successfully executed.
- + -## Function `supra_create_proposal_v2` +## Function `update_supra_governance_config` -Create a single-step or multi-step proposal with the backing stake_pool. -@param execution_hash Required. This is the hash of the resolution script. When the proposal is resolved, -only the exact script with matching hash can be successfully executed. +Update the governance configurations. This can only be called as part of resolving a proposal in this same +AptosGovernance. -
public entry fun supra_create_proposal_v2(proposer: &signer, execution_hash: vector<u8>, metadata_location: vector<u8>, metadata_hash: vector<u8>, is_multi_step_proposal: bool)
+
public fun update_supra_governance_config(supra_framework: &signer, voting_duration_secs: u64, min_voting_threshold: u64, voters: vector<address>)
 
@@ -1854,19 +697,39 @@ only the exact script with matching hash can be successfully executed. Implementation -
public entry fun supra_create_proposal_v2(
-    proposer: &signer,
-    execution_hash: vector<u8>,
-    metadata_location: vector<u8>,
-    metadata_hash: vector<u8>,
-    is_multi_step_proposal: bool,
+
public fun update_supra_governance_config(
+    supra_framework: &signer,
+    voting_duration_secs: u64,
+    min_voting_threshold: u64,
+    voters: vector<address>,
 ) acquires SupraGovernanceConfig, SupraGovernanceEvents {
-    supra_create_proposal_v2_impl(
-        proposer,
-        execution_hash,
-        metadata_location,
-        metadata_hash,
-        is_multi_step_proposal
+    system_addresses::assert_supra_framework(supra_framework);
+
+    assert!(vector::length(&voters) >= min_voting_threshold && min_voting_threshold > vector::length(&voters) / 2, error::invalid_argument(ETHRESHOLD_EXCEEDS_VOTERS));
+    assert!(min_voting_threshold > 1, error::invalid_argument(ETHRESHOLD_MUST_BE_GREATER_THAN_ONE));
+
+    let supra_governance_config = borrow_global_mut<SupraGovernanceConfig>(@supra_framework);
+    supra_governance_config.voting_duration_secs = voting_duration_secs;
+    supra_governance_config.min_voting_threshold = min_voting_threshold;
+    supra_governance_config.voters = voters;
+
+    if (std::features::module_event_migration_enabled()) {
+        event::emit(
+            SupraUpdateConfig {
+                min_voting_threshold,
+                voting_duration_secs,
+                voters,
+            },
+        )
+    };
+    let events = borrow_global_mut<SupraGovernanceEvents>(@supra_framework);
+    event::emit_event<SupraUpdateConfigEvent>(
+        &mut events.update_config_events,
+        SupraUpdateConfigEvent {
+            min_voting_threshold,
+            voting_duration_secs,
+            voters,
+        },
     );
 }
 
@@ -1875,17 +738,14 @@ only the exact script with matching hash can be successfully executed. - + -## Function `supra_create_proposal_v2_impl` +## Function `get_voting_duration_secs` -Create a single-step or multi-step proposal with the backing stake_pool. -@param execution_hash Required. This is the hash of the resolution script. When the proposal is resolved, -only the exact script with matching hash can be successfully executed. -Return proposal_id when a proposal is successfully created. -
public fun supra_create_proposal_v2_impl(proposer: &signer, execution_hash: vector<u8>, metadata_location: vector<u8>, metadata_hash: vector<u8>, is_multi_step_proposal: bool): u64
+
#[view]
+public fun get_voting_duration_secs(): u64
 
@@ -1894,56 +754,8 @@ Return proposal_id when a proposal is successfully created. Implementation -
public fun supra_create_proposal_v2_impl(
-    proposer: &signer,
-    execution_hash: vector<u8>,
-    metadata_location: vector<u8>,
-    metadata_hash: vector<u8>,
-    is_multi_step_proposal: bool,
-): u64 acquires SupraGovernanceConfig, SupraGovernanceEvents {
-    let proposer_address = signer::address_of(proposer);
-    let supra_governance_config = borrow_global<SupraGovernanceConfig>(@supra_framework);
-
-    assert!(vector::contains(&supra_governance_config.voters, &proposer_address), error::permission_denied(EACCOUNT_NOT_AUTHORIZED));
-
-    let proposal_expiration = timestamp::now_seconds() + supra_governance_config.voting_duration_secs;
-
-    // Create and validate proposal metadata.
-    let proposal_metadata = create_proposal_metadata(metadata_location, metadata_hash);
-
-    let proposal_id = multisig_voting::create_proposal_v2(
-        proposer_address,
-        @supra_framework,
-        governance_proposal::create_proposal(),
-        execution_hash,
-        supra_governance_config.min_voting_threshold,
-        supra_governance_config.voters,
-        proposal_expiration,
-        proposal_metadata,
-        is_multi_step_proposal,
-    );
-
-    if (std::features::module_event_migration_enabled()) {
-        event::emit(
-            SupraCreateProposal {
-                proposal_id,
-                proposer: proposer_address,
-                execution_hash,
-                proposal_metadata,
-            },
-        );
-    };
-    let events = borrow_global_mut<SupraGovernanceEvents>(@supra_framework);
-    event::emit_event<SupraCreateProposalEvent>(
-        &mut events.create_proposal_events,
-        SupraCreateProposalEvent {
-            proposal_id,
-            proposer: proposer_address,
-            execution_hash,
-            proposal_metadata,
-        },
-    );
-    proposal_id
+
public fun get_voting_duration_secs(): u64 acquires SupraGovernanceConfig {
+    borrow_global<SupraGovernanceConfig>(@supra_framework).voting_duration_secs
 }
 
@@ -1951,14 +763,14 @@ Return proposal_id when a proposal is successfully created. - + -## Function `batch_vote` +## Function `get_min_voting_threshold` -Vote on proposal with proposal_id and all voting power from multiple stake_pools. -
public entry fun batch_vote(voter: &signer, stake_pools: vector<address>, proposal_id: u64, should_pass: bool)
+
#[view]
+public fun get_min_voting_threshold(): u64
 
@@ -1967,15 +779,8 @@ Vote on proposal with proposal_id and all voting power from multiple stake_pools Implementation -
public entry fun batch_vote(
-    voter: &signer,
-    stake_pools: vector<address>,
-    proposal_id: u64,
-    should_pass: bool,
-) acquires ApprovedExecutionHashes, VotingRecords, VotingRecordsV2, GovernanceEvents {
-    vector::for_each(stake_pools, |stake_pool| {
-        vote_internal(voter, stake_pool, proposal_id, MAX_U64, should_pass);
-    });
+
public fun get_min_voting_threshold(): u64 acquires SupraGovernanceConfig {
+    borrow_global<SupraGovernanceConfig>(@supra_framework).min_voting_threshold
 }
 
@@ -1983,14 +788,14 @@ Vote on proposal with proposal_id and all voting power from multiple stake_pools - + -## Function `batch_partial_vote` +## Function `get_voters_list` -Batch vote on proposal with proposal_id and specified voting power from multiple stake_pools. -
public entry fun batch_partial_vote(voter: &signer, stake_pools: vector<address>, proposal_id: u64, voting_power: u64, should_pass: bool)
+
#[view]
+public fun get_voters_list(): vector<address>
 
@@ -1999,16 +804,8 @@ Batch vote on proposal with proposal_id and specified voting power from multiple Implementation -
public entry fun batch_partial_vote(
-    voter: &signer,
-    stake_pools: vector<address>,
-    proposal_id: u64,
-    voting_power: u64,
-    should_pass: bool,
-) acquires ApprovedExecutionHashes, VotingRecords, VotingRecordsV2, GovernanceEvents {
-    vector::for_each(stake_pools, |stake_pool| {
-        vote_internal(voter, stake_pool, proposal_id, voting_power, should_pass);
-    });
+
public fun get_voters_list(): vector<address> acquires SupraGovernanceConfig {
+    borrow_global<SupraGovernanceConfig>(@supra_framework).voters
 }
 
@@ -2016,14 +813,16 @@ Batch vote on proposal with proposal_id and specified voting power from multiple - + -## Function `vote` +## Function `supra_create_proposal` -Vote on proposal with proposal_id and all voting power from stake_pool. +Create a single-step proposal with the backing stake_pool. +@param execution_hash Required. This is the hash of the resolution script. When the proposal is resolved, +only the exact script with matching hash can be successfully executed. -
public entry fun vote(voter: &signer, stake_pool: address, proposal_id: u64, should_pass: bool)
+
public entry fun supra_create_proposal(proposer: &signer, execution_hash: vector<u8>, metadata_location: vector<u8>, metadata_hash: vector<u8>)
 
@@ -2032,13 +831,13 @@ Vote on proposal with proposal_id and all voting power from s Implementation -
public entry fun vote(
-    voter: &signer,
-    stake_pool: address,
-    proposal_id: u64,
-    should_pass: bool,
-) acquires ApprovedExecutionHashes, VotingRecords, VotingRecordsV2, GovernanceEvents {
-    vote_internal(voter, stake_pool, proposal_id, MAX_U64, should_pass);
+
public entry fun supra_create_proposal(
+    proposer: &signer,
+    execution_hash: vector<u8>,
+    metadata_location: vector<u8>,
+    metadata_hash: vector<u8>,
+) acquires SupraGovernanceConfig, SupraGovernanceEvents {
+    supra_create_proposal_v2(proposer, execution_hash, metadata_location, metadata_hash, false);
 }
 
@@ -2046,14 +845,16 @@ Vote on proposal with proposal_id and all voting power from s - + -## Function `partial_vote` +## Function `supra_create_proposal_v2` -Vote on proposal with proposal_id and specified voting power from stake_pool. +Create a single-step or multi-step proposal with the backing stake_pool. +@param execution_hash Required. This is the hash of the resolution script. When the proposal is resolved, +only the exact script with matching hash can be successfully executed. -
public entry fun partial_vote(voter: &signer, stake_pool: address, proposal_id: u64, voting_power: u64, should_pass: bool)
+
public entry fun supra_create_proposal_v2(proposer: &signer, execution_hash: vector<u8>, metadata_location: vector<u8>, metadata_hash: vector<u8>, is_multi_step_proposal: bool)
 
@@ -2062,14 +863,20 @@ Vote on proposal with proposal_id and specified voting power from < Implementation -
public entry fun partial_vote(
-    voter: &signer,
-    stake_pool: address,
-    proposal_id: u64,
-    voting_power: u64,
-    should_pass: bool,
-) acquires ApprovedExecutionHashes, VotingRecords, VotingRecordsV2, GovernanceEvents {
-    vote_internal(voter, stake_pool, proposal_id, voting_power, should_pass);
+
public entry fun supra_create_proposal_v2(
+    proposer: &signer,
+    execution_hash: vector<u8>,
+    metadata_location: vector<u8>,
+    metadata_hash: vector<u8>,
+    is_multi_step_proposal: bool,
+) acquires SupraGovernanceConfig, SupraGovernanceEvents {
+    supra_create_proposal_v2_impl(
+        proposer,
+        execution_hash,
+        metadata_location,
+        metadata_hash,
+        is_multi_step_proposal
+    );
 }
 
@@ -2077,17 +884,17 @@ Vote on proposal with proposal_id and specified voting power from < - + -## Function `vote_internal` +## Function `supra_create_proposal_v2_impl` -Vote on proposal with proposal_id and specified voting_power from stake_pool. -If voting_power is more than all the left voting power of stake_pool, use all the left voting power. -If a stake pool has already voted on a proposal before partial governance voting is enabled, the stake pool -cannot vote on the proposal even after partial governance voting is enabled. +Create a single-step or multi-step proposal with the backing stake_pool. +@param execution_hash Required. This is the hash of the resolution script. When the proposal is resolved, +only the exact script with matching hash can be successfully executed. +Return proposal_id when a proposal is successfully created. -
fun vote_internal(voter: &signer, stake_pool: address, proposal_id: u64, voting_power: u64, should_pass: bool)
+
public fun supra_create_proposal_v2_impl(proposer: &signer, execution_hash: vector<u8>, metadata_location: vector<u8>, metadata_hash: vector<u8>, is_multi_step_proposal: bool): u64
 
@@ -2096,86 +903,56 @@ cannot vote on the proposal even after partial governance voting is enabled. Implementation -
fun vote_internal(
-    voter: &signer,
-    stake_pool: address,
-    proposal_id: u64,
-    voting_power: u64,
-    should_pass: bool,
-) acquires ApprovedExecutionHashes, VotingRecords, VotingRecordsV2, GovernanceEvents {
-    let voter_address = signer::address_of(voter);
-    assert!(stake::get_delegated_voter(stake_pool) == voter_address, error::invalid_argument(ENOT_DELEGATED_VOTER));
+
public fun supra_create_proposal_v2_impl(
+    proposer: &signer,
+    execution_hash: vector<u8>,
+    metadata_location: vector<u8>,
+    metadata_hash: vector<u8>,
+    is_multi_step_proposal: bool,
+): u64 acquires SupraGovernanceConfig, SupraGovernanceEvents {
+    let proposer_address = signer::address_of(proposer);
+    let supra_governance_config = borrow_global<SupraGovernanceConfig>(@supra_framework);
 
-    // The voter's stake needs to be locked up at least as long as the proposal's expiration.
-    let proposal_expiration = voting::get_proposal_expiration_secs<GovernanceProposal>(
-        @supra_framework,
-        proposal_id
-    );
-    assert!(
-        stake::get_lockup_secs(stake_pool) >= proposal_expiration,
-        error::invalid_argument(EINSUFFICIENT_STAKE_LOCKUP),
-    );
+    assert!(vector::contains(&supra_governance_config.voters, &proposer_address), error::permission_denied(EACCOUNT_NOT_AUTHORIZED));
 
-    // If a stake pool has already voted on a proposal before partial governance voting is enabled,
-    // `get_remaining_voting_power` returns 0.
-    let staking_pool_voting_power = get_remaining_voting_power(stake_pool, proposal_id);
-    voting_power = min(voting_power, staking_pool_voting_power);
+    let proposal_expiration = timestamp::now_seconds() + supra_governance_config.voting_duration_secs;
 
-    // Short-circuit if the voter has no voting power.
-    assert!(voting_power > 0, error::invalid_argument(ENO_VOTING_POWER));
+    // Create and validate proposal metadata.
+    let proposal_metadata = create_proposal_metadata(metadata_location, metadata_hash);
 
-    voting::vote<GovernanceProposal>(
-        &governance_proposal::create_empty_proposal(),
+    let proposal_id = multisig_voting::create_proposal_v2(
+        proposer_address,
         @supra_framework,
-        proposal_id,
-        voting_power,
-        should_pass,
+        governance_proposal::create_proposal(),
+        execution_hash,
+        supra_governance_config.min_voting_threshold,
+        supra_governance_config.voters,
+        proposal_expiration,
+        proposal_metadata,
+        is_multi_step_proposal,
     );
 
-    let record_key = RecordKey {
-        stake_pool,
-        proposal_id,
-    };
-    if (features::partial_governance_voting_enabled()) {
-        let voting_records_v2 = borrow_global_mut<VotingRecordsV2>(@supra_framework);
-        let used_voting_power = smart_table::borrow_mut_with_default(&mut voting_records_v2.votes, record_key, 0);
-        // This calculation should never overflow because the used voting cannot exceed the total voting power of this stake pool.
-        *used_voting_power = *used_voting_power + voting_power;
-    } else {
-        let voting_records = borrow_global_mut<VotingRecords>(@supra_framework);
-        assert!(
-            !table::contains(&voting_records.votes, record_key),
-            error::invalid_argument(EALREADY_VOTED));
-        table::add(&mut voting_records.votes, record_key, true);
-    };
-
     if (std::features::module_event_migration_enabled()) {
         event::emit(
-            Vote {
+            SupraCreateProposal {
                 proposal_id,
-                voter: voter_address,
-                stake_pool,
-                num_votes: voting_power,
-                should_pass,
+                proposer: proposer_address,
+                execution_hash,
+                proposal_metadata,
             },
         );
     };
-    let events = borrow_global_mut<GovernanceEvents>(@supra_framework);
-    event::emit_event<VoteEvent>(
-        &mut events.vote_events,
-        VoteEvent {
+    let events = borrow_global_mut<SupraGovernanceEvents>(@supra_framework);
+    event::emit_event<SupraCreateProposalEvent>(
+        &mut events.create_proposal_events,
+        SupraCreateProposalEvent {
             proposal_id,
-            voter: voter_address,
-            stake_pool,
-            num_votes: voting_power,
-            should_pass,
+            proposer: proposer_address,
+            execution_hash,
+            proposal_metadata,
         },
     );
-
-    let proposal_state = voting::get_proposal_state<GovernanceProposal>(@supra_framework, proposal_id);
-    if (proposal_state == PROPOSAL_STATE_SUCCEEDED) {
-        add_approved_script_hash(proposal_id);
-    }
+    proposal_id
 }
 
@@ -2246,7 +1023,7 @@ cannot vote on the proposal even after partial governance voting is enabled. @supra_framework, proposal_id ); - assert!(timestamp::now_seconds() >= proposal_expiration, error::invalid_argument(EPROPOSAL_IS_EXPIRE)); + assert!(timestamp::now_seconds() <= proposal_expiration, error::invalid_argument(EPROPOSAL_IS_EXPIRE)); multisig_voting::vote<GovernanceProposal>( voter, @@ -2284,30 +1061,6 @@ cannot vote on the proposal even after partial governance voting is enabled. - - - - -## Function `add_approved_script_hash_script` - - - -
public entry fun add_approved_script_hash_script(proposal_id: u64)
-
- - - -
-Implementation - - -
public entry fun add_approved_script_hash_script(proposal_id: u64) acquires ApprovedExecutionHashes {
-    add_approved_script_hash(proposal_id)
-}
-
- - -
@@ -2332,48 +1085,6 @@ cannot vote on the proposal even after partial governance voting is enabled. - - - - -## Function `add_approved_script_hash` - -Add the execution script hash of a successful governance proposal to the approved list. -This is needed to bypass the mempool transaction size limit for approved governance proposal transactions that -are too large (e.g. module upgrades). - - -
public fun add_approved_script_hash(proposal_id: u64)
-
- - - -
-Implementation - - -
public fun add_approved_script_hash(proposal_id: u64) acquires ApprovedExecutionHashes {
-    let approved_hashes = borrow_global_mut<ApprovedExecutionHashes>(@supra_framework);
-
-    // Ensure the proposal can be resolved.
-    let proposal_state = voting::get_proposal_state<GovernanceProposal>(@supra_framework, proposal_id);
-    assert!(proposal_state == PROPOSAL_STATE_SUCCEEDED, error::invalid_argument(EPROPOSAL_NOT_RESOLVABLE_YET));
-
-    let execution_hash = voting::get_execution_hash<GovernanceProposal>(@supra_framework, proposal_id);
-
-    // If this is a multi-step proposal, the proposal id will already exist in the ApprovedExecutionHashes map.
-    // We will update execution hash in ApprovedExecutionHashes to be the next_execution_hash.
-    if (simple_map::contains_key(&approved_hashes.hashes, &proposal_id)) {
-        let current_execution_hash = simple_map::borrow_mut(&mut approved_hashes.hashes, &proposal_id);
-        *current_execution_hash = execution_hash;
-    } else {
-        simple_map::add(&mut approved_hashes.hashes, proposal_id, execution_hash);
-    }
-}
-
- - -
@@ -2416,37 +1127,6 @@ are too large (e.g. module upgrades). - - - - -## Function `resolve` - -Resolve a successful single-step proposal. This would fail if the proposal is not successful (not enough votes or more no -than yes). - - -
public fun resolve(proposal_id: u64, signer_address: address): signer
-
- - - -
-Implementation - - -
public fun resolve(
-    proposal_id: u64,
-    signer_address: address
-): signer acquires ApprovedExecutionHashes, GovernanceResponsbility {
-    voting::resolve<GovernanceProposal>(@supra_framework, proposal_id);
-    remove_approved_hash(proposal_id);
-    get_signer(signer_address)
-}
-
- - -
@@ -2478,46 +1158,6 @@ than yes). - - - - -## Function `resolve_multi_step_proposal` - -Resolve a successful multi-step proposal. This would fail if the proposal is not successful. - - -
public fun resolve_multi_step_proposal(proposal_id: u64, signer_address: address, next_execution_hash: vector<u8>): signer
-
- - - -
-Implementation - - -
public fun resolve_multi_step_proposal(
-    proposal_id: u64,
-    signer_address: address,
-    next_execution_hash: vector<u8>
-): signer acquires GovernanceResponsbility, ApprovedExecutionHashes {
-    voting::resolve_proposal_v2<GovernanceProposal>(@supra_framework, proposal_id, next_execution_hash);
-    // If the current step is the last step of this multi-step proposal,
-    // we will remove the execution hash from the ApprovedExecutionHashes map.
-    if (vector::length(&next_execution_hash) == 0) {
-        remove_approved_hash(proposal_id);
-    } else {
-        // If the current step is not the last step of this proposal,
-        // we replace the current execution hash with the next execution hash
-        // in the ApprovedExecutionHashes map.
-        add_approved_script_hash(proposal_id)
-    };
-    get_signer(signer_address)
-}
-
- - -
@@ -2558,39 +1198,6 @@ Resolve a successful multi-step proposal. This would fail if the proposal is not - - - - -## Function `remove_approved_hash` - -Remove an approved proposal's execution script hash. - - -
public fun remove_approved_hash(proposal_id: u64)
-
- - - -
-Implementation - - -
public fun remove_approved_hash(proposal_id: u64) acquires ApprovedExecutionHashes {
-    assert!(
-        voting::is_resolved<GovernanceProposal>(@supra_framework, proposal_id),
-        error::invalid_argument(EPROPOSAL_NOT_RESOLVED_YET),
-    );
-
-    let approved_hashes = &mut borrow_global_mut<ApprovedExecutionHashes>(@supra_framework).hashes;
-    if (simple_map::contains_key(approved_hashes, &proposal_id)) {
-        simple_map::remove(approved_hashes, &proposal_id);
-    };
-}
-
- - -
@@ -2777,41 +1384,6 @@ Only called in testnet where the core resources account exists and has been gran - - - - -## Function `get_voting_power` - -Return the voting power a stake pool has with respect to governance proposals. - - -
#[view]
-public fun get_voting_power(pool_address: address): u64
-
- - - -
-Implementation - - -
public fun get_voting_power(pool_address: address): u64 {
-    let allow_validator_set_change = staking_config::get_allow_validator_set_change(&staking_config::get());
-    if (allow_validator_set_change) {
-        let (active, _, pending_active, pending_inactive) = stake::get_stake(pool_address);
-        // We calculate the voting power as total non-inactive stakes of the pool. Even if the validator is not in the
-        // active validator set, as long as they have a lockup (separately checked in create_proposal and voting), their
-        // stake would still count in their voting power for governance proposals.
-        active + pending_active + pending_inactive
-    } else {
-        stake::get_current_epoch_voting_power(pool_address)
-    }
-}
-
- - -
@@ -2872,32 +1444,6 @@ Return a signer for making changes to 0x1 as part of on-chain governance proposa - - - - -## Function `assert_voting_initialization` - - - -
fun assert_voting_initialization()
-
- - - -
-Implementation - - -
fun assert_voting_initialization() {
-    if (features::partial_governance_voting_enabled()) {
-        assert!(exists<VotingRecordsV2>(@supra_framework), error::invalid_state(EPARTIAL_VOTING_NOT_INITIALIZED));
-    };
-}
-
- - -
@@ -2922,7 +1468,6 @@ Return a signer for making changes to 0x1 as part of on-chain governance proposa supra_min_voting_threshold: u64, voters: vector<address>, ) { - // old_initialize(supra_framework, min_voting_threshold, required_proposer_stake, voting_duration_secs); initialize(supra_framework, voting_duration_secs, supra_min_voting_threshold, voters); }
diff --git a/aptos-move/framework/supra-framework/doc/voting.md b/aptos-move/framework/supra-framework/doc/voting.md index 86cce9af9077a..40b720abe28fa 100644 --- a/aptos-move/framework/supra-framework/doc/voting.md +++ b/aptos-move/framework/supra-framework/doc/voting.md @@ -600,16 +600,6 @@ Extra metadata (e.g. description, code url) can be part of the ProposalType stru ## Constants - - -Minimum vote threshold cannot be higher than early resolution threshold. - - -
const EINVALID_MIN_VOTE_THRESHOLD: u64 = 7;
-
- - - If a proposal is multi-step, we need to use resolve_proposal_v2() to resolve it. @@ -780,6 +770,16 @@ Key used to track the resolvable time in the proposal's metadata. + + +Minimum vote threshold cannot be higher than early resolution threshold. + + +
const EINVALID_MIN_VOTE_THRESHOLD: u64 = 7;
+
+ + + ## Function `register` diff --git a/aptos-move/framework/supra-framework/sources/account.move b/aptos-move/framework/supra-framework/sources/account.move index a1f24b4aeb89e..8960161fe513c 100644 --- a/aptos-move/framework/supra-framework/sources/account.move +++ b/aptos-move/framework/supra-framework/sources/account.move @@ -986,6 +986,14 @@ module supra_framework::account { // Test-only sequence number mocking for extant Account resource /////////////////////////////////////////////////////////////////////////// + #[test_only] + /// Increment sequence number of account at address `addr` + public fun increment_sequence_number_for_test_using_source_code( + addr: address, + ) acquires Account { + increment_sequence_number(addr); + } + #[test_only] /// Increment sequence number of account at address `addr` public fun increment_sequence_number_for_test( @@ -1037,6 +1045,22 @@ module supra_framework::account { assert!(borrow_global(addr).sequence_number == 10, 2); } + #[test] + /// Verify source-code sequence number mocking + public entry fun mock_sequence_numbers_source_code() + acquires Account { + let addr: address = @0x1234; // Define test address + create_account(addr); // Initialize account resource + // Assert sequence number intializes to 0 + assert!(borrow_global(addr).sequence_number == 0, 0); + increment_sequence_number_for_test_using_source_code(addr); // Increment sequence number + // Assert correct mock value post-increment + assert!(borrow_global(addr).sequence_number == 1, 1); + set_sequence_number(addr, 10); // Set mock sequence number + // Assert correct mock value post-modification + assert!(borrow_global(addr).sequence_number == 10, 2); + } + /////////////////////////////////////////////////////////////////////////// // Test account helpers /////////////////////////////////////////////////////////////////////////// @@ -1050,6 +1074,28 @@ module supra_framework::account { rotate_authentication_key(&alice, ED25519_SCHEME, pk, ED25519_SCHEME, pk, sig, sig); } + #[test(alice_address = @0xa11ce)] + #[expected_failure(abort_code = 524289, location = supra_framework::account)] + public entry fun test_create_account_twice_should_fail(alice_address: address) { + create_account_if_does_not_exist(alice_address); + create_account(alice_address); + } + + #[test(alice_address = @0xa11ce)] + #[expected_failure(abort_code = 65541, location = supra_framework::account)] + public entry fun test_create_account_with_core_resource_address_should_fail(alice_address: address) { + create_account(alice_address); + create_account(@supra_framework); + create_account(@aptos_token); + create_account(@vm_reserved); + } + + #[test(alice_address = @0xa11ce)] + #[expected_failure(abort_code = 327691, location = supra_framework::account)] + public entry fun test_create_framework_reserved_account_with_core_resource_address_should_fail(alice_address: address) { + create_framework_reserved_account(alice_address); + } + #[test(alice = @0xa11ce)] #[expected_failure(abort_code = 262151, location = Self)] public entry fun test_empty_signature(alice: signer) acquires Account, OriginatingAddress { diff --git a/aptos-move/framework/supra-framework/sources/aggregator_v2/aggregator_v2.move b/aptos-move/framework/supra-framework/sources/aggregator_v2/aggregator_v2.move index 931ad06a649e3..6b8ce7fd9a89e 100644 --- a/aptos-move/framework/supra-framework/sources/aggregator_v2/aggregator_v2.move +++ b/aptos-move/framework/supra-framework/sources/aggregator_v2/aggregator_v2.move @@ -228,6 +228,42 @@ module supra_framework::aggregator_v2 { assert!(read_snapshot(&snap) == 5, 10); } + #[test] + fun test_aggregator_with_value() { + let agg = create_aggregator_with_value(0, 10); + assert!(try_add(&mut agg, 5), 1); + assert!(try_add(&mut agg, 5), 2); + assert!(read(&agg) == 10, 3); + } + + #[test] + fun test_create_unbounded_aggregator_with_value() { + let agg = create_unbounded_aggregator_with_value(0); + assert!(try_add(&mut agg, 5), 1); + assert!(try_add(&mut agg, 5), 2); + assert!(read(&agg) == 10, 3); + assert!(try_add(&mut agg, 5), 4); + assert!(read(&agg) == 15, 5); + add(&mut agg, 5); + sub(&mut agg, 5); + } + + #[test] + #[expected_failure(abort_code = 131073, location = Self)] + fun test_aggregator_overflow() { + let agg = create_aggregator(10); + add(&mut agg, 5); + add(&mut agg, 6); + } + + #[test] + #[expected_failure(abort_code = 131074, location = Self)] + fun test_aggregator_underflow() { + let agg = create_aggregator(10); + sub(&mut agg, 5); + sub(&mut agg, 6); + } + #[test] fun test_correct_read() { let snapshot = create_snapshot(42); diff --git a/aptos-move/framework/supra-framework/sources/delegation_pool.move b/aptos-move/framework/supra-framework/sources/delegation_pool.move index b2bdf7a2d9257..3fe53b1ede574 100644 --- a/aptos-move/framework/supra-framework/sources/delegation_pool.move +++ b/aptos-move/framework/supra-framework/sources/delegation_pool.move @@ -121,7 +121,6 @@ module supra_framework::delegation_pool { use supra_framework::account; use supra_framework::supra_account; use supra_framework::supra_coin::SupraCoin; - use supra_framework::supra_governance; use supra_framework::coin; use supra_framework::event::{Self, EventHandle, emit}; use supra_framework::stake; @@ -732,26 +731,6 @@ module supra_framework::delegation_pool { calculate_total_voting_power(pool, latest_delegated_votes) } - #[view] - /// Return the remaining voting power of a delegator in a delegation pool on a proposal. This function syncs DelegationPool to the - /// latest state. - public fun calculate_and_update_remaining_voting_power( - pool_address: address, - voter_address: address, - proposal_id: u64 - ): u64 acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { - assert_partial_governance_voting_enabled(pool_address); - // If the whole stake pool has no voting power(e.g. it has already voted before partial - // governance voting flag is enabled), the delegator also has no voting power. - if (supra_governance::get_remaining_voting_power(pool_address, proposal_id) == 0) { - return 0 - }; - - let total_voting_power = calculate_and_update_voter_total_voting_power(pool_address, voter_address); - let governance_records = borrow_global(pool_address); - total_voting_power - get_used_voting_power(governance_records, voter_address, proposal_id) - } - #[view] /// Return the latest delegated voter of a delegator in a delegation pool. This function syncs DelegationPool to the /// latest state. @@ -929,121 +908,6 @@ module supra_framework::delegation_pool { }); } - /// Vote on a proposal with a voter's voting power. To successfully vote, the following conditions must be met: - /// 1. The voting period of the proposal hasn't ended. - /// 2. The delegation pool's lockup period ends after the voting period of the proposal. - /// 3. The voter still has spare voting power on this proposal. - /// 4. The delegation pool never votes on the proposal before enabling partial governance voting. - public entry fun vote( - voter: &signer, - pool_address: address, - proposal_id: u64, - voting_power: u64, - should_pass: bool - ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { - assert_partial_governance_voting_enabled(pool_address); - // synchronize delegation and stake pools before any user operation. - synchronize_delegation_pool(pool_address); - - let voter_address = signer::address_of(voter); - let remaining_voting_power = calculate_and_update_remaining_voting_power( - pool_address, - voter_address, - proposal_id - ); - if (voting_power > remaining_voting_power) { - voting_power = remaining_voting_power; - }; - assert!(voting_power > 0, error::invalid_argument(ENO_VOTING_POWER)); - - let governance_records = borrow_global_mut(pool_address); - // Check a edge case during the transient period of enabling partial governance voting. - assert_and_update_proposal_used_voting_power(governance_records, pool_address, proposal_id, voting_power); - let used_voting_power = borrow_mut_used_voting_power(governance_records, voter_address, proposal_id); - *used_voting_power = *used_voting_power + voting_power; - - let pool_signer = retrieve_stake_pool_owner(borrow_global(pool_address)); - supra_governance::partial_vote(&pool_signer, pool_address, proposal_id, voting_power, should_pass); - - if (features::module_event_migration_enabled()) { - event::emit( - Vote { - voter: voter_address, - proposal_id, - delegation_pool: pool_address, - num_votes: voting_power, - should_pass, - } - ); - }; - - event::emit_event( - &mut governance_records.vote_events, - VoteEvent { - voter: voter_address, - proposal_id, - delegation_pool: pool_address, - num_votes: voting_power, - should_pass, - } - ); - } - - /// A voter could create a governance proposal by this function. To successfully create a proposal, the voter's - /// voting power in THIS delegation pool must be not less than the minimum required voting power specified in - /// `supra_governance.move`. - public entry fun create_proposal( - voter: &signer, - pool_address: address, - execution_hash: vector, - metadata_location: vector, - metadata_hash: vector, - is_multi_step_proposal: bool, - ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { - assert_partial_governance_voting_enabled(pool_address); - - // synchronize delegation and stake pools before any user operation - synchronize_delegation_pool(pool_address); - - let voter_addr = signer::address_of(voter); - let pool = borrow_global(pool_address); - let governance_records = borrow_global_mut(pool_address); - let total_voting_power = calculate_and_update_delegated_votes(pool, governance_records, voter_addr); - assert!( - total_voting_power >= supra_governance::get_required_proposer_stake(), - error::invalid_argument(EINSUFFICIENT_PROPOSER_STAKE)); - let pool_signer = retrieve_stake_pool_owner(borrow_global(pool_address)); - let proposal_id = supra_governance::create_proposal_v2_impl( - &pool_signer, - pool_address, - execution_hash, - metadata_location, - metadata_hash, - is_multi_step_proposal, - ); - - let governance_records = borrow_global_mut(pool_address); - - if (features::module_event_migration_enabled()) { - event::emit( - CreateProposal { - proposal_id, - voter: voter_addr, - delegation_pool: pool_address, - } - ); - }; - - event::emit_event( - &mut governance_records.create_proposal_events, - CreateProposalEvent { - proposal_id, - voter: voter_addr, - delegation_pool: pool_address, - } - ); - } - fun assert_owner_cap_exists(owner: address) { assert!(owner_cap_exists(owner), error::not_found(EOWNER_CAP_NOT_FOUND)); } @@ -2107,29 +1971,6 @@ module supra_framework::delegation_pool { } } - inline fun assert_and_update_proposal_used_voting_power( - governance_records: &mut GovernanceRecords, pool_address: address, proposal_id: u64, voting_power: u64 - ) { - let stake_pool_remaining_voting_power = supra_governance::get_remaining_voting_power(pool_address, proposal_id); - let stake_pool_used_voting_power = supra_governance::get_voting_power( - pool_address - ) - stake_pool_remaining_voting_power; - let proposal_used_voting_power = smart_table::borrow_mut_with_default( - &mut governance_records.votes_per_proposal, - proposal_id, - 0 - ); - // A edge case: Before enabling partial governance voting on a delegation pool, the delegation pool has - // a voter which can vote with all voting power of this delegation pool. If the voter votes on a proposal after - // partial governance voting flag is enabled, the delegation pool doesn't have enough voting power on this - // proposal for all the delegators. To be fair, no one can vote on this proposal through this delegation pool. - // To detect this case, check if the stake pool had used voting power not through delegation_pool module. - assert!( - stake_pool_used_voting_power == *proposal_used_voting_power, - error::invalid_argument(EALREADY_VOTED_BEFORE_ENABLE_PARTIAL_VOTING) - ); - *proposal_used_voting_power = *proposal_used_voting_power + voting_power; - } fun update_governance_records_for_buy_in_active_shares( pool: &DelegationPool, pool_address: address, new_shares: u128, shareholder: address @@ -4160,903 +4001,6 @@ module supra_framework::delegation_pool { assert_delegation(delegator1_address, pool_address, 5049999998, 0, 0); } - #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010)] - #[expected_failure(abort_code = 0x1000f, location = Self)] - public entry fun test_create_proposal_abort_if_inefficient_stake( - supra_framework: &signer, - validator: &signer, - delegator1: &signer, - // delegator2: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting { - initialize_for_test(supra_framework); - supra_governance::initialize_for_test( - supra_framework, - (10 * ONE_APT as u128), - 100 * ONE_APT, - 1000, - ); - supra_governance::initialize_partial_voting(supra_framework); - features::change_feature_flags_for_testing( - supra_framework, - vector[features::get_partial_governance_voting(), features::get_delegation_pool_partial_governance_voting( - )], - vector[]); - initialize_test_validator(validator, 100 * ONE_APT, true, false); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - // Delegation pool is created after partial governance voting feature flag is enabled. So this delegation - // pool is created with partial governance voting enabled. - assert!(stake::get_delegated_voter(pool_address) == pool_address, 1); - assert!(partial_governance_voting_enabled(pool_address), 2); - - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - stake::mint(delegator1, 100 * ONE_APT); - add_stake(delegator1, pool_address, 10 * ONE_APT); - end_aptos_epoch(); - - let execution_hash = vector::empty(); - vector::push_back(&mut execution_hash, 1); - create_proposal( - delegator1, - pool_address, - execution_hash, - b"", - b"", - true, - ); - } - - #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010)] - public entry fun test_create_proposal_with_sufficient_stake( - supra_framework: &signer, - validator: &signer, - delegator1: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting { - initialize_for_test(supra_framework); - supra_governance::initialize_for_test( - supra_framework, - (10 * ONE_APT as u128), - 100 * ONE_APT, - 1000, - ); - supra_governance::initialize_partial_voting(supra_framework); - features::change_feature_flags_for_testing( - supra_framework, - vector[features::get_partial_governance_voting(), features::get_delegation_pool_partial_governance_voting( - )], - vector[]); - initialize_test_validator(validator, 100 * ONE_APT, true, false); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - // Delegation pool is created after partial governance voting feature flag is enabled. So this delegation - // pool is created with partial governance voting enabled. - assert!(stake::get_delegated_voter(pool_address) == pool_address, 1); - assert!(partial_governance_voting_enabled(pool_address), 2); - - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - stake::mint(delegator1, 100 * ONE_APT); - add_stake(delegator1, pool_address, 100 * ONE_APT); - end_aptos_epoch(); - - let execution_hash = vector::empty(); - vector::push_back(&mut execution_hash, 1); - create_proposal( - delegator1, - pool_address, - execution_hash, - b"", - b"", - true, - ); - } - - #[test( - supra_framework = @supra_framework, - validator = @0x123, - delegator1 = @0x010, - delegator2 = @0x020, - voter1 = @0x030, - voter2 = @0x040 - )] - public entry fun test_voting_power_change( - supra_framework: &signer, - validator: &signer, - delegator1: &signer, - delegator2: &signer, - voter1: &signer, - voter2: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting { - initialize_for_test_no_reward(supra_framework); - supra_governance::initialize_for_test( - supra_framework, - (10 * ONE_APT as u128), - 100 * ONE_APT, - 1000, - ); - supra_governance::initialize_partial_voting(supra_framework); - features::change_feature_flags_for_testing( - supra_framework, - vector[features::get_partial_governance_voting(), features::get_delegation_pool_partial_governance_voting( - )], - vector[] - ); - - initialize_test_validator(validator, 100 * ONE_APT, true, false); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - // Delegation pool is created after partial governance voting feature flag is enabled. So this delegation - // pool is created with partial governance voting enabled. - assert!(stake::get_delegated_voter(pool_address) == pool_address, 1); - assert!(partial_governance_voting_enabled(pool_address), 1); - - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - let delegator2_address = signer::address_of(delegator2); - account::create_account_for_test(delegator2_address); - let voter1_address = signer::address_of(voter1); - account::create_account_for_test(voter1_address); - let voter2_address = signer::address_of(voter2); - account::create_account_for_test(voter2_address); - - stake::mint(delegator1, 110 * ONE_APT); - add_stake(delegator1, pool_address, 10 * ONE_APT); - stake::mint(delegator2, 110 * ONE_APT); - add_stake(delegator2, pool_address, 90 * ONE_APT); - // By default, the voter of a delegator is itself. - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 10 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator2_address) == 90 * ONE_APT, 1); - - end_aptos_epoch(); - // Reward rate is 0. No reward so no voting power change. - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 10 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator2_address) == 90 * ONE_APT, 1); - - // Delegator1 delegates its voting power to voter1 but it takes 1 lockup cycle to take effects. So no voting power - // change now. - delegate_voting_power(delegator1, pool_address, voter1_address); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 10 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator2_address) == 90 * ONE_APT, 1); - - // 1 epoch passed but the lockup cycle hasn't ended. No voting power change. - end_aptos_epoch(); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 10 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator2_address) == 90 * ONE_APT, 1); - - // One cycle passed. The voter change takes effects. - timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); - end_aptos_epoch(); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 10 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator2_address) == 90 * ONE_APT, 1); - - // Delegator2 delegates its voting power to voter1 but it takes 1 lockup cycle to take effects. So no voting power - // change now. - delegate_voting_power(delegator2, pool_address, voter1_address); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 10 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator2_address) == 90 * ONE_APT, 1); - - // One cycle passed. The voter change takes effects. - timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); - end_aptos_epoch(); - assert!(calculate_and_update_delegator_voter(pool_address, delegator2_address) == voter1_address, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 100 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator2_address) == 0, 1); - - // delegator1 changes to voter2 then change back. delegator2 changes to voter1. - // No voting power change in this lockup cycle. - delegate_voting_power(delegator1, pool_address, voter2_address); - delegate_voting_power(delegator2, pool_address, voter2_address); - delegate_voting_power(delegator1, pool_address, voter1_address); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 100 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator2_address) == 0, 1); - - // One cycle passed. The voter change takes effects. - timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); - end_aptos_epoch(); - assert!(calculate_and_update_delegator_voter(pool_address, delegator1_address) == voter1_address, 1); - assert!(calculate_and_update_delegator_voter(pool_address, delegator2_address) == voter2_address, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 10 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == 90 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator2_address) == 0, 1); - - // delegator1 adds stake to the pool. Voting power changes immediately. - add_stake(delegator1, pool_address, 90 * ONE_APT); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 100 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == 90 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator2_address) == 0, 1); - - // delegator1 unlocks stake and changes its voter. No voting power change until next lockup cycle. - unlock(delegator1, pool_address, 90 * ONE_APT); - delegate_voting_power(delegator1, pool_address, voter2_address); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 100 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == 90 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator2_address) == 0, 1); - - // One cycle passed. The voter change takes effects. - timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); - end_aptos_epoch(); - // Withdrawl inactive shares will not change voting power. - withdraw(delegator1, pool_address, 45 * ONE_APT); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == 100 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator2_address) == 0, 1); - - // voter2 adds stake for itself. Voting power changes immediately. - stake::mint(voter2, 110 * ONE_APT); - add_stake(voter2, pool_address, 10 * ONE_APT); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == 110 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator2_address) == 0, 1); - } - - #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, voter1 = @0x030)] - public entry fun test_voting_power_change_for_existing_delegation_pool( - supra_framework: &signer, - validator: &signer, - delegator1: &signer, - voter1: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting { - initialize_for_test_no_reward(supra_framework); - supra_governance::initialize_for_test( - supra_framework, - (10 * ONE_APT as u128), - 100 * ONE_APT, - 1000, - ); - supra_governance::initialize_partial_voting(supra_framework); - - initialize_test_validator(validator, 100 * ONE_APT, true, false); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - // Delegation pool is created before partial governance voting feature flag is enabled. So this delegation - // pool's voter is its owner. - assert!(stake::get_delegated_voter(pool_address) == validator_address, 1); - assert!(!partial_governance_voting_enabled(pool_address), 1); - - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - let voter1_address = signer::address_of(voter1); - account::create_account_for_test(voter1_address); - - stake::mint(delegator1, 110 * ONE_APT); - add_stake(delegator1, pool_address, 10 * ONE_APT); - - // Enable partial governance voting feature flag. - features::change_feature_flags_for_testing( - supra_framework, - vector[features::get_partial_governance_voting(), features::get_delegation_pool_partial_governance_voting( - )], - vector[] - ); - // Voter doens't change until enabling partial governance voting on this delegation pool. - assert!(stake::get_delegated_voter(pool_address) == validator_address, 1); - // Enable partial governance voting on this delegation pool. - enable_partial_governance_voting(pool_address); - assert!(stake::get_delegated_voter(pool_address) == pool_address, 1); - assert!(partial_governance_voting_enabled(pool_address), 1); - - // By default, the voter of a delegator is itself. - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 10 * ONE_APT, 1); - - // Delegator1 delegates its voting power to voter1. - // It takes 1 cycle to take effect. No immediate change. - delegate_voting_power(delegator1, pool_address, voter1_address); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 10 * ONE_APT, 1); - - // One cycle passed. The voter change takes effects. - timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); - end_aptos_epoch(); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 10 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 0, 1); - } - - #[test( - supra_framework = @supra_framework, - validator = @0x123, - delegator1 = @0x010, - delegator2 = @0x020, - voter1 = @0x030, - voter2 = @0x040 - )] - public entry fun test_voting_power_change_for_rewards( - supra_framework: &signer, - validator: &signer, - delegator1: &signer, - delegator2: &signer, - voter1: &signer, - voter2: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting { - initialize_for_test_custom( - supra_framework, - 100 * ONE_APT, - 10000 * ONE_APT, - LOCKUP_CYCLE_SECONDS, - true, - 100, - 100, - 1000000 - ); - supra_governance::initialize_for_test( - supra_framework, - (10 * ONE_APT as u128), - 100 * ONE_APT, - 1000, - ); - supra_governance::initialize_partial_voting(supra_framework); - features::change_feature_flags_for_testing( - supra_framework, - vector[features::get_partial_governance_voting(), features::get_delegation_pool_partial_governance_voting( - )], - vector[] - ); - - // 50% commission rate - initialize_test_validator_custom(validator, 100 * ONE_APT, true, false, 5000); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - // Delegation pool is created after partial governance voting feature flag is enabled. So this delegation - // pool is created with partial governance voting enabled. - assert!(stake::get_delegated_voter(pool_address) == pool_address, 1); - assert!(partial_governance_voting_enabled(pool_address), 1); - - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - let delegator2_address = signer::address_of(delegator2); - account::create_account_for_test(delegator2_address); - let voter1_address = signer::address_of(voter1); - account::create_account_for_test(voter1_address); - let voter2_address = signer::address_of(voter2); - account::create_account_for_test(voter2_address); - - stake::mint(delegator1, 110 * ONE_APT); - add_stake(delegator1, pool_address, 10 * ONE_APT); - stake::mint(delegator2, 110 * ONE_APT); - add_stake(delegator2, pool_address, 90 * ONE_APT); - // By default, the voter of a delegator is itself. - assert!(calculate_and_update_voter_total_voting_power(pool_address, validator_address) == 100 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 10 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator2_address) == 90 * ONE_APT, 1); - - // One epoch is passed. Delegators earn no reward because their stake was inactive. - end_aptos_epoch(); - assert!(calculate_and_update_voter_total_voting_power(pool_address, validator_address) == 100 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 10 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator2_address) == 90 * ONE_APT, 1); - - // 2 epoches are passed. Delegators earn reward and voting power increases. Operator earns reward and - // commission. Because there is no operation during these 2 epoches. Operator's commission is not compounded. - end_aptos_epoch(); - end_aptos_epoch(); - assert!(calculate_and_update_voter_total_voting_power(pool_address, validator_address) == 550 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 25 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator2_address) == 225 * ONE_APT, 1); - - // Another epoch is passed. Voting power chage due to reward is correct even if delegator1 and delegator2 change its voter. - delegate_voting_power(delegator1, pool_address, voter1_address); - delegate_voting_power(delegator2, pool_address, voter1_address); - timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); - end_aptos_epoch(); - assert!(calculate_and_update_voter_total_voting_power(pool_address, validator_address) == 122499999999, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 375 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator2_address) == 0, 1); - } - - #[test( - supra_framework = @supra_framework, - validator = @0x123, - delegator1 = @0x010, - delegator2 = @0x020, - voter1 = @0x030, - voter2 = @0x040 - )] - public entry fun test_voting_power_change_already_voted_before_partial( - supra_framework: &signer, - validator: &signer, - delegator1: &signer, - delegator2: &signer, - voter1: &signer, - voter2: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting { - // partial voing hasn't been enabled yet. A proposal has been created by the validator. - let proposal1_id = setup_vote(supra_framework, validator, false); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - let delegator2_address = signer::address_of(delegator2); - account::create_account_for_test(delegator2_address); - let voter1_address = signer::address_of(voter1); - account::create_account_for_test(voter1_address); - let voter2_address = signer::address_of(voter2); - account::create_account_for_test(voter2_address); - - stake::mint(delegator1, 110 * ONE_APT); - add_stake(delegator1, pool_address, 10 * ONE_APT); - stake::mint(delegator2, 110 * ONE_APT); - add_stake(delegator2, pool_address, 90 * ONE_APT); - - // Create 2 proposals and vote for proposal1. - let execution_hash = vector::empty(); - vector::push_back(&mut execution_hash, 1); - let proposal2_id = supra_governance::create_proposal_v2_impl( - validator, - pool_address, - execution_hash, - b"", - b"", - true, - ); - supra_governance::vote(validator, pool_address, proposal1_id, true); - - // Enable partial governance voting feature flag. - features::change_feature_flags_for_testing( - supra_framework, - vector[features::get_partial_governance_voting(), features::get_delegation_pool_partial_governance_voting( - )], - vector[] - ); - // Voter doens't change until enabling partial governance voting on this delegation pool. - assert!(stake::get_delegated_voter(pool_address) == validator_address, 1); - // Enable partial governance voting on this delegation pool. - enable_partial_governance_voting(pool_address); - assert!(stake::get_delegated_voter(pool_address) == pool_address, 1); - assert!(partial_governance_voting_enabled(pool_address), 1); - - assert!(calculate_and_update_voter_total_voting_power(pool_address, validator_address) == 100 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 10 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator2_address) == 90 * ONE_APT, 1); - // No one can vote for proposal1 because it's already voted before enabling partial governance voting. - assert!(calculate_and_update_remaining_voting_power(pool_address, validator_address, proposal1_id) == 0, 1); - assert!(calculate_and_update_remaining_voting_power(pool_address, delegator1_address, proposal1_id) == 0, 1); - assert!(calculate_and_update_remaining_voting_power(pool_address, delegator2_address, proposal1_id) == 0, 1); - assert!( - calculate_and_update_remaining_voting_power(pool_address, validator_address, proposal2_id) == 100 * ONE_APT, - 1 - ); - assert!( - calculate_and_update_remaining_voting_power(pool_address, delegator1_address, proposal2_id) == 10 * ONE_APT, - 1 - ); - assert!( - calculate_and_update_remaining_voting_power(pool_address, delegator2_address, proposal2_id) == 90 * ONE_APT, - 1 - ); - - // Delegator1 tries to use 50 APT to vote on proposal2, but it only has 10 APT. So only 10 APT voting power is used. - vote(delegator1, pool_address, proposal2_id, 50 * ONE_APT, true); - assert!(calculate_and_update_remaining_voting_power(pool_address, delegator1_address, proposal2_id) == 0, 1); - - add_stake(delegator1, pool_address, 60 * ONE_APT); - assert!(calculate_and_update_voter_total_voting_power(pool_address, delegator1_address) == 70 * ONE_APT, 1); - vote(delegator1, pool_address, proposal2_id, 25 * ONE_APT, true); - assert!( - calculate_and_update_remaining_voting_power(pool_address, delegator1_address, proposal2_id) == 35 * ONE_APT, - 1 - ); - vote(delegator1, pool_address, proposal2_id, 30 * ONE_APT, false); - assert!( - calculate_and_update_remaining_voting_power(pool_address, delegator1_address, proposal2_id) == 5 * ONE_APT, - 1 - ); - } - - #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, voter1 = @0x030)] - #[expected_failure(abort_code = 0x10010, location = Self)] - public entry fun test_vote_should_failed_if_already_voted_before_enable_partial_voting_flag( - supra_framework: &signer, - validator: &signer, - delegator1: &signer, - voter1: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting { - // partial voing hasn't been enabled yet. A proposal has been created by the validator. - let proposal1_id = setup_vote(supra_framework, validator, false); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - let voter1_address = signer::address_of(voter1); - account::create_account_for_test(voter1_address); - - stake::mint(delegator1, 110 * ONE_APT); - add_stake(delegator1, pool_address, 10 * ONE_APT); - end_aptos_epoch(); - - supra_governance::vote(validator, pool_address, proposal1_id, true); - - // Enable partial governance voting feature flag. - features::change_feature_flags_for_testing( - supra_framework, - vector[features::get_partial_governance_voting(), features::get_delegation_pool_partial_governance_voting( - )], - vector[] - ); - // Enable partial governance voting on this delegation pool. - enable_partial_governance_voting(pool_address); - - vote(delegator1, pool_address, proposal1_id, 10 * ONE_APT, true); - } - - #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, voter1 = @0x030)] - #[expected_failure(abort_code = 0x10011, location = Self)] - public entry fun test_vote_should_failed_if_already_voted_before_enable_partial_voting_on_pool( - supra_framework: &signer, - validator: &signer, - delegator1: &signer, - voter1: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting { - // partial voing hasn't been enabled yet. A proposal has been created by the validator. - let proposal1_id = setup_vote(supra_framework, validator, false); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - let voter1_address = signer::address_of(voter1); - account::create_account_for_test(voter1_address); - - stake::mint(delegator1, 110 * ONE_APT); - add_stake(delegator1, pool_address, 10 * ONE_APT); - end_aptos_epoch(); - - // Enable partial governance voting feature flag. - features::change_feature_flags_for_testing( - supra_framework, - vector[features::get_partial_governance_voting(), features::get_delegation_pool_partial_governance_voting( - )], - vector[] - ); - - // The operator voter votes on the proposal after partial governace voting flag is enabled but before partial voting is enabled on the pool. - supra_governance::vote(validator, pool_address, proposal1_id, true); - - // Enable partial governance voting on this delegation pool. - enable_partial_governance_voting(pool_address); - - add_stake(delegator1, pool_address, 10 * ONE_APT); - vote(delegator1, pool_address, proposal1_id, 10 * ONE_APT, true); - } - - #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010)] - #[expected_failure(abort_code = 0x10010, location = Self)] - public entry fun test_vote_should_failed_if_no_stake( - supra_framework: &signer, - validator: &signer, - delegator1: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting { - // partial voing hasn't been enabled yet. A proposal has been created by the validator. - let proposal1_id = setup_vote(supra_framework, validator, true); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - - // Delegator1 has no stake. Abort. - vote(delegator1, pool_address, proposal1_id, 10 * ONE_APT, true); - } - - #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, voter1 = @0x030)] - public entry fun test_delegate_voting_power_should_pass_even_if_no_stake( - supra_framework: &signer, - validator: &signer, - delegator1: &signer, - voter1: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting { - // partial voing hasn't been enabled yet. A proposal has been created by the validator. - setup_vote(supra_framework, validator, true); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - - // Delegator1 has no stake. Abort. - delegate_voting_power(delegator1, pool_address, signer::address_of(voter1)); - } - - #[test( - supra_framework = @supra_framework, - validator = @0x123, - delegator = @0x010, - voter1 = @0x020, - voter2 = @0x030 - )] - public entry fun test_delegate_voting_power_applies_next_lockup( - supra_framework: &signer, - validator: &signer, - delegator: &signer, - voter1: &signer, - voter2: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting { - initialize_for_test(supra_framework); - supra_governance::initialize_partial_voting(supra_framework); - features::change_feature_flags_for_testing( - supra_framework, - vector[ - features::get_partial_governance_voting(), - features::get_delegation_pool_partial_governance_voting() - ], - vector[] - ); - - initialize_test_validator(validator, 100 * ONE_APT, true, true); - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - - let delegator_address = signer::address_of(delegator); - account::create_account_for_test(delegator_address); - let voter1_address = signer::address_of(voter1); - let voter2_address = signer::address_of(voter2); - - stake::mint(delegator, 100 * ONE_APT); - add_stake(delegator, pool_address, 20 * ONE_APT); - - let first_lockup_end = stake::get_lockup_secs(pool_address); - // default voter is the delegator - let (voter, pending_voter, last_locked_until_secs) = calculate_and_update_voting_delegation( - pool_address, - delegator_address - ); - assert!(voter == delegator_address, 0); - assert!(pending_voter == delegator_address, 0); - assert!(last_locked_until_secs == first_lockup_end, 0); - - // delegate to voter 1 which takes effect next lockup - delegate_voting_power(delegator, pool_address, voter1_address); - (voter, pending_voter, last_locked_until_secs) = calculate_and_update_voting_delegation( - pool_address, - delegator_address - ); - assert!(voter == delegator_address, 0); - assert!(pending_voter == voter1_address, 0); - assert!(last_locked_until_secs == first_lockup_end, 0); - assert!( - calculate_and_update_voter_total_voting_power( - pool_address, - delegator_address - ) == 20 * ONE_APT - get_add_stake_fee(pool_address, 20 * ONE_APT), - 0 - ); - - // end this lockup cycle - fast_forward_to_unlock(pool_address); - let second_lockup_end = stake::get_lockup_secs(pool_address); - assert!(second_lockup_end > first_lockup_end, 0); - - (voter, pending_voter, last_locked_until_secs) = calculate_and_update_voting_delegation( - pool_address, - delegator_address - ); - // voter 1 becomes current voter and owns all voting power of delegator - assert!(voter == voter1_address, 0); - assert!(pending_voter == voter1_address, 0); - assert!(last_locked_until_secs == second_lockup_end, 0); - assert!( - calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 20 * ONE_APT, - 0 - ); - - // delegate to voter 2, current voter should still be voter 1 - delegate_voting_power(delegator, pool_address, voter2_address); - (voter, pending_voter, last_locked_until_secs) = calculate_and_update_voting_delegation( - pool_address, - delegator_address - ); - assert!(voter == voter1_address, 0); - assert!(pending_voter == voter2_address, 0); - assert!(last_locked_until_secs == second_lockup_end, 0); - assert!( - calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 20 * ONE_APT, - 0 - ); - - // stake added by delegator counts as voting power for the current voter - add_stake(delegator, pool_address, 30 * ONE_APT); - assert!( - calculate_and_update_voter_total_voting_power( - pool_address, - voter1_address - ) == 20 * ONE_APT + 30 * ONE_APT - get_add_stake_fee(pool_address, 30 * ONE_APT), - 0 - ); - - // refunded `add_stake` fee is counted as voting power too - end_aptos_epoch(); - assert!( - calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 5020000000, - 0 - ); - - // delegator can unlock their entire stake (all voting shares are owned by voter 1) - unlock(delegator, pool_address, 5020000000); - assert!( - calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 5020000000, - 0 - ); - - // delegator can reactivate their entire stake (all voting shares are owned by voter 1) - reactivate_stake(delegator, pool_address, 5020000000); - assert!( - calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == 5019999999, - 0 - ); - - // end this lockup cycle - fast_forward_to_unlock(pool_address); - let third_lockup_end = stake::get_lockup_secs(pool_address); - assert!(third_lockup_end > second_lockup_end, 0); - - // voter 2 becomes current voter and owns all voting power of delegator - (voter, pending_voter, last_locked_until_secs) = calculate_and_update_voting_delegation( - pool_address, - delegator_address - ); - assert!(voter == voter2_address, 0); - assert!(pending_voter == voter2_address, 0); - assert!(last_locked_until_secs == third_lockup_end, 0); - assert!( - calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == 5070199999, - 0 - ); - } - - #[test( - supra_framework = @supra_framework, - validator = @0x123, - validator_min_consensus = @0x234, - delegator = @0x010, - voter1 = @0x020, - voter2 = @0x030 - )] - public entry fun test_delegate_voting_power_from_inactive_validator( - supra_framework: &signer, - validator: &signer, - validator_min_consensus: &signer, - delegator: &signer, - voter1: &signer, - voter2: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting { - initialize_for_test(supra_framework); - supra_governance::initialize_partial_voting(supra_framework); - features::change_feature_flags_for_testing( - supra_framework, - vector[ - features::get_partial_governance_voting(), - features::get_delegation_pool_partial_governance_voting() - ], - vector[] - ); - - // activate more validators in order to inactivate one later - initialize_test_validator(validator, 100 * ONE_APT, true, false); - initialize_test_validator(validator_min_consensus, 100 * ONE_APT, true, true); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - - let delegator_address = signer::address_of(delegator); - account::create_account_for_test(delegator_address); - let voter1_address = signer::address_of(voter1); - let voter2_address = signer::address_of(voter2); - - let first_lockup_end = stake::get_lockup_secs(pool_address); - let (voter, pending_voter, last_locked_until_secs) = calculate_and_update_voting_delegation( - pool_address, - delegator_address - ); - assert!(voter == delegator_address, 0); - assert!(pending_voter == delegator_address, 0); - assert!(last_locked_until_secs == first_lockup_end, 0); - - delegate_voting_power(delegator, pool_address, voter1_address); - (voter, pending_voter, last_locked_until_secs) = calculate_and_update_voting_delegation( - pool_address, - delegator_address - ); - assert!(voter == delegator_address, 0); - assert!(pending_voter == voter1_address, 0); - assert!(last_locked_until_secs == first_lockup_end, 0); - - // end this lockup cycle - fast_forward_to_unlock(pool_address); - let second_lockup_end = stake::get_lockup_secs(pool_address); - assert!(second_lockup_end > first_lockup_end, 0); - - // voter 1 becomes current voter - (voter, pending_voter, last_locked_until_secs) = calculate_and_update_voting_delegation( - pool_address, - delegator_address - ); - assert!(voter == voter1_address, 0); - assert!(pending_voter == voter1_address, 0); - assert!(last_locked_until_secs == second_lockup_end, 0); - - // delegate to voter 2 which should apply next lockup - delegate_voting_power(delegator, pool_address, voter2_address); - (voter, pending_voter, last_locked_until_secs) = calculate_and_update_voting_delegation( - pool_address, - delegator_address - ); - assert!(voter == voter1_address, 0); - assert!(pending_voter == voter2_address, 0); - assert!(last_locked_until_secs == second_lockup_end, 0); - - // lockup cycle won't be refreshed on the pool anymore - stake::leave_validator_set(validator, pool_address); - end_aptos_epoch(); - assert!(stake::get_validator_state(pool_address) == VALIDATOR_STATUS_INACTIVE, 0); - - // lockup cycle passes, but validator has no lockup refresh because it is inactive - fast_forward_to_unlock(pool_address); - assert!(second_lockup_end == stake::get_lockup_secs(pool_address), 0); - assert!(second_lockup_end <= reconfiguration::last_reconfiguration_time(), 0); - - // pending voter 2 is not applied - (voter, pending_voter, last_locked_until_secs) = calculate_and_update_voting_delegation( - pool_address, - delegator_address - ); - assert!(voter == voter1_address, 0); - assert!(pending_voter == voter2_address, 0); - assert!(last_locked_until_secs == second_lockup_end, 0); - - // reactivate validator - stake::join_validator_set(validator, pool_address); - end_aptos_epoch(); - assert!(stake::get_validator_state(pool_address) == VALIDATOR_STATUS_ACTIVE, 0); - - // lockup cycle of pool has been refreshed again - let third_lockup_end = stake::get_lockup_secs(pool_address); - assert!(third_lockup_end > second_lockup_end, 0); - - // voter 2 finally becomes current voter - (voter, pending_voter, last_locked_until_secs) = calculate_and_update_voting_delegation( - pool_address, - delegator_address - ); - assert!(voter == voter2_address, 0); - assert!(pending_voter == voter2_address, 0); - assert!(last_locked_until_secs == third_lockup_end, 0); - } - #[test(staker = @0xe256f4f4e2986cada739e339895cf5585082ff247464cab8ec56eea726bd2263)] public entry fun test_get_expected_stake_pool_address(staker: address) { let pool_address = get_expected_stake_pool_address(staker, vector[0x42, 0x42]); @@ -5514,53 +4458,6 @@ module supra_framework::delegation_pool { } } - #[test_only] - public fun setup_vote( - supra_framework: &signer, - validator: &signer, - enable_partial_voting: bool, - ): u64 acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting { - initialize_for_test_no_reward(supra_framework); - supra_governance::initialize_for_test( - supra_framework, - (10 * ONE_APT as u128), - 100 * ONE_APT, - 1000, - ); - supra_governance::initialize_partial_voting(supra_framework); - - initialize_test_validator(validator, 100 * ONE_APT, true, false); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - // Delegation pool is created before partial governance voting feature flag is enabled. So this delegation - // pool's voter is its owner. - assert!(stake::get_delegated_voter(pool_address) == validator_address, 1); - assert!(!partial_governance_voting_enabled(pool_address), 1); - end_aptos_epoch(); - - // Create 1 proposals and vote for proposal1. - let execution_hash = vector::empty(); - vector::push_back(&mut execution_hash, 1); - let proposal_id = supra_governance::create_proposal_v2_impl( - validator, - pool_address, - execution_hash, - b"", - b"", - true, - ); - if (enable_partial_voting) { - features::change_feature_flags_for_testing( - supra_framework, - vector[features::get_partial_governance_voting( - ), features::get_delegation_pool_partial_governance_voting()], - vector[]); - enable_partial_governance_voting(pool_address); - }; - proposal_id - } - #[test_only] public fun total_coins_inactive(pool_address: address): u64 acquires DelegationPool { borrow_global(pool_address).total_coins_inactive diff --git a/aptos-move/framework/supra-framework/sources/genesis.move b/aptos-move/framework/supra-framework/sources/genesis.move index 933ca6c3e9b57..4fb2e32eb3fb2 100644 --- a/aptos-move/framework/supra-framework/sources/genesis.move +++ b/aptos-move/framework/supra-framework/sources/genesis.move @@ -3,11 +3,13 @@ module supra_framework::genesis { use std::fixed_point32; use std::vector; use std::option; + use std::string::{Self, String}; use aptos_std::simple_map; use supra_framework::supra_account; use supra_framework::delegation_pool; use supra_framework::pbo_delegation_pool; + use supra_framework::multisig_account; use supra_framework::account; use supra_framework::aggregator_factory; @@ -251,6 +253,38 @@ module supra_framework::genesis { account } } + + + fun create_multiple_multisig_accounts_with_schema(supra_framework: &signer, + owner: address, additional_owners: vector
,num_signatures_required:u64,metadata_keys:vector,metadata_values:vector>, + timeout_duration:u64, balance:u64, num_of_accounts: u32): vector
{ + + let counter = 0; + let result = vector::empty(); + while (counter < num_of_accounts) { + let account_addr = create_multisig_account_with_balance(supra_framework, owner, additional_owners, + num_signatures_required,metadata_keys,metadata_values,timeout_duration,balance); + vector::push_back(&mut result,account_addr); + account::increment_sequence_number(owner); + counter = counter + 1; + }; + result + } + fun create_multisig_account_with_balance(supra_framework: &signer, owner: address, additional_owners: vector
, + num_signatures_required:u64, metadata_keys: vector, + metadata_values: vector>, timeout_duration: u64, balance:u64 ) : address { + + + assert!(account::exists_at(owner),error::invalid_argument(EACCOUNT_DOES_NOT_EXIST)); + assert!(vector::all(&additional_owners,|ao_addr|{account::exists_at(*ao_addr)}),error::invalid_argument(EACCOUNT_DOES_NOT_EXIST)); + let addr = multisig_account::get_next_multisig_account_address(owner); + let owner_signer = create_signer(owner); + multisig_account::create_with_owners(&owner_signer,additional_owners,num_signatures_required,metadata_keys,metadata_values,timeout_duration); + supra_coin::mint(supra_framework,addr,balance); + addr + + } + fun create_employee_validators( employee_vesting_start: u64, @@ -776,8 +810,6 @@ module supra_framework::genesis { #[test_only] use aptos_std::ed25519; - #[test_only] - use supra_framework::multisig_account; #[test_only] fun generate_multisig_account(owner: &signer, addition_owner: vector
): address { @@ -1098,6 +1130,57 @@ module supra_framework::genesis { assert!(pbo_delegation_pool::delegation_pool_exists(pool_address1), 0); assert!(pbo_delegation_pool::delegation_pool_exists(pool_address2), 1); } + + #[test (supra_framework=@0x1, owner1=@0x1234, owner2=@0x2345, owner3=@0x3456)] + fun test_create_multisig_account_with_balance(supra_framework: &signer, owner1: address, owner2: address, owner3: address) + { + setup(); + initialize_supra_coin(supra_framework); + let additional_owners = vector[owner2, owner3]; + let timeout_duration=600; + let num_signatures_required = 2; + let metadata_keys: vector =vector::empty(); + let metadata_values: vector> = vector::empty(); + let balance = 10000000000; + create_account(supra_framework,owner1,0); + create_account(supra_framework,owner2,0); + create_account(supra_framework,owner3,0); + let addr = create_multisig_account_with_balance(supra_framework,owner1, additional_owners, + num_signatures_required, metadata_keys, metadata_values, timeout_duration,balance); + //Ensure it is indeed on-chain multisig account with required threshold + assert!(multisig_account::num_signatures_required(addr)==2,1); + //Ensure the account is seeded with supplied balance + assert!(coin::balance(addr)==balance,2); + // Ensure that you can transfer out funds from multisig account + let multisig_signer = create_signer(addr); + coin::transfer(&multisig_signer,owner1,balance); + assert!(coin::balance(owner1)==balance,3); + } + + #[test (supra_framework=@0x1, owner1=@0x1234, owner2=@0x2345, owner3=@0x3456)] + fun test_create_multisig_account_with_schema(supra_framework: &signer, owner1: address, owner2: address, owner3: address) + { + setup(); + initialize_supra_coin(supra_framework); + let additional_owners = vector[owner2, owner3]; + let timeout_duration=600; + let num_signatures_required = 2; + let metadata_keys: vector =vector::empty(); + let metadata_values: vector> = vector::empty(); + let balance = 10000000000; + let num_accounts = 3; + create_account(supra_framework,owner1,0); + create_account(supra_framework,owner2,0); + create_account(supra_framework,owner3,0); + let vec_addr = create_multiple_multisig_accounts_with_schema(supra_framework,owner1, + additional_owners,num_signatures_required,metadata_keys,metadata_values, + timeout_duration,balance,num_accounts); + //Ensure they are indeed on-chain multisig account with required threshold + assert!(vector::all(&vec_addr,|elem| {multisig_account::num_signatures_required(*elem)==2}),1); + //Ensure the accounts are seeded with supplied balance + assert!(vector::all(&vec_addr,|elem| {coin::balance(*elem)==balance}),2); + } + #[test(supra_framework = @0x1)] fun test_create_vesting_without_staking_pools(supra_framework: &signer) { diff --git a/aptos-move/framework/supra-framework/sources/pbo_delegation_pool.move b/aptos-move/framework/supra-framework/sources/pbo_delegation_pool.move index 18000074a2b1a..819ed3eaef635 100644 --- a/aptos-move/framework/supra-framework/sources/pbo_delegation_pool.move +++ b/aptos-move/framework/supra-framework/sources/pbo_delegation_pool.move @@ -127,7 +127,6 @@ module supra_framework::pbo_delegation_pool { use supra_framework::account; use supra_framework::supra_account; use supra_framework::supra_coin::SupraCoin; - use supra_framework::supra_governance; use supra_framework::coin; use supra_framework::event::{Self, EventHandle, emit}; use supra_framework::stake::{Self, get_operator}; @@ -694,26 +693,6 @@ module supra_framework::pbo_delegation_pool { calculate_total_voting_power(pool, latest_delegated_votes) } - #[view] - /// Return the remaining voting power of a delegator in a delegation pool on a proposal. This function syncs DelegationPool to the - /// latest state. - public fun calculate_and_update_remaining_voting_power( - pool_address: address, voter_address: address, proposal_id: u64 - ): u64 acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { - assert_partial_governance_voting_enabled(pool_address); - // If the whole stake pool has no voting power(e.g. it has already voted before partial - // governance voting flag is enabled), the delegator also has no voting power. - if (supra_governance::get_remaining_voting_power(pool_address, proposal_id) == 0) { - return 0 - }; - - let total_voting_power = calculate_and_update_voter_total_voting_power(pool_address, - voter_address); - let governance_records = borrow_global(pool_address); - total_voting_power - get_used_voting_power(governance_records, voter_address, - proposal_id) - } - #[view] /// Return the latest delegated voter of a delegator in a delegation pool. This function syncs DelegationPool to the /// latest state. @@ -929,96 +908,6 @@ module supra_framework::pbo_delegation_pool { }); } - /// Vote on a proposal with a voter's voting power. To successfully vote, the following conditions must be met: - /// 1. The voting period of the proposal hasn't ended. - /// 2. The delegation pool's lockup period ends after the voting period of the proposal. - /// 3. The voter still has spare voting power on this proposal. - /// 4. The delegation pool never votes on the proposal before enabling partial governance voting. - public entry fun vote( - voter: &signer, - pool_address: address, - proposal_id: u64, - voting_power: u64, - should_pass: bool - ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { - assert_partial_governance_voting_enabled(pool_address); - // synchronize delegation and stake pools before any user operation. - synchronize_delegation_pool(pool_address); - - let voter_address = signer::address_of(voter); - let remaining_voting_power = calculate_and_update_remaining_voting_power( - pool_address, voter_address, proposal_id - ); - if (voting_power > remaining_voting_power) { - voting_power = remaining_voting_power; - }; - assert!(voting_power > 0, error::invalid_argument(ENO_VOTING_POWER)); - - let governance_records = borrow_global_mut(pool_address); - // Check a edge case during the transient period of enabling partial governance voting. - assert_and_update_proposal_used_voting_power(governance_records, pool_address, - proposal_id, voting_power); - let used_voting_power = borrow_mut_used_voting_power(governance_records, - voter_address, proposal_id); - *used_voting_power = *used_voting_power + voting_power; - - let pool_signer = retrieve_stake_pool_owner(borrow_global( - pool_address - )); - supra_governance::partial_vote(&pool_signer, pool_address, proposal_id, voting_power, - should_pass); - - event::emit_event(&mut governance_records.vote_events, - VoteEvent { - voter: voter_address, - proposal_id, - delegation_pool: pool_address, - num_votes: voting_power, - should_pass, - } - ); - } - - /// A voter could create a governance proposal by this function. To successfully create a proposal, the voter's - /// voting power in THIS delegation pool must be not less than the minimum required voting power specified in - /// `supra_governance.move`. - public entry fun create_proposal( - voter: &signer, - pool_address: address, - execution_hash: vector, - metadata_location: vector, - metadata_hash: vector, - is_multi_step_proposal: bool, - ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { - assert_partial_governance_voting_enabled(pool_address); - - // synchronize delegation and stake pools before any user operation - synchronize_delegation_pool(pool_address); - - let voter_addr = signer::address_of(voter); - let pool = borrow_global(pool_address); - let governance_records = borrow_global_mut(pool_address); - let total_voting_power = calculate_and_update_delegated_votes(pool, - governance_records, voter_addr); - assert!(total_voting_power >= supra_governance::get_required_proposer_stake(), - error::invalid_argument(EINSUFFICIENT_PROPOSER_STAKE)); - let pool_signer = retrieve_stake_pool_owner(borrow_global( - pool_address - )); - let proposal_id = supra_governance::create_proposal_v2_impl(&pool_signer, - pool_address, - execution_hash, - metadata_location, - metadata_hash, - is_multi_step_proposal, - ); - - let governance_records = borrow_global_mut(pool_address); - event::emit_event(&mut governance_records.create_proposal_events, - CreateProposalEvent { proposal_id, voter: voter_addr, delegation_pool: pool_address, } - ); - } - fun assert_owner_cap_exists(owner: address) { assert!(owner_cap_exists(owner), error::not_found(EOWNER_CAP_NOT_FOUND)); } @@ -1999,29 +1888,6 @@ module supra_framework::pbo_delegation_pool { } } - inline fun assert_and_update_proposal_used_voting_power( - governance_records: &mut GovernanceRecords, - pool_address: address, - proposal_id: u64, - voting_power: u64 - ) { - let stake_pool_remaining_voting_power = supra_governance::get_remaining_voting_power( - pool_address, proposal_id - ); - let stake_pool_used_voting_power = supra_governance::get_voting_power(pool_address) - - stake_pool_remaining_voting_power; - let proposal_used_voting_power = smart_table::borrow_mut_with_default(&mut governance_records - .votes_per_proposal, proposal_id, 0); - // A edge case: Before enabling partial governance voting on a delegation pool, the delegation pool has - // a voter which can vote with all voting power of this delegation pool. If the voter votes on a proposal after - // partial governance voting flag is enabled, the delegation pool doesn't have enough voting power on this - // proposal for all the delegators. To be fair, no one can vote on this proposal through this delegation pool. - // To detect this case, check if the stake pool had used voting power not through delegation_pool module. - assert!(stake_pool_used_voting_power == *proposal_used_voting_power, - error::invalid_argument(EALREADY_VOTED_BEFORE_ENABLE_PARTIAL_VOTING)); - *proposal_used_voting_power = *proposal_used_voting_power + voting_power; - } - fun update_governance_records_for_buy_in_active_shares( pool: &DelegationPool, pool_address: address, new_shares: u128, shareholder: address ) acquires GovernanceRecords { @@ -4484,835 +4350,6 @@ module supra_framework::pbo_delegation_pool { assert_delegation(delegator1_address, pool_address, 3950000003, 0, 1099999996); } - #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010)] - #[expected_failure(abort_code = 0x1000f, location = Self)] - public entry fun test_create_proposal_abort_if_inefficient_stake( - supra_framework: &signer, validator: &signer, delegator1: &signer, - // delegator2: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { - initialize_for_test(supra_framework); - supra_governance::initialize_for_test(supra_framework,(10 * ONE_APT as u128), 100 - * ONE_APT, 1000,); - supra_governance::initialize_partial_voting(supra_framework); - features::change_feature_flags_for_testing(supra_framework, - vector[ - features::get_partial_governance_voting(), - features::get_delegation_pool_partial_governance_voting()], - vector[]); - let delegator_address = vector[@0x111]; - let principle_stake = vector[100 * ONE_APT]; - let coin = stake::mint_coins(100 * ONE_APT); - let principle_lockup_time = 0; - initialize_test_validator(validator, - 100 * ONE_APT, - true, - false, - 0, - delegator_address, - principle_stake, - coin, - option::none(), - vector[2, 2, 3], - 10, - principle_lockup_time, - 12 - ); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - // Delegation pool is created after partial governance voting feature flag is enabled. So this delegation - // pool is created with partial governance voting enabled. - assert!(stake::get_delegated_voter(pool_address) == pool_address, 1); - assert!(partial_governance_voting_enabled(pool_address), 2); - - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - stake::mint(delegator1, 100 * ONE_APT); - add_stake(delegator1, pool_address, 10 * ONE_APT); - end_aptos_epoch(); - - let execution_hash = vector::empty(); - vector::push_back(&mut execution_hash, 1); - create_proposal(delegator1, pool_address, execution_hash, b"", b"", true,); - } - - #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010)] - public entry fun test_create_proposal_with_sufficient_stake( - supra_framework: &signer, validator: &signer, delegator1: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { - initialize_for_test(supra_framework); - supra_governance::initialize_for_test(supra_framework,(10 * ONE_APT as u128), 100 - * ONE_APT, 1000,); - supra_governance::initialize_partial_voting(supra_framework); - features::change_feature_flags_for_testing(supra_framework, - vector[ - features::get_partial_governance_voting(), - features::get_delegation_pool_partial_governance_voting()], - vector[]); - let delegator_address = vector[@0x111]; - let principle_stake = vector[100 * ONE_APT]; - let coin = stake::mint_coins(100 * ONE_APT); - let principle_lockup_time = 0; - initialize_test_validator(validator, - 100 * ONE_APT, - true, - false, - 0, - delegator_address, - principle_stake, - coin, - option::none(), - vector[2, 2, 3], - 10, - principle_lockup_time, - 12 - ); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - // Delegation pool is created after partial governance voting feature flag is enabled. So this delegation - // pool is created with partial governance voting enabled. - assert!(stake::get_delegated_voter(pool_address) == pool_address, 1); - assert!(partial_governance_voting_enabled(pool_address), 2); - - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - stake::mint(delegator1, 100 * ONE_APT); - add_stake(delegator1, pool_address, 100 * ONE_APT); - end_aptos_epoch(); - - let execution_hash = vector::empty(); - vector::push_back(&mut execution_hash, 1); - create_proposal(delegator1, pool_address, execution_hash, b"", b"", true,); - } - - #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, delegator2 = @0x020, voter1 = @0x030, voter2 = @0x040)] - public entry fun test_voting_power_change( - supra_framework: &signer, - validator: &signer, - delegator1: &signer, - delegator2: &signer, - voter1: &signer, - voter2: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { - initialize_for_test_no_reward(supra_framework); - supra_governance::initialize_for_test(supra_framework,(10 * ONE_APT as u128), 100 - * ONE_APT, 1000,); - supra_governance::initialize_partial_voting(supra_framework); - features::change_feature_flags_for_testing(supra_framework, - vector[ - features::get_partial_governance_voting(), - features::get_delegation_pool_partial_governance_voting()], - vector[]); - let delegator_address = vector[@0x010, @0x020]; - let principle_stake = vector[0, 0]; - let coin = stake::mint_coins(0); - let principle_lockup_time = 0; - initialize_test_validator(validator, - 100 * ONE_APT, - true, - false, - 0, - delegator_address, - principle_stake, - coin, - option::none(), - vector[1], - 1, - principle_lockup_time, - LOCKUP_CYCLE_SECONDS - ); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - // Delegation pool is created after partial governance voting feature flag is enabled. So this delegation - // pool is created with partial governance voting enabled. - assert!(stake::get_delegated_voter(pool_address) == pool_address, 1); - assert!(partial_governance_voting_enabled(pool_address), 1); - - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - let delegator2_address = signer::address_of(delegator2); - account::create_account_for_test(delegator2_address); - let voter1_address = signer::address_of(voter1); - account::create_account_for_test(voter1_address); - let voter2_address = signer::address_of(voter2); - account::create_account_for_test(voter2_address); - - stake::mint(delegator1, 110 * ONE_APT); - add_stake(delegator1, pool_address, 10 * ONE_APT); - stake::mint(delegator2, 110 * ONE_APT); - add_stake(delegator2, pool_address, 90 * ONE_APT); - // By default, the voter of a delegator is itself. - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 10 * ONE_APT, - 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator2_address) == 90 * ONE_APT, - 1); - - end_aptos_epoch(); - // Reward rate is 0. No reward so no voting power change. - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 10 * ONE_APT, - 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator2_address) == 90 * ONE_APT, - 1); - - // Delegator1 delegates its voting power to voter1 but it takes 1 lockup cycle to take effects. So no voting power - // change now. - delegate_voting_power(delegator1, pool_address, voter1_address); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 10 * ONE_APT, - 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator2_address) == 90 * ONE_APT, - 1); - - // 1 epoch passed but the lockup cycle hasn't ended. No voting power change. - end_aptos_epoch(); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 10 * ONE_APT, - 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator2_address) == 90 * ONE_APT, - 1); - - // One cycle passed. The voter change takes effects. - timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); - end_aptos_epoch(); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 10 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator2_address) == 90 * ONE_APT, - 1); - - // Delegator2 delegates its voting power to voter1 but it takes 1 lockup cycle to take effects. So no voting power - // change now. - delegate_voting_power(delegator2, pool_address, voter1_address); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 10 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator2_address) == 90 * ONE_APT, - 1); - - // One cycle passed. The voter change takes effects. - timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); - end_aptos_epoch(); - assert!(calculate_and_update_delegator_voter(pool_address, delegator2_address) == voter1_address, - 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 100 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator2_address) == 0, 1); - - // delegator1 changes to voter2 then change back. delegator2 changes to voter1. - // No voting power change in this lockup cycle. - delegate_voting_power(delegator1, pool_address, voter2_address); - delegate_voting_power(delegator2, pool_address, voter2_address); - delegate_voting_power(delegator1, pool_address, voter1_address); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 100 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator2_address) == 0, 1); - - // One cycle passed. The voter change takes effects. - timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); - end_aptos_epoch(); - assert!(calculate_and_update_delegator_voter(pool_address, delegator1_address) == voter1_address, - 1); - assert!(calculate_and_update_delegator_voter(pool_address, delegator2_address) == voter2_address, - 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 10 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == - 90 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator2_address) == 0, 1); - - // delegator1 adds stake to the pool. Voting power changes immediately. - add_stake(delegator1, pool_address, 90 * ONE_APT); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 100 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == - 90 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator2_address) == 0, 1); - - // delegator1 unlocks stake and changes its voter. No voting power change until next lockup cycle. - unlock(delegator1, pool_address, 90 * ONE_APT); - delegate_voting_power(delegator1, pool_address, voter2_address); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 100 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == - 90 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator2_address) == 0, 1); - - // One cycle passed. The voter change takes effects. - timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); - end_aptos_epoch(); - // Withdrawl inactive shares will not change voting power. - withdraw(delegator1, pool_address, 45 * ONE_APT); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == - 100 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator2_address) == 0, 1); - - // voter2 adds stake for itself. Voting power changes immediately. - stake::mint(voter2, 110 * ONE_APT); - add_stake(voter2, pool_address, 10 * ONE_APT); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == - 110 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator2_address) == 0, 1); - } - - #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, voter1 = @0x030)] - public entry fun test_voting_power_change_for_existing_delegation_pool( - supra_framework: &signer, - validator: &signer, - delegator1: &signer, - voter1: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { - initialize_for_test_no_reward(supra_framework); - supra_governance::initialize_for_test(supra_framework,(10 * ONE_APT as u128), 100 - * ONE_APT, 1000,); - supra_governance::initialize_partial_voting(supra_framework); - let delegator_address = vector[@0x111]; - let principle_stake = vector[100 * ONE_APT]; - let coin = stake::mint_coins(100 * ONE_APT); - let principle_lockup_time = 0; - initialize_test_validator(validator, - 100 * ONE_APT, - true, - false, - 0, - delegator_address, - principle_stake, - coin, - option::none(), - vector[2, 2, 3], - 10, - principle_lockup_time, - 12 - ); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - // Delegation pool is created before partial governance voting feature flag is enabled. So this delegation - // pool's voter is its owner. - assert!(stake::get_delegated_voter(pool_address) == validator_address, 1); - assert!(!partial_governance_voting_enabled(pool_address), 1); - - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - let voter1_address = signer::address_of(voter1); - account::create_account_for_test(voter1_address); - - stake::mint(delegator1, 110 * ONE_APT); - add_stake(delegator1, pool_address, 10 * ONE_APT); - - // Enable partial governance voting feature flag. - features::change_feature_flags_for_testing(supra_framework, - vector[ - features::get_partial_governance_voting(), - features::get_delegation_pool_partial_governance_voting()], - vector[]); - // Voter doens't change until enabling partial governance voting on this delegation pool. - assert!(stake::get_delegated_voter(pool_address) == validator_address, 1); - // Enable partial governance voting on this delegation pool. - enable_partial_governance_voting(pool_address); - assert!(stake::get_delegated_voter(pool_address) == pool_address, 1); - assert!(partial_governance_voting_enabled(pool_address), 1); - - // By default, the voter of a delegator is itself. - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 10 * ONE_APT, - 1); - - // Delegator1 delegates its voting power to voter1. - // It takes 1 cycle to take effect. No immediate change. - delegate_voting_power(delegator1, pool_address, voter1_address); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 10 * ONE_APT, - 1); - - // One cycle passed. The voter change takes effects. - timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); - end_aptos_epoch(); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 10 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 0, 1); - } - - #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, delegator2 = @0x020, voter1 = @0x030, voter2 = @0x040)] - public entry fun test_voting_power_change_for_rewards( - supra_framework: &signer, - validator: &signer, - delegator1: &signer, - delegator2: &signer, - voter1: &signer, - voter2: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { - initialize_for_test_custom(supra_framework, 100 * ONE_APT, 10000 * ONE_APT, - LOCKUP_CYCLE_SECONDS, true, 100, 100, 1000000); - supra_governance::initialize_for_test(supra_framework,(10 * ONE_APT as u128), 100 - * ONE_APT, 1000,); - supra_governance::initialize_partial_voting(supra_framework); - features::change_feature_flags_for_testing(supra_framework, - vector[ - features::get_partial_governance_voting(), - features::get_delegation_pool_partial_governance_voting()], - vector[]); - let delegator_address = vector[@0x010, @0x020]; - let principle_stake = vector[0, 0]; - let principle_lockup_time = 0; - let coin = stake::mint_coins(0); - // 50% commission rate - initialize_test_validator(validator, - 100 * ONE_APT, - true, - false, - 5000, - delegator_address, - principle_stake, - coin, - option::none(), - vector[2, 2, 3], - 10, - principle_lockup_time, - 12 - ); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - // Delegation pool is created after partial governance voting feature flag is enabled. So this delegation - // pool is created with partial governance voting enabled. - assert!(stake::get_delegated_voter(pool_address) == pool_address, 1); - assert!(partial_governance_voting_enabled(pool_address), 1); - - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - let delegator2_address = signer::address_of(delegator2); - account::create_account_for_test(delegator2_address); - let voter1_address = signer::address_of(voter1); - account::create_account_for_test(voter1_address); - let voter2_address = signer::address_of(voter2); - account::create_account_for_test(voter2_address); - - stake::mint(delegator1, 110 * ONE_APT); - add_stake(delegator1, pool_address, 10 * ONE_APT); - stake::mint(delegator2, 110 * ONE_APT); - add_stake(delegator2, pool_address, 90 * ONE_APT); - // By default, the voter of a delegator is itself. - assert!(calculate_and_update_voter_total_voting_power(pool_address, - validator_address) == 100 * ONE_APT, - 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 10 * ONE_APT, - 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator2_address) == 90 * ONE_APT, - 1); - - // One epoch is passed. Delegators earn no reward because their stake was inactive. - end_aptos_epoch(); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - validator_address) == 100 * ONE_APT, - 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 10 * ONE_APT, - 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator2_address) == 90 * ONE_APT, - 1); - - // 2 epoches are passed. Delegators earn reward and voting power increases. Operator earns reward and - // commission. Because there is no operation during these 2 epoches. Operator's commission is not compounded. - end_aptos_epoch(); - end_aptos_epoch(); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - validator_address) == 550 * ONE_APT, - 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 25 * ONE_APT, - 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator2_address) == 225 * ONE_APT, - 1); - - // Another epoch is passed. Voting power chage due to reward is correct even if delegator1 and delegator2 change its voter. - delegate_voting_power(delegator1, pool_address, voter1_address); - delegate_voting_power(delegator2, pool_address, voter1_address); - timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); - end_aptos_epoch(); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - validator_address) == 122499999999, - 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter1_address) == - 375 * ONE_APT, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, voter2_address) == - 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 0, 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator2_address) == 0, 1); - } - - #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, delegator2 = @0x020, voter1 = @0x030, voter2 = @0x040)] - public entry fun test_voting_power_change_already_voted_before_partial( - supra_framework: &signer, - validator: &signer, - delegator1: &signer, - delegator2: &signer, - voter1: &signer, - voter2: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { - initialize_for_test_no_reward(supra_framework); - let delegator_address = vector[@0x111]; - let principle_stake = vector[100 * ONE_APT]; - let principle_lockup_time = 0; - let coin = stake::mint_coins(100 * ONE_APT); - - // partial voing hasn't been enabled yet. A proposal has been created by the validator. - let proposal1_id = setup_vote(supra_framework, - validator, - false, - delegator_address, - principle_stake, - coin, - option::none(), - vector[2, 2, 3], - 10, - principle_lockup_time, - 12, - ); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - let delegator2_address = signer::address_of(delegator2); - account::create_account_for_test(delegator2_address); - let voter1_address = signer::address_of(voter1); - account::create_account_for_test(voter1_address); - let voter2_address = signer::address_of(voter2); - account::create_account_for_test(voter2_address); - - stake::mint(delegator1, 110 * ONE_APT); - add_stake(delegator1, pool_address, 10 * ONE_APT); - stake::mint(delegator2, 110 * ONE_APT); - add_stake(delegator2, pool_address, 90 * ONE_APT); - - // Create 2 proposals and vote for proposal1. - let execution_hash = vector::empty(); - vector::push_back(&mut execution_hash, 1); - let proposal2_id = supra_governance::create_proposal_v2_impl(validator, pool_address, - execution_hash, b"", b"", true,); - supra_governance::vote(validator, pool_address, proposal1_id, true); - - // Enable partial governance voting feature flag. - features::change_feature_flags_for_testing(supra_framework, - vector[ - features::get_partial_governance_voting(), - features::get_delegation_pool_partial_governance_voting()], - vector[]); - // Voter doens't change until enabling partial governance voting on this delegation pool. - assert!(stake::get_delegated_voter(pool_address) == validator_address, 1); - // Enable partial governance voting on this delegation pool. - enable_partial_governance_voting(pool_address); - assert!(stake::get_delegated_voter(pool_address) == pool_address, 1); - assert!(partial_governance_voting_enabled(pool_address), 1); - - assert!(calculate_and_update_voter_total_voting_power(pool_address, - validator_address) == 100 * ONE_APT, - 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 10 * ONE_APT, - 1); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator2_address) == 90 * ONE_APT, - 1); - // No one can vote for proposal1 because it's already voted before enabling partial governance voting. - assert!(calculate_and_update_remaining_voting_power(pool_address, validator_address, - proposal1_id) == 0, - 1); - assert!(calculate_and_update_remaining_voting_power(pool_address, delegator1_address, - proposal1_id) == 0, - 1); - assert!(calculate_and_update_remaining_voting_power(pool_address, delegator2_address, - proposal1_id) == 0, - 1); - assert!(calculate_and_update_remaining_voting_power(pool_address, validator_address, - proposal2_id) == 100 * ONE_APT, - 1); - assert!(calculate_and_update_remaining_voting_power(pool_address, delegator1_address, - proposal2_id) == 10 * ONE_APT, - 1); - assert!(calculate_and_update_remaining_voting_power(pool_address, delegator2_address, - proposal2_id) == 90 * ONE_APT, - 1); - - // Delegator1 tries to use 50 APT to vote on proposal2, but it only has 10 APT. So only 10 APT voting power is used. - vote(delegator1, pool_address, proposal2_id, 50 * ONE_APT, true); - assert!(calculate_and_update_remaining_voting_power(pool_address, delegator1_address, - proposal2_id) == 0, - 1); - - add_stake(delegator1, pool_address, 60 * ONE_APT); - assert!(calculate_and_update_voter_total_voting_power(pool_address, - delegator1_address) == 70 * ONE_APT, - 1); - vote(delegator1, pool_address, proposal2_id, 25 * ONE_APT, true); - assert!(calculate_and_update_remaining_voting_power(pool_address, delegator1_address, - proposal2_id) == 35 * ONE_APT, - 1); - vote(delegator1, pool_address, proposal2_id, 30 * ONE_APT, false); - assert!(calculate_and_update_remaining_voting_power(pool_address, delegator1_address, - proposal2_id) == 5 * ONE_APT, - 1); - } - - #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, voter1 = @0x030)] - #[expected_failure(abort_code = 0x10010, location = Self)] - public entry fun test_vote_should_failed_if_already_voted_before_enable_partial_voting_flag( - supra_framework: &signer, - validator: &signer, - delegator1: &signer, - voter1: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { - initialize_for_test_no_reward(supra_framework); - - let delegator_address = vector[@0x111]; - let principle_stake = vector[100 * ONE_APT]; - let principle_lockup_time = 0; - let coin = stake::mint_coins(100 * ONE_APT); - - // partial voing hasn't been enabled yet. A proposal has been created by the validator. - let proposal1_id = setup_vote(supra_framework, - validator, - false, - delegator_address, - principle_stake, - coin, - option::none(), - vector[2, 2, 3], - 10, - principle_lockup_time, - 12 - ); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - let voter1_address = signer::address_of(voter1); - account::create_account_for_test(voter1_address); - - stake::mint(delegator1, 110 * ONE_APT); - add_stake(delegator1, pool_address, 10 * ONE_APT); - end_aptos_epoch(); - - supra_governance::vote(validator, pool_address, proposal1_id, true); - - // Enable partial governance voting feature flag. - features::change_feature_flags_for_testing(supra_framework, - vector[ - features::get_partial_governance_voting(), - features::get_delegation_pool_partial_governance_voting()], - vector[]); - // Enable partial governance voting on this delegation pool. - enable_partial_governance_voting(pool_address); - - vote(delegator1, pool_address, proposal1_id, 10 * ONE_APT, true); - } - - #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, voter1 = @0x030)] - #[expected_failure(abort_code = 0x10011, location = Self)] - public entry fun test_vote_should_failed_if_already_voted_before_enable_partial_voting_on_pool( - supra_framework: &signer, - validator: &signer, - delegator1: &signer, - voter1: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { - initialize_for_test_no_reward(supra_framework); - let delegator_address = vector[@0x111]; - let principle_stake = vector[100 * ONE_APT]; - let principle_lockup_time = 0; - let coin = stake::mint_coins(100 * ONE_APT); - // partial voing hasn't been enabled yet. A proposal has been created by the validator. - let proposal1_id = setup_vote(supra_framework, - validator, - false, - delegator_address, - principle_stake, - coin, - option::none(), - vector[2, 2, 3], - 10, - principle_lockup_time, - 12 - ); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - let voter1_address = signer::address_of(voter1); - account::create_account_for_test(voter1_address); - - stake::mint(delegator1, 110 * ONE_APT); - add_stake(delegator1, pool_address, 10 * ONE_APT); - end_aptos_epoch(); - - // Enable partial governance voting feature flag. - features::change_feature_flags_for_testing(supra_framework, - vector[ - features::get_partial_governance_voting(), - features::get_delegation_pool_partial_governance_voting()], - vector[]); - - // The operator voter votes on the proposal after partial governace voting flag is enabled but before partial voting is enabled on the pool. - supra_governance::vote(validator, pool_address, proposal1_id, true); - - // Enable partial governance voting on this delegation pool. - enable_partial_governance_voting(pool_address); - - add_stake(delegator1, pool_address, 10 * ONE_APT); - vote(delegator1, pool_address, proposal1_id, 10 * ONE_APT, true); - } - - #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010)] - #[expected_failure(abort_code = 0x10010, location = Self)] - public entry fun test_vote_should_failed_if_no_stake( - supra_framework: &signer, validator: &signer, delegator1: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { - initialize_for_test_no_reward(supra_framework); - let delegator_address = vector[@0x010]; - let principle_stake = vector[0]; - let principle_lockup_time = 0; - let coin = stake::mint_coins(0); - - // partial voing hasn't been enabled yet. A proposal has been created by the validator. - let proposal1_id = setup_vote(supra_framework, - validator, - true, - delegator_address, - principle_stake, - coin, - option::none(), - vector[2, 2, 3], - 10, - principle_lockup_time, - 12, - ); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - - // Delegator1 has no stake. Abort. - vote(delegator1, pool_address, proposal1_id, 10 * ONE_APT, true); - } - - #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, voter1 = @0x030)] - public entry fun test_delegate_voting_power_should_pass_even_if_no_stake( - supra_framework: &signer, - validator: &signer, - delegator1: &signer, - voter1: &signer, - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { - initialize_for_test_no_reward(supra_framework); - let delegator_address = vector[@0x010]; - let principle_stake = vector[0]; - let principle_lockup_time = 0; - let coin = stake::mint_coins(0); - // partial voing hasn't been enabled yet. A proposal has been created by the validator. - setup_vote(supra_framework, - validator, - true, - delegator_address, - principle_stake, - coin, - option::none(), - vector[2, 2, 3], - 10, - principle_lockup_time, - 12 - ); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - let delegator1_address = signer::address_of(delegator1); - account::create_account_for_test(delegator1_address); - - // Delegator1 has no stake. Abort. - delegate_voting_power(delegator1, pool_address, signer::address_of(voter1)); - } - #[test(staker = @0xe256f4f4e2986cada739e339895cf5585082ff247464cab8ec56eea726bd2263)] public entry fun test_get_expected_stake_pool_address(staker: address) { let pool_address = get_expected_stake_pool_address(staker, vector[0x42, 0x42]); @@ -5371,63 +4408,6 @@ module supra_framework::pbo_delegation_pool { } } - #[test_only] - public fun setup_vote( - supra_framework: &signer, - validator: &signer, - enable_partial_voting: bool, - delegator_address: vector
, - principle_stake: vector, - coin: Coin, - multisig_admin: option::Option
, - unlock_numerators: vector, - unlock_denominator: u64, - principle_lockup_time: u64, - unlock_duration: u64, - ): u64 acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { - supra_governance::initialize_for_test(supra_framework,(10 * ONE_APT as u128), 100 - * ONE_APT, 1000,); - supra_governance::initialize_partial_voting(supra_framework); - - initialize_test_validator(validator, - 100 * ONE_APT, - true, - false, - 0, - delegator_address, - principle_stake, - coin, - multisig_admin, - unlock_numerators, - unlock_denominator, - principle_lockup_time, - unlock_duration - ); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - // Delegation pool is created before partial governance voting feature flag is enabled. So this delegation - // pool's voter is its owner. - assert!(stake::get_delegated_voter(pool_address) == validator_address, 1); - assert!(!partial_governance_voting_enabled(pool_address), 1); - end_aptos_epoch(); - - // Create 1 proposals and vote for proposal1. - let execution_hash = vector::empty(); - vector::push_back(&mut execution_hash, 1); - let proposal_id = supra_governance::create_proposal_v2_impl(validator, pool_address, - execution_hash, b"", b"", true,); - if (enable_partial_voting) { - features::change_feature_flags_for_testing(supra_framework, - vector[ - features::get_partial_governance_voting(), - features::get_delegation_pool_partial_governance_voting()], - vector[]); - enable_partial_governance_voting(pool_address); - }; - proposal_id - } - #[test_only] public fun total_coins_inactive(pool_address: address): u64 acquires DelegationPool { borrow_global(pool_address).total_coins_inactive @@ -5987,48 +4967,6 @@ module supra_framework::pbo_delegation_pool { assert!(coin::balance(new_delegator_address) == (100 * ONE_APT) - 1, 0); } - #[test(supra_framework = @supra_framework, validator = @0x123, delegator = @0x010)] - /// after replace_delegator new_delegator should be able to vote (if partial_voting is enable), or should be able to delegate voting - public entry fun test_replace_delegation_and_vote_delegate_voting_success( - supra_framework: &signer, - validator: &signer, - delegator :&signer - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { - initialize_for_test(supra_framework); - account::create_account_for_test(signer::address_of(validator)); - let delegator_address = signer::address_of(delegator); - let delegator_address_vec = vector[delegator_address, @0x020]; - let principle_stake = vector[300 * ONE_APT, 200 * ONE_APT]; - let coin = stake::mint_coins(500 * ONE_APT); - let principle_lockup_time = 0; - let multisig = generate_multisig_account(validator, vector[@0x12134], 2); - let multisig_signer = account::create_signer_for_test(multisig); - - // partial voing hasn't been enabled yet. A proposal has been created by the validator. - let proposal1_id = setup_vote(supra_framework, - validator, - true, - delegator_address_vec, - principle_stake, - coin, - option::some(multisig), - vector[2, 2, 3], - 10, - principle_lockup_time, - 12 - ); - - let validator_address = signer::address_of(validator); - let pool_address = get_owned_pool_address(validator_address); - let new_delegator_address = @0x0101; - let new_delegator_address_signer = &account::create_signer_for_test(new_delegator_address); - replace_delegator(&multisig_signer, pool_address, delegator_address, new_delegator_address); - - vote(new_delegator_address_signer, pool_address, proposal1_id, 10 * ONE_APT, true); - let result = calculate_and_update_remaining_voting_power(pool_address, new_delegator_address, proposal1_id); - assert!(result == 290 * ONE_APT, 1); - } - #[test(supra_framework = @supra_framework, validator = @0x123, delegator = @0x010)] /// if delegator is not part of one of the principle stake holder, they can unlock/withdraw without restriction public entry fun test_unlock_withdraw_delegator_not_part_of_principle_stake_success( diff --git a/aptos-move/framework/supra-framework/sources/supra_coin.move b/aptos-move/framework/supra-framework/sources/supra_coin.move index 884c01ff87398..58e9849449713 100644 --- a/aptos-move/framework/supra-framework/sources/supra_coin.move +++ b/aptos-move/framework/supra-framework/sources/supra_coin.move @@ -8,7 +8,6 @@ module supra_framework::supra_coin { use std::option::{Self, Option}; use supra_framework::coin::{Self, BurnCapability, MintCapability}; - //use supra_framework::coin; use supra_framework::system_addresses; friend supra_framework::genesis; @@ -197,6 +196,23 @@ module supra_framework::supra_coin { (burn_cap, mint_cap) } + #[test_only] + fun initialize_with_aggregator(supra_framework: &signer) { + let (burn_cap, freeze_cap, mint_cap) =coin::initialize_with_parallelizable_supply_with_limit( + supra_framework, + string::utf8(b"Supra Coin"), + string::utf8(b"SUP"), + 8, // decimals + true, // monitor_supply + MAX_SUPRA_COIN_SUPPLY, + ); + coin::destroy_freeze_cap(freeze_cap); + move_to(supra_framework, SupraCoinCapabilities { + burn_cap, + mint_cap, + }); + } + // This is particularly useful if the aggregator_factory is already initialized via another call path. #[test_only] public fun initialize_for_test_without_aggregator_factory( @@ -208,51 +224,100 @@ module supra_framework::supra_coin { (burn_cap, mint_cap) } + #[test_only] + struct SupraCoinCapabilities has key { + burn_cap: BurnCapability, + mint_cap: MintCapability, + } - #[test_only] - use supra_framework::supra_account; - - // #[test(source = @0x1, destination = @0x2)] - // public entry fun end_to_end( - // source: signer, - // destination: signer, - // ) { - // let source_addr = signer::address_of(&source); - // account::create_account_for_test(source_addr); - // let destination_addr = signer::address_of(&destination); - // account::create_account_for_test(destination_addr); - - // let name = string::utf8(b"Fake money"); - // let symbol = string::utf8(b"FMD"); - - // aggregator_factory::initialize_aggregator_factory_for_test(&source); - // let (burn_cap, mint_cap) = initialize( - // &source, - // ); - // coin::register(&source); - // coin::register(&destination); - // assert!(*option::borrow(&coin::supply()) == 0, 0); - - // assert!(coin::name() == name, 1); - // assert!(coin::symbol() == symbol, 2); - // assert!(coin::decimals() == 18, 3); - - // let coins_minted = coin::mint(100, &mint_cap); - // coin::deposit(source_addr, coins_minted); - // coin::transfer(&source, destination_addr, 50); - - // assert!(coin::balance(source_addr) == 50, 4); - // assert!(coin::balance(destination_addr) == 50, 5); - // assert!(*option::borrow(&coin::supply()) == 100, 6); - - // let coin = coin::withdraw(&source, 10); - // assert!(coin::value(&coin) == 10, 7); - // coin::burn(coin, &burn_cap); - // assert!(*option::borrow(&coin::supply()) == 90, 8); - - // move_to(&source, SupraCoinCapabilities { - // burn_cap, - // mint_cap, - // }); - // } + #[test(source = @0x1, destination = @0x2)] + public entry fun end_to_end( + source: signer, + destination: signer, + ) { + let source_addr = signer::address_of(&source); + account::create_account_for_test(source_addr); + let destination_addr = signer::address_of(&destination); + account::create_account_for_test(destination_addr); + + let name = string::utf8(b"Supra Coin"); + let symbol = string::utf8(b"SUP"); + + aggregator_factory::initialize_aggregator_factory_for_test(&source); + let (burn_cap, mint_cap) = initialize( + &source, + ); + coin::register(&source); + coin::register(&destination); + assert!(*option::borrow(&coin::supply()) == 0, 0); + + assert!(coin::name() == name, 1); + assert!(coin::symbol() == symbol, 2); + assert!(coin::decimals() == 8, 3); + + let coins_minted = coin::mint(100, &mint_cap); + coin::deposit(source_addr, coins_minted); + coin::transfer(&source, destination_addr, 50); + + assert!(coin::balance(source_addr) == 50, 4); + assert!(coin::balance(destination_addr) == 50, 5); + assert!(*option::borrow(&coin::supply()) == 100, 6); + + let coin = coin::withdraw(&source, 10); + assert!(coin::value(&coin) == 10, 7); + coin::burn(coin, &burn_cap); + assert!(*option::borrow(&coin::supply()) == 90, 8); + + move_to(&source, SupraCoinCapabilities { + burn_cap, + mint_cap, + }); + } + + #[test(source = @0x1, destination = @0x2)] + public entry fun test_mint_no_overflow( + source: signer, + destination: signer, + ){ + let source_addr = signer::address_of(&source); + account::create_account_for_test(source_addr); + let destination_addr = signer::address_of(&destination); + account::create_account_for_test(destination_addr); + + aggregator_factory::initialize_aggregator_factory_for_test(&source); + let (burn_cap, mint_cap) = initialize( + &source, + ); + coin::register(&source); + coin::register(&destination); + assert!(*option::borrow(&coin::supply()) == 0, 0); + assert!(*option::borrow(&coin::supply()) == 0, 0); + + let coins_minted = coin::mint((MAX_SUPRA_COIN_SUPPLY as u64), &mint_cap); + coin::deposit(source_addr, coins_minted); + coin::transfer(&source, destination_addr, (MAX_SUPRA_COIN_SUPPLY as u64)); + coin::destroy_burn_cap(burn_cap); + coin::destroy_mint_cap(mint_cap); + } + + #[test(source = @0x1)] + #[expected_failure(abort_code = 0x20001, location = supra_framework::aggregator)] + public entry fun test_mint_overflow( + source: signer, + ) { + let source_addr = signer::address_of(&source); + account::create_account_for_test(source_addr); + + aggregator_factory::initialize_aggregator_factory_for_test(&source); + let (burn_cap, mint_cap) = initialize( + &source, + ); + coin::register(&source); + assert!(*option::borrow(&coin::supply()) == 0, 0); + + let coins_minted = coin::mint((MAX_SUPRA_COIN_SUPPLY as u64)+1, &mint_cap); + coin::deposit(source_addr, coins_minted); + coin::destroy_burn_cap(burn_cap); + coin::destroy_mint_cap(mint_cap); + } } diff --git a/aptos-move/framework/supra-framework/sources/supra_governance.move b/aptos-move/framework/supra-framework/sources/supra_governance.move index 243a3e0e575ad..8876523348599 100644 --- a/aptos-move/framework/supra-framework/sources/supra_governance.move +++ b/aptos-move/framework/supra-framework/sources/supra_governance.move @@ -11,42 +11,24 @@ /// on a proposal multiple times as long as the total voting power of these votes doesn't exceed its total voting power. module supra_framework::supra_governance { use std::error; - use std::option; use std::signer; use std::string::{Self, String, utf8}; use std::vector; use std::features; - use aptos_std::math64::min; use aptos_std::simple_map::{Self, SimpleMap}; - use aptos_std::smart_table::{Self, SmartTable}; - use aptos_std::table::{Self, Table}; use supra_framework::account::{Self, SignerCapability, create_signer_with_capability}; - use supra_framework::coin; use supra_framework::event::{Self, EventHandle}; use supra_framework::governance_proposal::{Self, GovernanceProposal}; - use supra_framework::stake; - use supra_framework::staking_config; use supra_framework::system_addresses; - use supra_framework::supra_coin::{Self, SupraCoin}; + use supra_framework::supra_coin; use supra_framework::consensus_config; use supra_framework::randomness_config; use supra_framework::reconfiguration_with_dkg; use supra_framework::timestamp; - use supra_framework::voting; use supra_framework::multisig_voting; - /// The specified stake pool does not have sufficient stake to create a proposal - const EINSUFFICIENT_PROPOSER_STAKE: u64 = 1; - /// This account is not the designated voter of the specified stake pool - const ENOT_DELEGATED_VOTER: u64 = 2; - /// The specified stake pool does not have long enough remaining lockup to create a proposal or vote - const EINSUFFICIENT_STAKE_LOCKUP: u64 = 3; - /// The specified stake pool has already been used to vote on the same proposal - const EALREADY_VOTED: u64 = 4; - /// The specified stake pool must be part of the validator set - const ENO_VOTING_POWER: u64 = 5; /// Proposal is not ready to be resolved. Waiting on time or votes const EPROPOSAL_NOT_RESOLVABLE_YET: u64 = 6; /// The proposal has not been resolved yet @@ -57,12 +39,6 @@ module supra_framework::supra_governance { const EMETADATA_HASH_TOO_LONG: u64 = 10; /// Account is not authorized to call this function. const EUNAUTHORIZED: u64 = 11; - /// The stake pool is using voting power more than it has. - const EVOTING_POWER_OVERFLOW: u64 = 12; - /// Partial voting feature hasn't been properly initialized. - const EPARTIAL_VOTING_NOT_INITIALIZED: u64 = 13; - /// The proposal in the argument is not a partial voting proposal. - const ENOT_PARTIAL_VOTING_PROPOSAL: u64 = 14; /// The account does not have permission to propose or vote const EACCOUNT_NOT_AUTHORIZED: u64 = 15; /// Proposal is expired @@ -75,8 +51,6 @@ module supra_framework::supra_governance { /// This matches the same enum const in voting. We have to duplicate it as Move doesn't have support for enums yet. const PROPOSAL_STATE_SUCCEEDED: u64 = 1; - const MAX_U64: u64 = 18446744073709551615; - /// Proposal metadata attribute keys. const METADATA_LOCATION_KEY: vector = b"metadata_location"; const METADATA_HASH_KEY: vector = b"metadata_hash"; @@ -86,95 +60,12 @@ module supra_framework::supra_governance { signer_caps: SimpleMap, } - /// Configurations of the AptosGovernance, set during Genesis and can be updated by the same process offered - /// by this AptosGovernance module. - struct GovernanceConfig has key { - min_voting_threshold: u128, - required_proposer_stake: u64, - voting_duration_secs: u64, - } - - struct RecordKey has copy, drop, store { - stake_pool: address, - proposal_id: u64, - } - - /// Records to track the proposals each stake pool has been used to vote on. - struct VotingRecords has key { - votes: Table - } - - /// Records to track the voting power usage of each stake pool on each proposal. - struct VotingRecordsV2 has key { - votes: SmartTable - } - /// Used to track which execution script hashes have been approved by governance. /// This is required to bypass cases where the execution scripts exceed the size limit imposed by mempool. struct ApprovedExecutionHashes has key { hashes: SimpleMap>, } - /// Events generated by interactions with the AptosGovernance module. - struct GovernanceEvents has key { - create_proposal_events: EventHandle, - update_config_events: EventHandle, - vote_events: EventHandle, - } - - /// Event emitted when a proposal is created. - struct CreateProposalEvent has drop, store { - proposer: address, - stake_pool: address, - proposal_id: u64, - execution_hash: vector, - proposal_metadata: SimpleMap>, - } - - /// Event emitted when there's a vote on a proposa; - struct VoteEvent has drop, store { - proposal_id: u64, - voter: address, - stake_pool: address, - num_votes: u64, - should_pass: bool, - } - - /// Event emitted when the governance configs are updated. - struct UpdateConfigEvent has drop, store { - min_voting_threshold: u128, - required_proposer_stake: u64, - voting_duration_secs: u64, - } - - #[event] - /// Event emitted when a proposal is created. - struct CreateProposal has drop, store { - proposer: address, - stake_pool: address, - proposal_id: u64, - execution_hash: vector, - proposal_metadata: SimpleMap>, - } - - #[event] - /// Event emitted when there's a vote on a proposa; - struct Vote has drop, store { - proposal_id: u64, - voter: address, - stake_pool: address, - num_votes: u64, - should_pass: bool, - } - - #[event] - /// Event emitted when the governance configs are updated. - struct UpdateConfig has drop, store { - min_voting_threshold: u128, - required_proposer_stake: u64, - voting_duration_secs: u64, - } - /// Configurations of the SupraGovernance, set during Genesis and can be updated by the same process offered /// by this SupraGovernance module. struct SupraGovernanceConfig has key { @@ -237,7 +128,6 @@ module supra_framework::supra_governance { voters: vector
, } - /// Can be called during genesis or by the governance itself. /// Stores the signer capability for a given address. public fun store_signer_cap( @@ -259,33 +149,6 @@ module supra_framework::supra_governance { simple_map::add(signer_caps, signer_address, signer_cap); } - fun old_initialize( - supra_framework: &signer, - min_voting_threshold: u128, - required_proposer_stake: u64, - voting_duration_secs: u64, - ) { - system_addresses::assert_supra_framework(supra_framework); - - voting::register(supra_framework); - move_to(supra_framework, GovernanceConfig { - voting_duration_secs, - min_voting_threshold, - required_proposer_stake, - }); - move_to(supra_framework, GovernanceEvents { - create_proposal_events: account::new_event_handle(supra_framework), - update_config_events: account::new_event_handle(supra_framework), - vote_events: account::new_event_handle(supra_framework), - }); - move_to(supra_framework, VotingRecords { - votes: table::new(), - }); - move_to(supra_framework, ApprovedExecutionHashes { - hashes: simple_map::create>() - }); - } - /// Initializes the state for Aptos Governance. Can only be called during Genesis with a signer /// for the supra_framework (0x1) account. /// This function is private because it's called directly from the vm. @@ -317,39 +180,6 @@ module supra_framework::supra_governance { /// Update the governance configurations. This can only be called as part of resolving a proposal in this same /// AptosGovernance. - public fun update_governance_config( - supra_framework: &signer, - min_voting_threshold: u128, - required_proposer_stake: u64, - voting_duration_secs: u64, - ) acquires GovernanceConfig, GovernanceEvents { - system_addresses::assert_supra_framework(supra_framework); - - let governance_config = borrow_global_mut(@supra_framework); - governance_config.voting_duration_secs = voting_duration_secs; - governance_config.min_voting_threshold = min_voting_threshold; - governance_config.required_proposer_stake = required_proposer_stake; - - if (std::features::module_event_migration_enabled()) { - event::emit( - UpdateConfig { - min_voting_threshold, - required_proposer_stake, - voting_duration_secs - }, - ) - }; - let events = borrow_global_mut(@supra_framework); - event::emit_event( - &mut events.update_config_events, - UpdateConfigEvent { - min_voting_threshold, - required_proposer_stake, - voting_duration_secs - }, - ); - } - public fun update_supra_governance_config( supra_framework: &signer, voting_duration_secs: u64, @@ -386,204 +216,21 @@ module supra_framework::supra_governance { ); } - /// Initializes the state for Aptos Governance partial voting. Can only be called through Aptos governance - /// proposals with a signer for the supra_framework (0x1) account. - public fun initialize_partial_voting( - supra_framework: &signer, - ) { - system_addresses::assert_supra_framework(supra_framework); - - move_to(supra_framework, VotingRecordsV2 { - votes: smart_table::new(), - }); - } - - #[view] - public fun get_voting_duration_secs(): u64 acquires GovernanceConfig { - borrow_global(@supra_framework).voting_duration_secs - } - - #[view] - public fun get_min_voting_threshold(): u128 acquires GovernanceConfig { - borrow_global(@supra_framework).min_voting_threshold - } - #[view] - public fun get_required_proposer_stake(): u64 acquires GovernanceConfig { - borrow_global(@supra_framework).required_proposer_stake + public fun get_voting_duration_secs(): u64 acquires SupraGovernanceConfig { + borrow_global(@supra_framework).voting_duration_secs } #[view] - /// Return true if a stake pool has already voted on a proposal before partial governance voting is enabled. - public fun has_entirely_voted(stake_pool: address, proposal_id: u64): bool acquires VotingRecords { - let record_key = RecordKey { - stake_pool, - proposal_id, - }; - // If a stake pool has already voted on a proposal before partial governance voting is enabled, - // there is a record in VotingRecords. - let voting_records = borrow_global(@supra_framework); - table::contains(&voting_records.votes, record_key) + public fun get_min_voting_threshold(): u64 acquires SupraGovernanceConfig { + borrow_global(@supra_framework).min_voting_threshold } #[view] - /// Return remaining voting power of a stake pool on a proposal. - /// Note: a stake pool's voting power on a proposal could increase over time(e.g. rewards/new stake). - public fun get_remaining_voting_power( - stake_pool: address, - proposal_id: u64 - ): u64 acquires VotingRecords, VotingRecordsV2 { - assert_voting_initialization(); - - let proposal_expiration = voting::get_proposal_expiration_secs( - @supra_framework, - proposal_id - ); - let lockup_until = stake::get_lockup_secs(stake_pool); - // The voter's stake needs to be locked up at least as long as the proposal's expiration. - // Also no one can vote on a expired proposal. - if (proposal_expiration > lockup_until || timestamp::now_seconds() > proposal_expiration) { - return 0 - }; - - // If a stake pool has already voted on a proposal before partial governance voting is enabled, the stake pool - // cannot vote on the proposal even after partial governance voting is enabled. - if (has_entirely_voted(stake_pool, proposal_id)) { - return 0 - }; - let record_key = RecordKey { - stake_pool, - proposal_id, - }; - let used_voting_power = 0u64; - if (features::partial_governance_voting_enabled()) { - let voting_records_v2 = borrow_global(@supra_framework); - used_voting_power = *smart_table::borrow_with_default(&voting_records_v2.votes, record_key, &0); - }; - get_voting_power(stake_pool) - used_voting_power - } - - /// Create a single-step proposal with the backing `stake_pool`. - /// @param execution_hash Required. This is the hash of the resolution script. When the proposal is resolved, - /// only the exact script with matching hash can be successfully executed. - public entry fun create_proposal( - proposer: &signer, - stake_pool: address, - execution_hash: vector, - metadata_location: vector, - metadata_hash: vector, - ) acquires GovernanceConfig, GovernanceEvents { - create_proposal_v2(proposer, stake_pool, execution_hash, metadata_location, metadata_hash, false); - } - - /// Create a single-step or multi-step proposal with the backing `stake_pool`. - /// @param execution_hash Required. This is the hash of the resolution script. When the proposal is resolved, - /// only the exact script with matching hash can be successfully executed. - public entry fun create_proposal_v2( - proposer: &signer, - stake_pool: address, - execution_hash: vector, - metadata_location: vector, - metadata_hash: vector, - is_multi_step_proposal: bool, - ) acquires GovernanceConfig, GovernanceEvents { - create_proposal_v2_impl( - proposer, - stake_pool, - execution_hash, - metadata_location, - metadata_hash, - is_multi_step_proposal - ); - } - - /// Create a single-step or multi-step proposal with the backing `stake_pool`. - /// @param execution_hash Required. This is the hash of the resolution script. When the proposal is resolved, - /// only the exact script with matching hash can be successfully executed. - /// Return proposal_id when a proposal is successfully created. - public fun create_proposal_v2_impl( - proposer: &signer, - stake_pool: address, - execution_hash: vector, - metadata_location: vector, - metadata_hash: vector, - is_multi_step_proposal: bool, - ): u64 acquires GovernanceConfig, GovernanceEvents { - let proposer_address = signer::address_of(proposer); - assert!( - stake::get_delegated_voter(stake_pool) == proposer_address, - error::invalid_argument(ENOT_DELEGATED_VOTER) - ); - - // The proposer's stake needs to be at least the required bond amount. - let governance_config = borrow_global(@supra_framework); - let stake_balance = get_voting_power(stake_pool); - assert!( - stake_balance >= governance_config.required_proposer_stake, - error::invalid_argument(EINSUFFICIENT_PROPOSER_STAKE), - ); - - // The proposer's stake needs to be locked up at least as long as the proposal's voting period. - let current_time = timestamp::now_seconds(); - let proposal_expiration = current_time + governance_config.voting_duration_secs; - assert!( - stake::get_lockup_secs(stake_pool) >= proposal_expiration, - error::invalid_argument(EINSUFFICIENT_STAKE_LOCKUP), - ); - - // Create and validate proposal metadata. - let proposal_metadata = create_proposal_metadata(metadata_location, metadata_hash); - - // We want to allow early resolution of proposals if more than 50% of the total supply of the network coins - // has voted. This doesn't take into subsequent inflation/deflation (rewards are issued every epoch and gas fees - // are burnt after every transaction), but inflation/delation is very unlikely to have a major impact on total - // supply during the voting period. - let total_voting_token_supply = coin::supply(); - let early_resolution_vote_threshold = option::none(); - if (option::is_some(&total_voting_token_supply)) { - let total_supply = *option::borrow(&total_voting_token_supply); - // 50% + 1 to avoid rounding errors. - early_resolution_vote_threshold = option::some(total_supply / 2 + 1); - }; - - let proposal_id = voting::create_proposal_v2( - proposer_address, - @supra_framework, - governance_proposal::create_proposal(), - execution_hash, - governance_config.min_voting_threshold, - proposal_expiration, - early_resolution_vote_threshold, - proposal_metadata, - is_multi_step_proposal, - ); - - if (std::features::module_event_migration_enabled()) { - event::emit( - CreateProposal { - proposal_id, - proposer: proposer_address, - stake_pool, - execution_hash, - proposal_metadata, - }, - ); - }; - let events = borrow_global_mut(@supra_framework); - event::emit_event( - &mut events.create_proposal_events, - CreateProposalEvent { - proposal_id, - proposer: proposer_address, - stake_pool, - execution_hash, - proposal_metadata, - }, - ); - proposal_id + public fun get_voters_list(): vector
acquires SupraGovernanceConfig { + borrow_global(@supra_framework).voters } - /// Create a single-step proposal with the backing `stake_pool`. /// @param execution_hash Required. This is the hash of the resolution script. When the proposal is resolved, /// only the exact script with matching hash can be successfully executed. @@ -671,138 +318,6 @@ module supra_framework::supra_governance { proposal_id } - /// Vote on proposal with proposal_id and all voting power from multiple stake_pools. - public entry fun batch_vote( - voter: &signer, - stake_pools: vector
, - proposal_id: u64, - should_pass: bool, - ) acquires ApprovedExecutionHashes, VotingRecords, VotingRecordsV2, GovernanceEvents { - vector::for_each(stake_pools, |stake_pool| { - vote_internal(voter, stake_pool, proposal_id, MAX_U64, should_pass); - }); - } - - /// Batch vote on proposal with proposal_id and specified voting power from multiple stake_pools. - public entry fun batch_partial_vote( - voter: &signer, - stake_pools: vector
, - proposal_id: u64, - voting_power: u64, - should_pass: bool, - ) acquires ApprovedExecutionHashes, VotingRecords, VotingRecordsV2, GovernanceEvents { - vector::for_each(stake_pools, |stake_pool| { - vote_internal(voter, stake_pool, proposal_id, voting_power, should_pass); - }); - } - - /// Vote on proposal with `proposal_id` and all voting power from `stake_pool`. - public entry fun vote( - voter: &signer, - stake_pool: address, - proposal_id: u64, - should_pass: bool, - ) acquires ApprovedExecutionHashes, VotingRecords, VotingRecordsV2, GovernanceEvents { - vote_internal(voter, stake_pool, proposal_id, MAX_U64, should_pass); - } - - /// Vote on proposal with `proposal_id` and specified voting power from `stake_pool`. - public entry fun partial_vote( - voter: &signer, - stake_pool: address, - proposal_id: u64, - voting_power: u64, - should_pass: bool, - ) acquires ApprovedExecutionHashes, VotingRecords, VotingRecordsV2, GovernanceEvents { - vote_internal(voter, stake_pool, proposal_id, voting_power, should_pass); - } - - /// Vote on proposal with `proposal_id` and specified voting_power from `stake_pool`. - /// If voting_power is more than all the left voting power of `stake_pool`, use all the left voting power. - /// If a stake pool has already voted on a proposal before partial governance voting is enabled, the stake pool - /// cannot vote on the proposal even after partial governance voting is enabled. - fun vote_internal( - voter: &signer, - stake_pool: address, - proposal_id: u64, - voting_power: u64, - should_pass: bool, - ) acquires ApprovedExecutionHashes, VotingRecords, VotingRecordsV2, GovernanceEvents { - let voter_address = signer::address_of(voter); - assert!(stake::get_delegated_voter(stake_pool) == voter_address, error::invalid_argument(ENOT_DELEGATED_VOTER)); - - // The voter's stake needs to be locked up at least as long as the proposal's expiration. - let proposal_expiration = voting::get_proposal_expiration_secs( - @supra_framework, - proposal_id - ); - assert!( - stake::get_lockup_secs(stake_pool) >= proposal_expiration, - error::invalid_argument(EINSUFFICIENT_STAKE_LOCKUP), - ); - - // If a stake pool has already voted on a proposal before partial governance voting is enabled, - // `get_remaining_voting_power` returns 0. - let staking_pool_voting_power = get_remaining_voting_power(stake_pool, proposal_id); - voting_power = min(voting_power, staking_pool_voting_power); - - // Short-circuit if the voter has no voting power. - assert!(voting_power > 0, error::invalid_argument(ENO_VOTING_POWER)); - - voting::vote( - &governance_proposal::create_empty_proposal(), - @supra_framework, - proposal_id, - voting_power, - should_pass, - ); - - let record_key = RecordKey { - stake_pool, - proposal_id, - }; - if (features::partial_governance_voting_enabled()) { - let voting_records_v2 = borrow_global_mut(@supra_framework); - let used_voting_power = smart_table::borrow_mut_with_default(&mut voting_records_v2.votes, record_key, 0); - // This calculation should never overflow because the used voting cannot exceed the total voting power of this stake pool. - *used_voting_power = *used_voting_power + voting_power; - } else { - let voting_records = borrow_global_mut(@supra_framework); - assert!( - !table::contains(&voting_records.votes, record_key), - error::invalid_argument(EALREADY_VOTED)); - table::add(&mut voting_records.votes, record_key, true); - }; - - if (std::features::module_event_migration_enabled()) { - event::emit( - Vote { - proposal_id, - voter: voter_address, - stake_pool, - num_votes: voting_power, - should_pass, - }, - ); - }; - let events = borrow_global_mut(@supra_framework); - event::emit_event( - &mut events.vote_events, - VoteEvent { - proposal_id, - voter: voter_address, - stake_pool, - num_votes: voting_power, - should_pass, - }, - ); - - let proposal_state = voting::get_proposal_state(@supra_framework, proposal_id); - if (proposal_state == PROPOSAL_STATE_SUCCEEDED) { - add_approved_script_hash(proposal_id); - } - } - /// Vote on proposal with `proposal_id` and all voting power from `stake_pool`. public entry fun supra_vote( voter: &signer, @@ -866,36 +381,10 @@ module supra_framework::supra_governance { } } - public entry fun add_approved_script_hash_script(proposal_id: u64) acquires ApprovedExecutionHashes { - add_approved_script_hash(proposal_id) - } - public entry fun add_supra_approved_script_hash_script(proposal_id: u64) acquires ApprovedExecutionHashes { add_supra_approved_script_hash(proposal_id) } - /// Add the execution script hash of a successful governance proposal to the approved list. - /// This is needed to bypass the mempool transaction size limit for approved governance proposal transactions that - /// are too large (e.g. module upgrades). - public fun add_approved_script_hash(proposal_id: u64) acquires ApprovedExecutionHashes { - let approved_hashes = borrow_global_mut(@supra_framework); - - // Ensure the proposal can be resolved. - let proposal_state = voting::get_proposal_state(@supra_framework, proposal_id); - assert!(proposal_state == PROPOSAL_STATE_SUCCEEDED, error::invalid_argument(EPROPOSAL_NOT_RESOLVABLE_YET)); - - let execution_hash = voting::get_execution_hash(@supra_framework, proposal_id); - - // If this is a multi-step proposal, the proposal id will already exist in the ApprovedExecutionHashes map. - // We will update execution hash in ApprovedExecutionHashes to be the next_execution_hash. - if (simple_map::contains_key(&approved_hashes.hashes, &proposal_id)) { - let current_execution_hash = simple_map::borrow_mut(&mut approved_hashes.hashes, &proposal_id); - *current_execution_hash = execution_hash; - } else { - simple_map::add(&mut approved_hashes.hashes, proposal_id, execution_hash); - } - } - /// Add the execution script hash of a successful governance proposal to the approved list. /// This is needed to bypass the mempool transaction size limit for approved governance proposal transactions that /// are too large (e.g. module upgrades). @@ -918,17 +407,6 @@ module supra_framework::supra_governance { } } - /// Resolve a successful single-step proposal. This would fail if the proposal is not successful (not enough votes or more no - /// than yes). - public fun resolve( - proposal_id: u64, - signer_address: address - ): signer acquires ApprovedExecutionHashes, GovernanceResponsbility { - voting::resolve(@supra_framework, proposal_id); - remove_approved_hash(proposal_id); - get_signer(signer_address) - } - /// Resolve a successful single-step proposal. This would fail if the proposal is not successful (not enough votes or more no /// than yes). public fun supra_resolve( @@ -940,26 +418,6 @@ module supra_framework::supra_governance { get_signer(signer_address) } - /// Resolve a successful multi-step proposal. This would fail if the proposal is not successful. - public fun resolve_multi_step_proposal( - proposal_id: u64, - signer_address: address, - next_execution_hash: vector - ): signer acquires GovernanceResponsbility, ApprovedExecutionHashes { - voting::resolve_proposal_v2(@supra_framework, proposal_id, next_execution_hash); - // If the current step is the last step of this multi-step proposal, - // we will remove the execution hash from the ApprovedExecutionHashes map. - if (vector::length(&next_execution_hash) == 0) { - remove_approved_hash(proposal_id); - } else { - // If the current step is not the last step of this proposal, - // we replace the current execution hash with the next execution hash - // in the ApprovedExecutionHashes map. - add_approved_script_hash(proposal_id) - }; - get_signer(signer_address) - } - /// Resolve a successful multi-step proposal. This would fail if the proposal is not successful. public fun resolve_supra_multi_step_proposal( proposal_id: u64, @@ -980,19 +438,6 @@ module supra_framework::supra_governance { get_signer(signer_address) } - /// Remove an approved proposal's execution script hash. - public fun remove_approved_hash(proposal_id: u64) acquires ApprovedExecutionHashes { - assert!( - voting::is_resolved(@supra_framework, proposal_id), - error::invalid_argument(EPROPOSAL_NOT_RESOLVED_YET), - ); - - let approved_hashes = &mut borrow_global_mut(@supra_framework).hashes; - if (simple_map::contains_key(approved_hashes, &proposal_id)) { - simple_map::remove(approved_hashes, &proposal_id); - }; - } - /// Remove an approved proposal's execution script hash. public fun remove_supra_approved_hash(proposal_id: u64) acquires ApprovedExecutionHashes { assert!( @@ -1059,21 +504,6 @@ module supra_framework::supra_governance { get_signer(signer_address) } - #[view] - /// Return the voting power a stake pool has with respect to governance proposals. - public fun get_voting_power(pool_address: address): u64 { - let allow_validator_set_change = staking_config::get_allow_validator_set_change(&staking_config::get()); - if (allow_validator_set_change) { - let (active, _, pending_active, pending_inactive) = stake::get_stake(pool_address); - // We calculate the voting power as total non-inactive stakes of the pool. Even if the validator is not in the - // active validator set, as long as they have a lockup (separately checked in create_proposal and voting), their - // stake would still count in their voting power for governance proposals. - active + pending_active + pending_inactive - } else { - stake::get_current_epoch_voting_power(pool_address) - } - } - /// Return a signer for making changes to 0x1 as part of on-chain governance proposal process. fun get_signer(signer_address: address): signer acquires GovernanceResponsbility { let governance_responsibility = borrow_global(@supra_framework); @@ -1094,32 +524,24 @@ module supra_framework::supra_governance { metadata } - fun assert_voting_initialization() { - if (features::partial_governance_voting_enabled()) { - assert!(exists(@supra_framework), error::invalid_state(EPARTIAL_VOTING_NOT_INITIALIZED)); - }; - } - #[test_only] - public entry fun create_proposal_for_test( + public entry fun supra_create_proposal_for_test( proposer: &signer, multi_step: bool, - ) acquires GovernanceConfig, GovernanceEvents { + ) acquires SupraGovernanceConfig, SupraGovernanceEvents { let execution_hash = vector::empty(); vector::push_back(&mut execution_hash, 1); if (multi_step) { - create_proposal_v2( + supra_create_proposal_v2( proposer, - signer::address_of(proposer), execution_hash, b"", b"", true, ); } else { - create_proposal( + supra_create_proposal( proposer, - signer::address_of(proposer), execution_hash, b"", b"", @@ -1128,7 +550,7 @@ module supra_framework::supra_governance { } #[test_only] - public fun resolve_proposal_for_test( + public fun supra_resolve_proposal_for_test( proposal_id: u64, signer_address: address, multi_step: bool, @@ -1139,12 +561,12 @@ module supra_framework::supra_governance { vector::push_back(&mut execution_hash, 1); if (finish_multi_step_execution) { - resolve_multi_step_proposal(proposal_id, signer_address, vector::empty()) + resolve_supra_multi_step_proposal(proposal_id, signer_address, vector::empty()) } else { - resolve_multi_step_proposal(proposal_id, signer_address, execution_hash) + resolve_supra_multi_step_proposal(proposal_id, signer_address, execution_hash) } } else { - resolve(proposal_id, signer_address) + supra_resolve(proposal_id, signer_address) } } @@ -1156,126 +578,130 @@ module supra_framework::supra_governance { #[test_only] public entry fun test_voting_generic( - supra_framework: signer, - proposer: signer, - yes_voter: signer, - no_voter: signer, + supra_framework: &signer, + proposer: &signer, + yes_voter: &signer, + no_voter: &signer, multi_step: bool, use_generic_resolve_function: bool, - ) acquires ApprovedExecutionHashes, GovernanceConfig, GovernanceResponsbility, VotingRecords, VotingRecordsV2, GovernanceEvents { - setup_voting(&supra_framework, &proposer, &yes_voter, &no_voter); + ) acquires ApprovedExecutionHashes, SupraGovernanceConfig, GovernanceResponsbility, SupraGovernanceEvents { + let voters = vector[signer::address_of(proposer), signer::address_of(yes_voter), signer::address_of(no_voter)]; + supra_setup_voting(supra_framework, voters); let execution_hash = vector::empty(); vector::push_back(&mut execution_hash, 1); - create_proposal_for_test(&proposer, multi_step); + supra_create_proposal_for_test(proposer, multi_step); - vote(&yes_voter, signer::address_of(&yes_voter), 0, true); - vote(&no_voter, signer::address_of(&no_voter), 0, false); + supra_vote(proposer, 0, true); + supra_vote(yes_voter, 0, true); + supra_vote(no_voter, 0, false); - test_resolving_proposal_generic(supra_framework, use_generic_resolve_function, execution_hash); + supra_test_resolving_proposal_generic(supra_framework, use_generic_resolve_function, execution_hash); } #[test_only] - public entry fun test_resolving_proposal_generic( - supra_framework: signer, + public entry fun supra_test_resolving_proposal_generic( + supra_framework: &signer, use_generic_resolve_function: bool, execution_hash: vector, ) acquires ApprovedExecutionHashes, GovernanceResponsbility { // Once expiration time has passed, the proposal should be considered resolve now as there are more yes votes // than no. timestamp::update_global_time_for_test(100001000000); - let proposal_state = voting::get_proposal_state(signer::address_of(&supra_framework), 0); + let proposal_state = multisig_voting::get_proposal_state(signer::address_of(supra_framework), 0); assert!(proposal_state == PROPOSAL_STATE_SUCCEEDED, proposal_state); // Add approved script hash. - add_approved_script_hash(0); + add_supra_approved_script_hash(0); let approved_hashes = borrow_global(@supra_framework).hashes; assert!(*simple_map::borrow(&approved_hashes, &0) == execution_hash, 0); // Resolve the proposal. - let account = resolve_proposal_for_test(0, @supra_framework, use_generic_resolve_function, true); + let account = supra_resolve_proposal_for_test(0, @supra_framework, use_generic_resolve_function, true); assert!(signer::address_of(&account) == @supra_framework, 1); - assert!(voting::is_resolved(@supra_framework, 0), 2); + assert!(multisig_voting::is_resolved(@supra_framework, 0), 2); let approved_hashes = borrow_global(@supra_framework).hashes; assert!(!simple_map::contains_key(&approved_hashes, &0), 3); } #[test(supra_framework = @supra_framework, proposer = @0x123, yes_voter = @0x234, no_voter = @345)] public entry fun test_voting( - supra_framework: signer, - proposer: signer, - yes_voter: signer, - no_voter: signer, - ) acquires ApprovedExecutionHashes, GovernanceConfig, GovernanceResponsbility, VotingRecords, VotingRecordsV2, GovernanceEvents { + supra_framework: &signer, + proposer: &signer, + yes_voter: &signer, + no_voter: &signer, + ) acquires ApprovedExecutionHashes, SupraGovernanceConfig, GovernanceResponsbility, SupraGovernanceEvents { test_voting_generic(supra_framework, proposer, yes_voter, no_voter, false, false); } #[test(supra_framework = @supra_framework, proposer = @0x123, yes_voter = @0x234, no_voter = @345)] public entry fun test_voting_multi_step( - supra_framework: signer, - proposer: signer, - yes_voter: signer, - no_voter: signer, - ) acquires ApprovedExecutionHashes, GovernanceConfig, GovernanceResponsbility, VotingRecords, VotingRecordsV2, GovernanceEvents { + supra_framework: &signer, + proposer: &signer, + yes_voter: &signer, + no_voter: &signer, + ) acquires ApprovedExecutionHashes, SupraGovernanceConfig, GovernanceResponsbility, SupraGovernanceEvents { test_voting_generic(supra_framework, proposer, yes_voter, no_voter, true, true); } #[test(supra_framework = @supra_framework, proposer = @0x123, yes_voter = @0x234, no_voter = @345)] - #[expected_failure(abort_code = 0x5000a, location = supra_framework::voting)] + #[expected_failure(abort_code = 0x5000a, location = supra_framework::multisig_voting)] public entry fun test_voting_multi_step_cannot_use_single_step_resolve( - supra_framework: signer, - proposer: signer, - yes_voter: signer, - no_voter: signer, - ) acquires ApprovedExecutionHashes, GovernanceConfig, GovernanceResponsbility, VotingRecords, VotingRecordsV2, GovernanceEvents { + supra_framework: &signer, + proposer: &signer, + yes_voter: &signer, + no_voter: &signer, + ) acquires ApprovedExecutionHashes, SupraGovernanceConfig, GovernanceResponsbility, SupraGovernanceEvents { test_voting_generic(supra_framework, proposer, yes_voter, no_voter, true, false); } #[test(supra_framework = @supra_framework, proposer = @0x123, yes_voter = @0x234, no_voter = @345)] public entry fun test_voting_single_step_can_use_generic_resolve_function( - supra_framework: signer, - proposer: signer, - yes_voter: signer, - no_voter: signer, - ) acquires ApprovedExecutionHashes, GovernanceConfig, GovernanceResponsbility, VotingRecords, VotingRecordsV2, GovernanceEvents { + supra_framework: &signer, + proposer: &signer, + yes_voter: &signer, + no_voter: &signer, + ) acquires ApprovedExecutionHashes, SupraGovernanceConfig, GovernanceResponsbility, SupraGovernanceEvents { test_voting_generic(supra_framework, proposer, yes_voter, no_voter, false, true); } #[test_only] public entry fun test_can_remove_approved_hash_if_executed_directly_via_voting_generic( - supra_framework: signer, - proposer: signer, - yes_voter: signer, - no_voter: signer, + supra_framework: &signer, + proposer: &signer, + yes_voter: &signer, + no_voter: &signer, multi_step: bool, - ) acquires ApprovedExecutionHashes, GovernanceConfig, GovernanceResponsbility, VotingRecords, VotingRecordsV2, GovernanceEvents { - setup_voting(&supra_framework, &proposer, &yes_voter, &no_voter); + ) acquires ApprovedExecutionHashes, GovernanceResponsbility, SupraGovernanceEvents, SupraGovernanceConfig { + let voters = vector[signer::address_of(proposer), signer::address_of(yes_voter), signer::address_of(no_voter)]; + supra_setup_voting(supra_framework, voters); - create_proposal_for_test(&proposer, multi_step); - vote(&yes_voter, signer::address_of(&yes_voter), 0, true); - vote(&no_voter, signer::address_of(&no_voter), 0, false); + supra_create_proposal_for_test(proposer, multi_step); + supra_vote(proposer, 0, true); + supra_vote(yes_voter, 0, true); + supra_vote(no_voter, 0, false); // Add approved script hash. timestamp::update_global_time_for_test(100001000000); - add_approved_script_hash(0); + add_supra_approved_script_hash(0); // Resolve the proposal. if (multi_step) { let execution_hash = vector::empty(); let next_execution_hash = vector::empty(); vector::push_back(&mut execution_hash, 1); - voting::resolve_proposal_v2(@supra_framework, 0, next_execution_hash); - assert!(voting::is_resolved(@supra_framework, 0), 0); + multisig_voting::resolve_proposal_v2(@supra_framework, 0, next_execution_hash); + assert!(multisig_voting::is_resolved(@supra_framework, 0), 0); if (vector::length(&next_execution_hash) == 0) { - remove_approved_hash(0); + remove_supra_approved_hash(0); } else { - add_approved_script_hash(0) + add_supra_approved_script_hash(0) }; } else { - voting::resolve(@supra_framework, 0); - assert!(voting::is_resolved(@supra_framework, 0), 0); - remove_approved_hash(0); + multisig_voting::resolve(@supra_framework, 0); + assert!(multisig_voting::is_resolved(@supra_framework, 0), 0); + remove_supra_approved_hash(0); }; let approved_hashes = borrow_global(@supra_framework).hashes; assert!(!simple_map::contains_key(&approved_hashes, &0), 1); @@ -1283,11 +709,11 @@ module supra_framework::supra_governance { #[test(supra_framework = @supra_framework, proposer = @0x123, yes_voter = @0x234, no_voter = @345)] public entry fun test_can_remove_approved_hash_if_executed_directly_via_voting( - supra_framework: signer, - proposer: signer, - yes_voter: signer, - no_voter: signer, - ) acquires ApprovedExecutionHashes, GovernanceConfig, GovernanceResponsbility, VotingRecords, VotingRecordsV2, GovernanceEvents { + supra_framework: &signer, + proposer: &signer, + yes_voter: &signer, + no_voter: &signer, + ) acquires ApprovedExecutionHashes, GovernanceResponsbility, SupraGovernanceEvents, SupraGovernanceConfig { test_can_remove_approved_hash_if_executed_directly_via_voting_generic( supra_framework, proposer, @@ -1299,11 +725,11 @@ module supra_framework::supra_governance { #[test(supra_framework = @supra_framework, proposer = @0x123, yes_voter = @0x234, no_voter = @345)] public entry fun test_can_remove_approved_hash_if_executed_directly_via_voting_multi_step( - supra_framework: signer, - proposer: signer, - yes_voter: signer, - no_voter: signer, - ) acquires ApprovedExecutionHashes, GovernanceConfig, GovernanceResponsbility, VotingRecords, VotingRecordsV2, GovernanceEvents { + supra_framework: &signer, + proposer: &signer, + yes_voter: &signer, + no_voter: &signer, + ) acquires ApprovedExecutionHashes, GovernanceResponsbility, SupraGovernanceEvents, SupraGovernanceConfig { test_can_remove_approved_hash_if_executed_directly_via_voting_generic( supra_framework, proposer, @@ -1314,393 +740,92 @@ module supra_framework::supra_governance { } #[test(supra_framework = @supra_framework, proposer = @0x123, voter_1 = @0x234, voter_2 = @345)] - #[expected_failure(abort_code = 0x10004, location = supra_framework::voting)] + #[expected_failure(abort_code = 0x8000d, location = supra_framework::multisig_voting)] public entry fun test_cannot_double_vote( - supra_framework: signer, - proposer: signer, - voter_1: signer, - voter_2: signer, - ) acquires ApprovedExecutionHashes, GovernanceConfig, GovernanceResponsbility, VotingRecords, VotingRecordsV2, GovernanceEvents { - setup_voting(&supra_framework, &proposer, &voter_1, &voter_2); - - create_proposal( - &proposer, - signer::address_of(&proposer), - b"", - b"", - b"", - ); - - // Double voting should throw an error. - vote(&voter_1, signer::address_of(&voter_1), 0, true); - vote(&voter_1, signer::address_of(&voter_1), 0, true); - } - - #[test(supra_framework = @supra_framework, proposer = @0x123, voter_1 = @0x234, voter_2 = @345)] - #[expected_failure(abort_code = 0x10004, location = supra_framework::voting)] - public entry fun test_cannot_double_vote_with_different_voter_addresses( - supra_framework: signer, - proposer: signer, - voter_1: signer, - voter_2: signer, - ) acquires ApprovedExecutionHashes, GovernanceConfig, GovernanceResponsbility, VotingRecords, VotingRecordsV2, GovernanceEvents { - setup_voting(&supra_framework, &proposer, &voter_1, &voter_2); - - create_proposal( - &proposer, - signer::address_of(&proposer), - b"", - b"", - b"", - ); - - // Double voting should throw an error for 2 different voters if they still use the same stake pool. - vote(&voter_1, signer::address_of(&voter_1), 0, true); - stake::set_delegated_voter(&voter_1, signer::address_of(&voter_2)); - vote(&voter_2, signer::address_of(&voter_1), 0, true); - } - - #[test(supra_framework = @supra_framework, proposer = @0x123, voter_1 = @0x234, voter_2 = @345)] - public entry fun test_stake_pool_can_vote_on_partial_voting_proposal_many_times( - supra_framework: signer, - proposer: signer, - voter_1: signer, - voter_2: signer, - ) acquires ApprovedExecutionHashes, GovernanceConfig, GovernanceResponsbility, VotingRecords, VotingRecordsV2, GovernanceEvents { - setup_partial_voting(&supra_framework, &proposer, &voter_1, &voter_2); - let execution_hash = vector::empty(); - vector::push_back(&mut execution_hash, 1); - let proposer_addr = signer::address_of(&proposer); - let voter_1_addr = signer::address_of(&voter_1); - let voter_2_addr = signer::address_of(&voter_2); - - create_proposal_for_test(&proposer, true); - - partial_vote(&voter_1, voter_1_addr, 0, 5, true); - partial_vote(&voter_1, voter_1_addr, 0, 3, true); - partial_vote(&voter_1, voter_1_addr, 0, 2, true); - - assert!(get_remaining_voting_power(proposer_addr, 0) == 100, 0); - assert!(get_remaining_voting_power(voter_1_addr, 0) == 10, 1); - assert!(get_remaining_voting_power(voter_2_addr, 0) == 10, 2); - - test_resolving_proposal_generic(supra_framework, true, execution_hash); - } - - #[test(supra_framework = @supra_framework, proposer = @0x123, voter_1 = @0x234, voter_2 = @345)] - #[expected_failure(abort_code = 0x3, location = Self)] - public entry fun test_stake_pool_can_vote_with_partial_voting_power( - supra_framework: signer, - proposer: signer, - voter_1: signer, - voter_2: signer, - ) acquires ApprovedExecutionHashes, GovernanceConfig, GovernanceResponsbility, VotingRecords, VotingRecordsV2, GovernanceEvents { - setup_partial_voting(&supra_framework, &proposer, &voter_1, &voter_2); - let execution_hash = vector::empty(); - vector::push_back(&mut execution_hash, 1); - let proposer_addr = signer::address_of(&proposer); - let voter_1_addr = signer::address_of(&voter_1); - let voter_2_addr = signer::address_of(&voter_2); - - create_proposal_for_test(&proposer, true); - - partial_vote(&voter_1, voter_1_addr, 0, 9, true); - - assert!(get_remaining_voting_power(proposer_addr, 0) == 100, 0); - assert!(get_remaining_voting_power(voter_1_addr, 0) == 11, 1); - assert!(get_remaining_voting_power(voter_2_addr, 0) == 10, 2); - - // No enough Yes. The proposal cannot be resolved. - test_resolving_proposal_generic(supra_framework, true, execution_hash); - } - - #[test(supra_framework = @supra_framework, proposer = @0x123, voter_1 = @0x234, voter_2 = @345)] - public entry fun test_batch_vote( - supra_framework: signer, - proposer: signer, - voter_1: signer, - voter_2: signer, - ) acquires ApprovedExecutionHashes, GovernanceConfig, GovernanceResponsbility, VotingRecords, VotingRecordsV2, GovernanceEvents { - features::change_feature_flags_for_testing(&supra_framework, vector[features::get_coin_to_fungible_asset_migration_feature()], vector[]); - setup_partial_voting(&supra_framework, &proposer, &voter_1, &voter_2); - let execution_hash = vector::empty(); - vector::push_back(&mut execution_hash, 1); - let voter_1_addr = signer::address_of(&voter_1); - let voter_2_addr = signer::address_of(&voter_2); - stake::set_delegated_voter(&voter_2, voter_1_addr); - create_proposal_for_test(&proposer, true); - batch_vote(&voter_1, vector[voter_1_addr, voter_2_addr], 0, true); - test_resolving_proposal_generic(supra_framework, true, execution_hash); - } - - #[test(supra_framework = @supra_framework, proposer = @0x123, voter_1 = @0x234, voter_2 = @345)] - public entry fun test_batch_partial_vote( - supra_framework: signer, - proposer: signer, - voter_1: signer, - voter_2: signer, - ) acquires ApprovedExecutionHashes, GovernanceConfig, GovernanceResponsbility, VotingRecords, VotingRecordsV2, GovernanceEvents { - features::change_feature_flags_for_testing(&supra_framework, vector[features::get_coin_to_fungible_asset_migration_feature()], vector[]); - setup_partial_voting(&supra_framework, &proposer, &voter_1, &voter_2); - let execution_hash = vector::empty(); - vector::push_back(&mut execution_hash, 1); - let voter_1_addr = signer::address_of(&voter_1); - let voter_2_addr = signer::address_of(&voter_2); - stake::set_delegated_voter(&voter_2, voter_1_addr); - create_proposal_for_test(&proposer, true); - batch_partial_vote(&voter_1, vector[voter_1_addr, voter_2_addr], 0, 9, true); - test_resolving_proposal_generic(supra_framework, true, execution_hash); - } - - #[test(supra_framework = @supra_framework, proposer = @0x123, voter_1 = @0x234, voter_2 = @345)] - public entry fun test_stake_pool_can_vote_only_with_its_own_voting_power( - supra_framework: signer, - proposer: signer, - voter_1: signer, - voter_2: signer, - ) acquires ApprovedExecutionHashes, GovernanceConfig, GovernanceResponsbility, VotingRecords, VotingRecordsV2, GovernanceEvents { - setup_partial_voting(&supra_framework, &proposer, &voter_1, &voter_2); - let execution_hash = vector::empty(); - vector::push_back(&mut execution_hash, 1); - let proposer_addr = signer::address_of(&proposer); - let voter_1_addr = signer::address_of(&voter_1); - let voter_2_addr = signer::address_of(&voter_2); - - create_proposal_for_test(&proposer, true); - - partial_vote(&voter_1, voter_1_addr, 0, 9, true); - // The total voting power of voter_1 is 20. It can only vote with 20 voting power even we pass 30 as the argument. - partial_vote(&voter_1, voter_1_addr, 0, 30, true); - - assert!(get_remaining_voting_power(proposer_addr, 0) == 100, 0); - assert!(get_remaining_voting_power(voter_1_addr, 0) == 0, 1); - assert!(get_remaining_voting_power(voter_2_addr, 0) == 10, 2); - - test_resolving_proposal_generic(supra_framework, true, execution_hash); - } - - #[test(supra_framework = @supra_framework, proposer = @0x123, voter_1 = @0x234, voter_2 = @345)] - public entry fun test_stake_pool_can_vote_before_and_after_partial_governance_voting_enabled( - supra_framework: signer, - proposer: signer, - voter_1: signer, - voter_2: signer, - ) acquires ApprovedExecutionHashes, GovernanceConfig, GovernanceResponsbility, VotingRecords, VotingRecordsV2, GovernanceEvents { - setup_voting(&supra_framework, &proposer, &voter_1, &voter_2); - let execution_hash = vector::empty(); - vector::push_back(&mut execution_hash, 1); - let proposer_addr = signer::address_of(&proposer); - let voter_1_addr = signer::address_of(&voter_1); - let voter_2_addr = signer::address_of(&voter_2); - - create_proposal_for_test(&proposer, true); - vote(&voter_1, voter_1_addr, 0, true); - assert!(get_remaining_voting_power(proposer_addr, 0) == 100, 0); - assert!(get_remaining_voting_power(voter_1_addr, 0) == 0, 1); - assert!(get_remaining_voting_power(voter_2_addr, 0) == 10, 2); - - initialize_partial_voting(&supra_framework); - features::change_feature_flags_for_testing(&supra_framework, vector[features::get_partial_governance_voting()], vector[]); - - coin::register(&voter_1); - coin::register(&voter_2); - stake::add_stake(&voter_1, 20); - stake::add_stake(&voter_2, 5); - - // voter1 has already voted before partial governance voting is enalbed. So it cannot vote even after adding stake. - // voter2's voting poewr increase after adding stake. - assert!(get_remaining_voting_power(proposer_addr, 0) == 100, 0); - assert!(get_remaining_voting_power(voter_1_addr, 0) == 0, 1); - assert!(get_remaining_voting_power(voter_2_addr, 0) == 15, 2); - - test_resolving_proposal_generic(supra_framework, true, execution_hash); - } - - #[test(supra_framework = @supra_framework, proposer = @0x123, voter_1 = @0x234, voter_2 = @345)] - public entry fun test_no_remaining_voting_power_about_proposal_expiration_time( - supra_framework: signer, - proposer: signer, - voter_1: signer, - voter_2: signer, - ) acquires GovernanceConfig, GovernanceResponsbility, VotingRecords, VotingRecordsV2, GovernanceEvents { - setup_voting_with_initialized_stake(&supra_framework, &proposer, &voter_1, &voter_2); - let execution_hash = vector::empty(); - vector::push_back(&mut execution_hash, 1); - let proposer_addr = signer::address_of(&proposer); - let voter_1_addr = signer::address_of(&voter_1); - let voter_2_addr = signer::address_of(&voter_2); - - create_proposal_for_test(&proposer, true); - assert!(get_remaining_voting_power(proposer_addr, 0) == 100, 0); - assert!(get_remaining_voting_power(voter_1_addr, 0) == 0, 1); - assert!(get_remaining_voting_power(voter_2_addr, 0) == 0, 2); - - // 500 seconds later, lockup period of voter_1 and voter_2 is reset. - timestamp::fast_forward_seconds(440); - stake::end_epoch(); - assert!(get_remaining_voting_power(proposer_addr, 0) == 100, 0); - assert!(get_remaining_voting_power(voter_1_addr, 0) == 20, 1); - assert!(get_remaining_voting_power(voter_2_addr, 0) == 10, 2); - - // 501 seconds later, the proposal expires. - timestamp::fast_forward_seconds(441); - stake::end_epoch(); - assert!(get_remaining_voting_power(proposer_addr, 0) == 0, 0); - assert!(get_remaining_voting_power(voter_1_addr, 0) == 0, 1); - assert!(get_remaining_voting_power(voter_2_addr, 0) == 0, 2); - } - - #[test_only] - public fun setup_voting( supra_framework: &signer, proposer: &signer, - yes_voter: &signer, - no_voter: &signer, - ) acquires GovernanceResponsbility { - use std::vector; - use supra_framework::account; - use supra_framework::coin; - use supra_framework::supra_coin::{Self, SupraCoin}; - - timestamp::set_time_has_started_for_testing(supra_framework); - account::create_account_for_test(signer::address_of(supra_framework)); - account::create_account_for_test(signer::address_of(proposer)); - account::create_account_for_test(signer::address_of(yes_voter)); - account::create_account_for_test(signer::address_of(no_voter)); + voter_1: &signer, + voter_2: &signer, + ) acquires ApprovedExecutionHashes, GovernanceResponsbility, SupraGovernanceConfig, SupraGovernanceEvents { + let voters = vector[signer::address_of(proposer), signer::address_of(voter_1), signer::address_of(voter_2)]; + supra_setup_voting(supra_framework, voters); - // Initialize the governance. - staking_config::initialize_for_test(supra_framework, 0, 1000, 2000, true, 0, 1, 100); - old_initialize(supra_framework, 10, 100, 1000); - store_signer_cap( - supra_framework, - @supra_framework, - account::create_test_signer_cap(@supra_framework), + supra_create_proposal( + proposer, + b"random-test", + b"", + b"", ); - // Initialize the stake pools for proposer and voters. - let active_validators = vector::empty
(); - vector::push_back(&mut active_validators, signer::address_of(proposer)); - vector::push_back(&mut active_validators, signer::address_of(yes_voter)); - vector::push_back(&mut active_validators, signer::address_of(no_voter)); - let (_sk_1, pk_1) = stake::generate_identity(); - let (_sk_2, pk_2) = stake::generate_identity(); - let (_sk_3, pk_3) = stake::generate_identity(); - let pks = vector[pk_1, pk_2, pk_3]; - stake::create_validator_set(supra_framework, active_validators, pks); - - let (burn_cap, mint_cap) = supra_coin::initialize_for_test(supra_framework); - // Spread stake among active and pending_inactive because both need to be accounted for when computing voting - // power. - coin::register(proposer); - coin::deposit(signer::address_of(proposer), coin::mint(100, &mint_cap)); - coin::register(yes_voter); - coin::deposit(signer::address_of(yes_voter), coin::mint(20, &mint_cap)); - coin::register(no_voter); - coin::deposit(signer::address_of(no_voter), coin::mint(10, &mint_cap)); - stake::create_stake_pool(proposer, coin::mint(50, &mint_cap), coin::mint(50, &mint_cap), 10000); - stake::create_stake_pool(yes_voter, coin::mint(10, &mint_cap), coin::mint(10, &mint_cap), 10000); - stake::create_stake_pool(no_voter, coin::mint(5, &mint_cap), coin::mint(5, &mint_cap), 10000); - coin::destroy_mint_cap(mint_cap); - coin::destroy_burn_cap(burn_cap); + // Double voting should throw an error. + supra_vote(voter_1, 0, true); + supra_vote(voter_1, 0, true); } #[test_only] - public fun setup_voting_with_initialized_stake( + public fun supra_setup_voting( supra_framework: &signer, - proposer: &signer, - yes_voter: &signer, - no_voter: &signer, + voters: vector
, ) acquires GovernanceResponsbility { use supra_framework::account; - use supra_framework::coin; - use supra_framework::supra_coin::SupraCoin; timestamp::set_time_has_started_for_testing(supra_framework); account::create_account_for_test(signer::address_of(supra_framework)); - account::create_account_for_test(signer::address_of(proposer)); - account::create_account_for_test(signer::address_of(yes_voter)); - account::create_account_for_test(signer::address_of(no_voter)); // Initialize the governance. - stake::initialize_for_test_custom(supra_framework, 0, 1000, 2000, true, 0, 1, 1000); - old_initialize(supra_framework, 10, 100, 1000); + initialize(supra_framework, 1000, 2, voters); store_signer_cap( supra_framework, @supra_framework, account::create_test_signer_cap(@supra_framework), ); - - // Initialize the stake pools for proposer and voters. - // Spread stake among active and pending_inactive because both need to be accounted for when computing voting - // power. - coin::register(proposer); - coin::deposit(signer::address_of(proposer), stake::mint_coins(100)); - coin::register(yes_voter); - coin::deposit(signer::address_of(yes_voter), stake::mint_coins(20)); - coin::register(no_voter); - coin::deposit(signer::address_of(no_voter), stake::mint_coins(10)); - - let (_sk_1, pk_1) = stake::generate_identity(); - let (_sk_2, pk_2) = stake::generate_identity(); - let (_sk_3, pk_3) = stake::generate_identity(); - stake::initialize_test_validator(&pk_2, yes_voter, 20, true, false); - stake::initialize_test_validator(&pk_3, no_voter, 10, true, false); - stake::end_epoch(); - timestamp::fast_forward_seconds(1440); - stake::initialize_test_validator(&pk_1, proposer, 100, true, false); - stake::end_epoch(); - } - - #[test_only] - public fun setup_partial_voting( - supra_framework: &signer, - proposer: &signer, - voter_1: &signer, - voter_2: &signer, - ) acquires GovernanceResponsbility { - initialize_partial_voting(supra_framework); - features::change_feature_flags_for_testing(supra_framework, vector[features::get_partial_governance_voting()], vector[]); - setup_voting(supra_framework, proposer, voter_1, voter_2); } #[test(supra_framework = @supra_framework)] public entry fun test_update_governance_config( supra_framework: signer, - ) acquires GovernanceConfig, GovernanceEvents { + ) acquires SupraGovernanceEvents, SupraGovernanceConfig { account::create_account_for_test(signer::address_of(&supra_framework)); - old_initialize(&supra_framework, 1, 2, 3); - update_governance_config(&supra_framework, 10, 20, 30); + let voters = vector[@0xa1, @0xa2, @0xa3]; + initialize(&supra_framework, 1000, 2, voters); + let updated_voters = vector[@0xa1, @0xa2, @0xa3, @0xa4, @0xa5]; + update_supra_governance_config(&supra_framework, 1500, 3, updated_voters); - let config = borrow_global(@supra_framework); - assert!(config.min_voting_threshold == 10, 0); - assert!(config.required_proposer_stake == 20, 1); - assert!(config.voting_duration_secs == 30, 3); + let supra_config = borrow_global(@supra_framework); + assert!(supra_config.min_voting_threshold == 3, 0); + assert!(supra_config.voters == updated_voters, 1); + assert!(supra_config.voting_duration_secs == 1500, 3); } #[test(account = @0x123)] #[expected_failure(abort_code = 0x50003, location = supra_framework::system_addresses)] - public entry fun test_update_governance_config_unauthorized_should_fail( - account: signer) acquires GovernanceConfig, GovernanceEvents { - old_initialize(&account, 1, 2, 3); - update_governance_config(&account, 10, 20, 30); + public entry fun test_update_governance_config_unauthorized_should_fail(account: signer) + acquires SupraGovernanceConfig, SupraGovernanceEvents { + account::create_account_for_test(signer::address_of(&account)); + + let voters = vector[@0xa1, @0xa2, @0xa3]; + initialize(&account, 1000, 2, voters); + update_supra_governance_config(&account, 1500, 2, voters); } #[test(supra_framework = @supra_framework, proposer = @0x123, yes_voter = @0x234, no_voter = @345)] public entry fun test_replace_execution_hash( - supra_framework: signer, - proposer: signer, - yes_voter: signer, - no_voter: signer, - ) acquires GovernanceResponsbility, GovernanceConfig, ApprovedExecutionHashes, VotingRecords, VotingRecordsV2, GovernanceEvents { - setup_voting(&supra_framework, &proposer, &yes_voter, &no_voter); + supra_framework: &signer, + proposer: &signer, + yes_voter: &signer, + no_voter: &signer, + ) acquires GovernanceResponsbility, ApprovedExecutionHashes, SupraGovernanceConfig, SupraGovernanceEvents { + let voters = vector[signer::address_of(proposer), signer::address_of(yes_voter), signer::address_of(no_voter)]; + supra_setup_voting(supra_framework, voters); - create_proposal_for_test(&proposer, true); - vote(&yes_voter, signer::address_of(&yes_voter), 0, true); - vote(&no_voter, signer::address_of(&no_voter), 0, false); + supra_create_proposal_for_test(proposer, true); + supra_vote(proposer, 0, true); + supra_vote(yes_voter, 0, true); + supra_vote(no_voter, 0, false); // Add approved script hash. timestamp::update_global_time_for_test(100001000000); - add_approved_script_hash(0); + add_supra_approved_script_hash(0); // Resolve the proposal. let execution_hash = vector::empty(); @@ -1708,28 +833,18 @@ module supra_framework::supra_governance { vector::push_back(&mut execution_hash, 1); vector::push_back(&mut next_execution_hash, 10); - voting::resolve_proposal_v2(@supra_framework, 0, next_execution_hash); + multisig_voting::resolve_proposal_v2(@supra_framework, 0, next_execution_hash); if (vector::length(&next_execution_hash) == 0) { - remove_approved_hash(0); + remove_supra_approved_hash(0); } else { - add_approved_script_hash(0) + add_supra_approved_script_hash(0) }; let approved_hashes = borrow_global(@supra_framework).hashes; assert!(*simple_map::borrow(&approved_hashes, &0) == vector[10u8, ], 1); } - #[test_only] - public fun initialize_for_test( - supra_framework: &signer, - min_voting_threshold: u128, - required_proposer_stake: u64, - voting_duration_secs: u64, - ) { - old_initialize(supra_framework, min_voting_threshold, required_proposer_stake, voting_duration_secs); - } - #[verify_only] public fun initialize_for_verification( supra_framework: &signer, @@ -1737,7 +852,6 @@ module supra_framework::supra_governance { supra_min_voting_threshold: u64, voters: vector
, ) { - // old_initialize(supra_framework, min_voting_threshold, required_proposer_stake, voting_duration_secs); initialize(supra_framework, voting_duration_secs, supra_min_voting_threshold, voters); } } diff --git a/aptos-move/move-examples/governance/sources/block_update_epoch_interval.move b/aptos-move/move-examples/governance/sources/block_update_epoch_interval.move index bb671f733cb0e..bcde5f3431b27 100644 --- a/aptos-move/move-examples/governance/sources/block_update_epoch_interval.move +++ b/aptos-move/move-examples/governance/sources/block_update_epoch_interval.move @@ -3,7 +3,7 @@ script { use supra_framework::block; fun main(proposal_id: u64) { - let framework_signer = supra_governance::resolve(proposal_id, @supra_framework); + let framework_signer = supra_governance::supra_resolve(proposal_id, @supra_framework); // Update epoch interval to 2 hours. let epoch_interval_secs = 2 * 60 * 60; let epoch_interval_microsecs = epoch_interval_secs * 1000000; diff --git a/aptos-move/move-examples/governance/sources/governance_update_voting_duration.move b/aptos-move/move-examples/governance/sources/governance_update_voting_duration.move index 284ef503fbb18..6848afbf09dd6 100644 --- a/aptos-move/move-examples/governance/sources/governance_update_voting_duration.move +++ b/aptos-move/move-examples/governance/sources/governance_update_voting_duration.move @@ -2,16 +2,16 @@ script { use supra_framework::supra_governance; fun main(proposal_id: u64) { - let framework_signer = supra_governance::resolve(proposal_id, @supra_framework); + let framework_signer = supra_governance::supra_resolve(proposal_id, @supra_framework); // Update voting duration of Aptos governance proposals to 1 day. Other params don't change. let updated_voting_duration_secs = 24 * 60 * 60; let unchanged_min_voting_threshold = supra_governance::get_min_voting_threshold(); - let unchanged_required_proposer_stake = supra_governance::get_required_proposer_stake(); - supra_governance::update_governance_config( + let voters = supra_governance::get_voters_list(); + supra_governance::update_supra_governance_config( &framework_signer, unchanged_min_voting_threshold, - unchanged_required_proposer_stake, updated_voting_duration_secs, + voters, ); } } diff --git a/aptos-move/move-examples/governance/sources/stake_update_min_max.move b/aptos-move/move-examples/governance/sources/stake_update_min_max.move index 1b0288d66292d..1f2e418b22e16 100644 --- a/aptos-move/move-examples/governance/sources/stake_update_min_max.move +++ b/aptos-move/move-examples/governance/sources/stake_update_min_max.move @@ -5,7 +5,7 @@ script { use supra_framework::staking_config; fun main(proposal_id: u64) { - let framework_signer = supra_governance::resolve(proposal_id, @supra_framework); + let framework_signer = supra_governance::supra_resolve(proposal_id, @supra_framework); let one_supra_coin_with_decimals = 10 ** (coin::decimals() as u64); // Change min to 1000 and max to 1M Aptos coins. let new_min_stake = 1000 * one_supra_coin_with_decimals; diff --git a/aptos-move/move-examples/governance/sources/stake_update_recurring_lockup_time.move b/aptos-move/move-examples/governance/sources/stake_update_recurring_lockup_time.move index 93500f71af109..85bef41291324 100644 --- a/aptos-move/move-examples/governance/sources/stake_update_recurring_lockup_time.move +++ b/aptos-move/move-examples/governance/sources/stake_update_recurring_lockup_time.move @@ -3,7 +3,7 @@ script { use supra_framework::staking_config; fun main(proposal_id: u64) { - let framework_signer = supra_governance::resolve(proposal_id, @supra_framework); + let framework_signer = supra_governance::supra_resolve(proposal_id, @supra_framework); // Change recurring lockup to 1 day. let one_day_in_secs = 24 * 60 * 60; staking_config::update_recurring_lockup_duration_secs(&framework_signer, one_day_in_secs); diff --git a/aptos-move/move-examples/governance/sources/stake_update_rewards_rate.move b/aptos-move/move-examples/governance/sources/stake_update_rewards_rate.move index d091789e1e815..f491fe9a0f201 100644 --- a/aptos-move/move-examples/governance/sources/stake_update_rewards_rate.move +++ b/aptos-move/move-examples/governance/sources/stake_update_rewards_rate.move @@ -4,7 +4,7 @@ script { use supra_framework::staking_config; fun main(proposal_id: u64) { - let framework_signer = supra_governance::resolve(proposal_id, @supra_framework); + let framework_signer = supra_governance::supra_resolve(proposal_id, @supra_framework); let num_seconds_in_a_year = 365 * 24 * 60 * 60; let epoch_duration_secs = block::get_epoch_interval_secs(); let num_epochs_in_a_year = num_seconds_in_a_year / epoch_duration_secs; diff --git a/aptos-move/move-examples/governance/sources/stake_update_voting_power_increase_limit.move b/aptos-move/move-examples/governance/sources/stake_update_voting_power_increase_limit.move index e263b76bbf74e..e659c72176399 100644 --- a/aptos-move/move-examples/governance/sources/stake_update_voting_power_increase_limit.move +++ b/aptos-move/move-examples/governance/sources/stake_update_voting_power_increase_limit.move @@ -3,7 +3,7 @@ script { use supra_framework::staking_config; fun main(proposal_id: u64) { - let framework_signer = supra_governance::resolve(proposal_id, @supra_framework); + let framework_signer = supra_governance::supra_resolve(proposal_id, @supra_framework); // Update voting power increase limit to 10%. staking_config::update_voting_power_increase_limit(&framework_signer, 10); }