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 1c78207c6e802..a22d2fb159cb0 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 @@ -245,6 +245,86 @@ pub enum EntryFunctionCall { coin_type: TypeTag, }, + /// Remove the committee from the store + CommitteeMapRemoveCommittee { + com_store_addr: AccountAddress, + id: u64, + }, + + /// Remove the committee in bulk + CommitteeMapRemoveCommitteeBulk { + com_store_addr: AccountAddress, + ids: Vec, + }, + + /// Remove the node from the committee + CommitteeMapRemoveCommitteeMember { + com_store_addr: AccountAddress, + id: u64, + node_address: AccountAddress, + }, + + /// Update the dkg flag + CommitteeMapUpdateDkgFlag { + com_store_addr: AccountAddress, + com_id: u64, + flag_value: bool, + }, + + /// This function is used to add a new committee to the store + CommitteeMapUpsertCommittee { + com_store_addr: AccountAddress, + id: u64, + node_addresses: Vec, + ip_public_address: Vec>, + node_public_key: Vec>, + network_public_key: Vec>, + cg_public_key: Vec>, + network_port: Vec, + rpc_port: Vec, + committee_type: u8, + }, + + /// Add the committee in bulk + CommitteeMapUpsertCommitteeBulk { + com_store_addr: AccountAddress, + ids: Vec, + node_addresses_bulk: Vec>, + ip_public_address_bulk: Vec>>, + node_public_key_bulk: Vec>>, + network_public_key_bulk: Vec>>, + cg_public_key_bulk: Vec>>, + network_port_bulk: Vec>, + rpc_por_bulkt: Vec>, + committee_types: Vec, + }, + + /// Upsert the node to the committee + CommitteeMapUpsertCommitteeMember { + com_store_addr: AccountAddress, + id: u64, + node_address: AccountAddress, + ip_public_address: Vec, + node_public_key: Vec, + network_public_key: Vec, + cg_public_key: Vec, + network_port: u16, + rpc_port: u16, + }, + + /// Upsert nodes to the committee + CommitteeMapUpsertCommitteeMemberBulk { + com_store_addr: AccountAddress, + ids: Vec, + node_addresses: Vec, + ip_public_address: Vec>, + node_public_key: Vec>, + network_public_key: Vec>, + cg_public_key: Vec>, + network_port: Vec, + rpc_port: Vec, + }, + /// Add `amount` of coins to the delegation pool `pool_address`. DelegationPoolAddStake { pool_address: AccountAddress, @@ -1176,6 +1256,111 @@ impl EntryFunctionCall { amount, } => coin_transfer(coin_type, to, amount), CoinUpgradeSupply { coin_type } => coin_upgrade_supply(coin_type), + CommitteeMapRemoveCommittee { com_store_addr, id } => { + committee_map_remove_committee(com_store_addr, id) + }, + CommitteeMapRemoveCommitteeBulk { + com_store_addr, + ids, + } => committee_map_remove_committee_bulk(com_store_addr, ids), + CommitteeMapRemoveCommitteeMember { + com_store_addr, + id, + node_address, + } => committee_map_remove_committee_member(com_store_addr, id, node_address), + CommitteeMapUpdateDkgFlag { + com_store_addr, + com_id, + flag_value, + } => committee_map_update_dkg_flag(com_store_addr, com_id, flag_value), + CommitteeMapUpsertCommittee { + com_store_addr, + id, + node_addresses, + ip_public_address, + node_public_key, + network_public_key, + cg_public_key, + network_port, + rpc_port, + committee_type, + } => committee_map_upsert_committee( + com_store_addr, + id, + node_addresses, + ip_public_address, + node_public_key, + network_public_key, + cg_public_key, + network_port, + rpc_port, + committee_type, + ), + CommitteeMapUpsertCommitteeBulk { + com_store_addr, + ids, + node_addresses_bulk, + ip_public_address_bulk, + node_public_key_bulk, + network_public_key_bulk, + cg_public_key_bulk, + network_port_bulk, + rpc_por_bulkt, + committee_types, + } => committee_map_upsert_committee_bulk( + com_store_addr, + ids, + node_addresses_bulk, + ip_public_address_bulk, + node_public_key_bulk, + network_public_key_bulk, + cg_public_key_bulk, + network_port_bulk, + rpc_por_bulkt, + committee_types, + ), + CommitteeMapUpsertCommitteeMember { + com_store_addr, + id, + node_address, + ip_public_address, + node_public_key, + network_public_key, + cg_public_key, + network_port, + rpc_port, + } => committee_map_upsert_committee_member( + com_store_addr, + id, + node_address, + ip_public_address, + node_public_key, + network_public_key, + cg_public_key, + network_port, + rpc_port, + ), + CommitteeMapUpsertCommitteeMemberBulk { + com_store_addr, + ids, + node_addresses, + ip_public_address, + node_public_key, + network_public_key, + cg_public_key, + network_port, + rpc_port, + } => committee_map_upsert_committee_member_bulk( + com_store_addr, + ids, + node_addresses, + ip_public_address, + node_public_key, + network_public_key, + cg_public_key, + network_port, + rpc_port, + ), DelegationPoolAddStake { pool_address, amount, @@ -2232,6 +2417,246 @@ pub fn coin_upgrade_supply(coin_type: TypeTag) -> TransactionPayload { )) } +/// Remove the committee from the store +pub fn committee_map_remove_committee( + com_store_addr: AccountAddress, + 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!("committee_map").to_owned(), + ), + ident_str!("remove_committee").to_owned(), + vec![], + vec![ + bcs::to_bytes(&com_store_addr).unwrap(), + bcs::to_bytes(&id).unwrap(), + ], + )) +} + +/// Remove the committee in bulk +pub fn committee_map_remove_committee_bulk( + com_store_addr: AccountAddress, + ids: 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!("committee_map").to_owned(), + ), + ident_str!("remove_committee_bulk").to_owned(), + vec![], + vec![ + bcs::to_bytes(&com_store_addr).unwrap(), + bcs::to_bytes(&ids).unwrap(), + ], + )) +} + +/// Remove the node from the committee +pub fn committee_map_remove_committee_member( + com_store_addr: AccountAddress, + id: u64, + node_address: AccountAddress, +) -> 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!("committee_map").to_owned(), + ), + ident_str!("remove_committee_member").to_owned(), + vec![], + vec![ + bcs::to_bytes(&com_store_addr).unwrap(), + bcs::to_bytes(&id).unwrap(), + bcs::to_bytes(&node_address).unwrap(), + ], + )) +} + +/// Update the dkg flag +pub fn committee_map_update_dkg_flag( + com_store_addr: AccountAddress, + com_id: u64, + flag_value: 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!("committee_map").to_owned(), + ), + ident_str!("update_dkg_flag").to_owned(), + vec![], + vec![ + bcs::to_bytes(&com_store_addr).unwrap(), + bcs::to_bytes(&com_id).unwrap(), + bcs::to_bytes(&flag_value).unwrap(), + ], + )) +} + +/// This function is used to add a new committee to the store +pub fn committee_map_upsert_committee( + com_store_addr: AccountAddress, + id: u64, + node_addresses: Vec, + ip_public_address: Vec>, + node_public_key: Vec>, + network_public_key: Vec>, + cg_public_key: Vec>, + network_port: Vec, + rpc_port: Vec, + committee_type: u8, +) -> 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!("committee_map").to_owned(), + ), + ident_str!("upsert_committee").to_owned(), + vec![], + vec![ + bcs::to_bytes(&com_store_addr).unwrap(), + bcs::to_bytes(&id).unwrap(), + bcs::to_bytes(&node_addresses).unwrap(), + bcs::to_bytes(&ip_public_address).unwrap(), + bcs::to_bytes(&node_public_key).unwrap(), + bcs::to_bytes(&network_public_key).unwrap(), + bcs::to_bytes(&cg_public_key).unwrap(), + bcs::to_bytes(&network_port).unwrap(), + bcs::to_bytes(&rpc_port).unwrap(), + bcs::to_bytes(&committee_type).unwrap(), + ], + )) +} + +/// Add the committee in bulk +pub fn committee_map_upsert_committee_bulk( + com_store_addr: AccountAddress, + ids: Vec, + node_addresses_bulk: Vec>, + ip_public_address_bulk: Vec>>, + node_public_key_bulk: Vec>>, + network_public_key_bulk: Vec>>, + cg_public_key_bulk: Vec>>, + network_port_bulk: Vec>, + rpc_por_bulkt: Vec>, + committee_types: 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!("committee_map").to_owned(), + ), + ident_str!("upsert_committee_bulk").to_owned(), + vec![], + vec![ + bcs::to_bytes(&com_store_addr).unwrap(), + bcs::to_bytes(&ids).unwrap(), + bcs::to_bytes(&node_addresses_bulk).unwrap(), + bcs::to_bytes(&ip_public_address_bulk).unwrap(), + bcs::to_bytes(&node_public_key_bulk).unwrap(), + bcs::to_bytes(&network_public_key_bulk).unwrap(), + bcs::to_bytes(&cg_public_key_bulk).unwrap(), + bcs::to_bytes(&network_port_bulk).unwrap(), + bcs::to_bytes(&rpc_por_bulkt).unwrap(), + bcs::to_bytes(&committee_types).unwrap(), + ], + )) +} + +/// Upsert the node to the committee +pub fn committee_map_upsert_committee_member( + com_store_addr: AccountAddress, + id: u64, + node_address: AccountAddress, + ip_public_address: Vec, + node_public_key: Vec, + network_public_key: Vec, + cg_public_key: Vec, + network_port: u16, + rpc_port: u16, +) -> 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!("committee_map").to_owned(), + ), + ident_str!("upsert_committee_member").to_owned(), + vec![], + vec![ + bcs::to_bytes(&com_store_addr).unwrap(), + bcs::to_bytes(&id).unwrap(), + bcs::to_bytes(&node_address).unwrap(), + bcs::to_bytes(&ip_public_address).unwrap(), + bcs::to_bytes(&node_public_key).unwrap(), + bcs::to_bytes(&network_public_key).unwrap(), + bcs::to_bytes(&cg_public_key).unwrap(), + bcs::to_bytes(&network_port).unwrap(), + bcs::to_bytes(&rpc_port).unwrap(), + ], + )) +} + +/// Upsert nodes to the committee +pub fn committee_map_upsert_committee_member_bulk( + com_store_addr: AccountAddress, + ids: Vec, + node_addresses: Vec, + ip_public_address: Vec>, + node_public_key: Vec>, + network_public_key: Vec>, + cg_public_key: Vec>, + network_port: Vec, + rpc_port: 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!("committee_map").to_owned(), + ), + ident_str!("upsert_committee_member_bulk").to_owned(), + vec![], + vec![ + bcs::to_bytes(&com_store_addr).unwrap(), + bcs::to_bytes(&ids).unwrap(), + bcs::to_bytes(&node_addresses).unwrap(), + bcs::to_bytes(&ip_public_address).unwrap(), + bcs::to_bytes(&node_public_key).unwrap(), + bcs::to_bytes(&network_public_key).unwrap(), + bcs::to_bytes(&cg_public_key).unwrap(), + bcs::to_bytes(&network_port).unwrap(), + bcs::to_bytes(&rpc_port).unwrap(), + ], + )) +} + /// Add `amount` of coins to the delegation pool `pool_address`. pub fn delegation_pool_add_stake(pool_address: AccountAddress, amount: u64) -> TransactionPayload { TransactionPayload::EntryFunction(EntryFunction::new( @@ -5028,6 +5453,142 @@ mod decoder { } } + pub fn committee_map_remove_committee( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::CommitteeMapRemoveCommittee { + com_store_addr: bcs::from_bytes(script.args().get(0)?).ok()?, + id: bcs::from_bytes(script.args().get(1)?).ok()?, + }) + } else { + None + } + } + + pub fn committee_map_remove_committee_bulk( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::CommitteeMapRemoveCommitteeBulk { + com_store_addr: bcs::from_bytes(script.args().get(0)?).ok()?, + ids: bcs::from_bytes(script.args().get(1)?).ok()?, + }) + } else { + None + } + } + + pub fn committee_map_remove_committee_member( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::CommitteeMapRemoveCommitteeMember { + com_store_addr: bcs::from_bytes(script.args().get(0)?).ok()?, + id: bcs::from_bytes(script.args().get(1)?).ok()?, + node_address: bcs::from_bytes(script.args().get(2)?).ok()?, + }) + } else { + None + } + } + + pub fn committee_map_update_dkg_flag( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::CommitteeMapUpdateDkgFlag { + com_store_addr: bcs::from_bytes(script.args().get(0)?).ok()?, + com_id: bcs::from_bytes(script.args().get(1)?).ok()?, + flag_value: bcs::from_bytes(script.args().get(2)?).ok()?, + }) + } else { + None + } + } + + pub fn committee_map_upsert_committee( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::CommitteeMapUpsertCommittee { + com_store_addr: bcs::from_bytes(script.args().get(0)?).ok()?, + id: bcs::from_bytes(script.args().get(1)?).ok()?, + node_addresses: bcs::from_bytes(script.args().get(2)?).ok()?, + ip_public_address: bcs::from_bytes(script.args().get(3)?).ok()?, + node_public_key: bcs::from_bytes(script.args().get(4)?).ok()?, + network_public_key: bcs::from_bytes(script.args().get(5)?).ok()?, + cg_public_key: bcs::from_bytes(script.args().get(6)?).ok()?, + network_port: bcs::from_bytes(script.args().get(7)?).ok()?, + rpc_port: bcs::from_bytes(script.args().get(8)?).ok()?, + committee_type: bcs::from_bytes(script.args().get(9)?).ok()?, + }) + } else { + None + } + } + + pub fn committee_map_upsert_committee_bulk( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::CommitteeMapUpsertCommitteeBulk { + com_store_addr: bcs::from_bytes(script.args().get(0)?).ok()?, + ids: bcs::from_bytes(script.args().get(1)?).ok()?, + node_addresses_bulk: bcs::from_bytes(script.args().get(2)?).ok()?, + ip_public_address_bulk: bcs::from_bytes(script.args().get(3)?).ok()?, + node_public_key_bulk: bcs::from_bytes(script.args().get(4)?).ok()?, + network_public_key_bulk: bcs::from_bytes(script.args().get(5)?).ok()?, + cg_public_key_bulk: bcs::from_bytes(script.args().get(6)?).ok()?, + network_port_bulk: bcs::from_bytes(script.args().get(7)?).ok()?, + rpc_por_bulkt: bcs::from_bytes(script.args().get(8)?).ok()?, + committee_types: bcs::from_bytes(script.args().get(9)?).ok()?, + }) + } else { + None + } + } + + pub fn committee_map_upsert_committee_member( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::CommitteeMapUpsertCommitteeMember { + com_store_addr: bcs::from_bytes(script.args().get(0)?).ok()?, + id: bcs::from_bytes(script.args().get(1)?).ok()?, + node_address: bcs::from_bytes(script.args().get(2)?).ok()?, + ip_public_address: bcs::from_bytes(script.args().get(3)?).ok()?, + node_public_key: bcs::from_bytes(script.args().get(4)?).ok()?, + network_public_key: bcs::from_bytes(script.args().get(5)?).ok()?, + cg_public_key: bcs::from_bytes(script.args().get(6)?).ok()?, + network_port: bcs::from_bytes(script.args().get(7)?).ok()?, + rpc_port: bcs::from_bytes(script.args().get(8)?).ok()?, + }) + } else { + None + } + } + + pub fn committee_map_upsert_committee_member_bulk( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::CommitteeMapUpsertCommitteeMemberBulk { + com_store_addr: bcs::from_bytes(script.args().get(0)?).ok()?, + ids: bcs::from_bytes(script.args().get(1)?).ok()?, + node_addresses: bcs::from_bytes(script.args().get(2)?).ok()?, + ip_public_address: bcs::from_bytes(script.args().get(3)?).ok()?, + node_public_key: bcs::from_bytes(script.args().get(4)?).ok()?, + network_public_key: bcs::from_bytes(script.args().get(5)?).ok()?, + cg_public_key: bcs::from_bytes(script.args().get(6)?).ok()?, + network_port: bcs::from_bytes(script.args().get(7)?).ok()?, + rpc_port: bcs::from_bytes(script.args().get(8)?).ok()?, + }) + } else { + None + } + } + pub fn delegation_pool_add_stake(payload: &TransactionPayload) -> Option { if let TransactionPayload::EntryFunction(script) = payload { Some(EntryFunctionCall::DelegationPoolAddStake { @@ -6614,6 +7175,38 @@ static SCRIPT_FUNCTION_DECODER_MAP: once_cell::sync::Lazyuse 0x1::coin; use 0x1::consensus_config; use 0x1::create_signer; +use 0x1::delegation_pool; use 0x1::error; use 0x1::execution_config; use 0x1::features; use 0x1::fixed_point32; use 0x1::gas_schedule; use 0x1::jwks; +use 0x1::pbo_delegation_pool; use 0x1::reconfiguration; use 0x1::simple_map; use 0x1::stake; @@ -63,6 +74,7 @@ use 0x1::vector; use 0x1::version; use 0x1::vesting; +use 0x1::vesting_without_staking; @@ -98,6 +110,75 @@ + + + + +## Struct `VestingPoolsMap` + + + +
struct VestingPoolsMap has copy, drop
+
+ + + +
+Fields + + +
+
+admin_address: address +
+
+ +
+
+vesting_percentage: u8 +
+
+ +
+
+vesting_numerators: vector<u64> +
+
+ +
+
+vesting_denominator: u64 +
+
+ +
+
+withdrawal_address: address +
+
+ +
+
+shareholders: vector<address> +
+
+ +
+
+cliff_period_in_seconds: u64 +
+
+ +
+
+period_duration_in_seconds: u64 +
+
+ +
+
+ +
@@ -251,6 +332,90 @@ + + + + +## Struct `DelegatorConfiguration` + + + +
struct DelegatorConfiguration has copy, drop
+
+ + + +
+Fields + + +
+
+owner_address: address +
+
+ +
+
+delegation_pool_creation_seed: vector<u8> +
+
+ +
+
+validator: genesis::ValidatorConfigurationWithCommission +
+
+ +
+
+delegator_addresses: vector<address> +
+
+ +
+
+delegator_stakes: vector<u64> +
+
+ +
+
+ + +
+ + + +## Struct `PboDelegatorConfiguration` + + + +
struct PboDelegatorConfiguration has copy, drop
+
+ + + +
+Fields + + +
+
+delegator_config: genesis::DelegatorConfiguration +
+
+ +
+
+principle_lockup_time: u64 +
+
+ +
+
+ +
@@ -267,6 +432,33 @@ + + + + +
const ENO_SHAREHOLDERS: u64 = 5;
+
+ + + + + + + +
const EACCOUNT_NOT_REGISTERED_FOR_COIN: u64 = 9;
+
+ + + + + + + +
const EDENOMINATOR_IS_ZERO: u64 = 8;
+
+ + + @@ -276,6 +468,51 @@ + + + + +
const ENUMERATOR_GREATER_THAN_DENOMINATOR: u64 = 7;
+
+ + + + + + + +
const ENUMERATOR_IS_ZERO: u64 = 4;
+
+ + + + + + + +
const EVESTING_SCHEDULE_IS_ZERO: u64 = 3;
+
+ + + + + + + +
const PERCENTAGE_INVALID: u64 = 6;
+
+ + + + + + + +
const VESTING_CONTRACT_SEED: vector<u8> = [86, 69, 83, 84, 73, 78, 71, 95, 87, 73, 72, 79, 85, 84, 95, 83, 84, 65, 75, 73, 78, 71, 95, 83, 69, 69, 68];
+
+ + + ## Function `initialize` @@ -749,6 +986,318 @@ encoded in a single BCS byte array. + + + + +## Function `create_delegation_pools` + + + +
fun create_delegation_pools(delegator_configs: vector<genesis::DelegatorConfiguration>)
+
+ + + +
+Implementation + + +
fun create_delegation_pools(
+    delegator_configs: vector<DelegatorConfiguration>,
+) {
+		let unique_accounts: vector<address> = vector::empty();
+    vector::for_each_ref(&delegator_configs, |delegator_config| {
+        let delegator_config: &DelegatorConfiguration = delegator_config;
+			//Ensure that there is a unique owner_address for each pool
+			//This is needed otherwise move_to of DelegationPoolOwnership at owner_address would fail
+			assert!(!vector::contains(&unique_accounts,&delegator_config.owner_address),
+				error::already_exists(EDUPLICATE_ACCOUNT));
+				vector::push_back(&mut unique_accounts,delegator_config.owner_address);
+        create_delegation_pool(delegator_config);
+    });
+}
+
+ + + +
+ + + +## Function `create_delegation_pool` + + + +
fun create_delegation_pool(delegator_config: &genesis::DelegatorConfiguration)
+
+ + + +
+Implementation + + +
fun create_delegation_pool(
+    delegator_config: &DelegatorConfiguration,
+) {
+    let unique_accounts:vector<address> = vector::empty();
+    vector::for_each_ref(&delegator_config.delegator_addresses, |delegator_address| {
+        let delegator_address: &address = delegator_address;
+        assert!(
+            !vector::contains(&unique_accounts, delegator_address),
+            error::already_exists(EDUPLICATE_ACCOUNT),
+        );
+        vector::push_back(&mut unique_accounts, *delegator_address);
+    });
+    let owner_signer = create_signer(delegator_config.owner_address);
+    delegation_pool::initialize_delegation_pool(
+        &owner_signer,
+        delegator_config.validator.commission_percentage,
+        delegator_config.delegation_pool_creation_seed,
+    );
+    let pool_address = delegation_pool::get_owned_pool_address(delegator_config.owner_address);
+
+    let i = 0;
+    while (i < vector::length(&delegator_config.delegator_addresses)) {
+        let delegator_address = *vector::borrow(&delegator_config.delegator_addresses, i);
+        let delegator = &create_signer(delegator_address);
+        let delegator_stake = *vector::borrow(&delegator_config.delegator_stakes, i);
+        delegation_pool::add_stake(delegator, pool_address, delegator_stake);
+        i = i + 1;
+    };
+		
+		let validator = delegator_config.validator.validator_config;
+		assert_validator_addresses_check(&validator);
+
+    if (delegator_config.validator.join_during_genesis) {
+            initialize_validator(pool_address,&validator);
+        };
+
+}
+
+ + + +
+ + + +## Function `create_pbo_delegation_pools` + + + +
fun create_pbo_delegation_pools(pbo_delegator_configs: vector<genesis::PboDelegatorConfiguration>, delegation_percentage: u64)
+
+ + + +
+Implementation + + +
fun create_pbo_delegation_pools(
+    pbo_delegator_configs: vector<PboDelegatorConfiguration>,
+    delegation_percentage: u64,
+) {
+		let unique_accounts: vector<address> = vector::empty();
+    assert!(delegation_percentage > 0 && delegation_percentage <= 100, error::invalid_argument(PERCENTAGE_INVALID));
+    vector::for_each_ref(&pbo_delegator_configs, |pbo_delegator_config| {
+        let pbo_delegator_config: &PboDelegatorConfiguration = pbo_delegator_config;
+			assert!(!vector::contains(&unique_accounts,&pbo_delegator_config.delegator_config.owner_address),
+				error::invalid_argument(EDUPLICATE_ACCOUNT));
+				vector::push_back(&mut unique_accounts,pbo_delegator_config.delegator_config.owner_address);
+        create_pbo_delegation_pool(pbo_delegator_config, delegation_percentage);
+    });
+}
+
+ + + +
+ + + +## Function `create_pbo_delegation_pool` + + + +
fun create_pbo_delegation_pool(pbo_delegator_config: &genesis::PboDelegatorConfiguration, delegation_percentage: u64)
+
+ + + +
+Implementation + + +
fun create_pbo_delegation_pool(
+    pbo_delegator_config: &PboDelegatorConfiguration,
+    delegation_percentage: u64,
+) {
+    let unique_accounts:vector<address> = vector::empty();
+    vector::for_each_ref(&pbo_delegator_config.delegator_config.delegator_addresses, |delegator_address| {
+        let delegator_address: &address = delegator_address;
+        assert!(
+            !vector::contains(&unique_accounts, delegator_address),
+            error::already_exists(EDUPLICATE_ACCOUNT),
+        );
+        vector::push_back(&mut unique_accounts, *delegator_address);
+    });
+    let owner_signer = create_signer(pbo_delegator_config.delegator_config.owner_address);
+    // get a list of delegator addresses, withdraw the coin from them and merge them into a single account
+    let delegator_addresses = pbo_delegator_config.delegator_config.delegator_addresses;
+    let coinInitialization = coin::zero<SupraCoin>();
+    vector::for_each(delegator_addresses, |delegator_address| {
+        let delegator = &create_signer(delegator_address);
+        let total = coin::balance<SupraCoin>(delegator_address);
+        let withdraw_amount = total * delegation_percentage / 100;
+        let coins = coin::withdraw<SupraCoin>(delegator, withdraw_amount);
+        coin::merge(&mut coinInitialization, coins);
+    });
+    pbo_delegation_pool::initialize_delegation_pool(
+        &owner_signer,
+        pbo_delegator_config.delegator_config.validator.commission_percentage,
+        pbo_delegator_config.delegator_config.delegation_pool_creation_seed,
+        pbo_delegator_config.delegator_config.delegator_addresses,
+        pbo_delegator_config.delegator_config.delegator_stakes,
+        coinInitialization,
+        pbo_delegator_config.principle_lockup_time,
+    );
+
+    let pool_address = delegation_pool::get_owned_pool_address(pbo_delegator_config.delegator_config.owner_address);
+		let validator = pbo_delegator_config.delegator_config.validator.validator_config;
+		assert_validator_addresses_check(&validator);
+
+		if (pbo_delegator_config.delegator_config.validator.join_during_genesis) {
+            initialize_validator(pool_address,&validator);
+        };
+
+}
+
+ + + +
+ + + +## Function `assert_validator_addresses_check` + + + +
fun assert_validator_addresses_check(validator: &genesis::ValidatorConfiguration)
+
+ + + +
+Implementation + + +
fun assert_validator_addresses_check(validator: &ValidatorConfiguration)
+	{
+		 assert!(
+               account::exists_at(validator.owner_address),
+               error::not_found(EACCOUNT_DOES_NOT_EXIST),
+           );
+           assert!(
+               account::exists_at(validator.operator_address),
+               error::not_found(EACCOUNT_DOES_NOT_EXIST),
+           );
+           assert!(
+               account::exists_at(validator.voter_address),
+               error::not_found(EACCOUNT_DOES_NOT_EXIST),
+           );
+
+	}
+
+ + + +
+ + + +## Function `create_vesting_without_staking_pools` + + + +
fun create_vesting_without_staking_pools(vesting_pool_map: vector<genesis::VestingPoolsMap>)
+
+ + + +
+Implementation + + +
fun create_vesting_without_staking_pools(
+    vesting_pool_map : vector<VestingPoolsMap>
+) {
+    let unique_accounts: vector<address> = vector::empty();
+    vector::for_each_ref(&vesting_pool_map, |pool_config|{
+        let pool_config: &VestingPoolsMap = pool_config;
+        let schedule  = vector::empty();
+        let schedule_length = vector::length(&pool_config.vesting_numerators);
+        assert!(schedule_length > 0, error::invalid_argument(EVESTING_SCHEDULE_IS_ZERO));
+        assert!(pool_config.vesting_denominator > 0, error::invalid_argument(EDENOMINATOR_IS_ZERO));
+        assert!(pool_config.vesting_percentage > 0 && pool_config.vesting_percentage <=100 ,
+            error::invalid_argument(PERCENTAGE_INVALID));
+        //check the sum of numerator are <= denominator.
+        let sum = vector::fold(pool_config.vesting_numerators,0,|acc, x| acc + x);
+        // Check that total of all fraction in `vesting_schedule` is not greater than 1
+        assert!(sum <= pool_config.vesting_denominator,
+            error::invalid_argument(ENUMERATOR_GREATER_THAN_DENOMINATOR));
+        //assert that withdrawal_address is registered to receive SupraCoin
+        assert!(coin::is_account_registered<SupraCoin>(pool_config.withdrawal_address), error::invalid_argument(EACCOUNT_NOT_REGISTERED_FOR_COIN));
+        //assertion on admin_address?
+        let admin = create_signer(pool_config.admin_address);
+
+        //Create the vesting schedule
+        let j=0;
+        while (j < schedule_length) {
+            let numerator = *vector::borrow(&pool_config.vesting_numerators,j);
+            assert!(numerator > 0, error::invalid_argument(ENUMERATOR_IS_ZERO));
+            let event = fixed_point32::create_from_rational(numerator,pool_config.vesting_denominator);
+            vector::push_back(&mut schedule,event);
+            j = j + 1;
+        };
+
+        let vesting_schedule = vesting_without_staking::create_vesting_schedule(
+            schedule,
+            timestamp::now_seconds() + pool_config.cliff_period_in_seconds,
+            pool_config.period_duration_in_seconds,
+        );
+
+        let buy_ins  = simple_map::create();
+        let num_shareholders = vector::length(&pool_config.shareholders);
+        assert!(num_shareholders > 0, error::invalid_argument(ENO_SHAREHOLDERS));
+        let j = 0;
+        while (j < num_shareholders) {
+            let shareholder = *vector::borrow(&pool_config.shareholders,j);
+            assert!(!vector::contains(&unique_accounts,&shareholder), error::already_exists(EDUPLICATE_ACCOUNT));
+            vector::push_back(&mut unique_accounts,shareholder);
+            let shareholder_signer = create_signer(shareholder);
+            let amount = coin::balance<SupraCoin>(shareholder);
+            let amount_to_extract = (amount * (pool_config.vesting_percentage as u64)) / 100;
+            let coin_share = coin::withdraw<SupraCoin>(&shareholder_signer, amount_to_extract);
+            simple_map::add(&mut buy_ins,shareholder,coin_share);
+            j = j + 1;
+        };
+        vesting_without_staking::create_vesting_contract(
+            &admin,
+            buy_ins,
+            vesting_schedule,
+            pool_config.withdrawal_address,
+            VESTING_CONTRACT_SEED
+        );
+    });
+}
+
+ + +
diff --git a/aptos-move/framework/supra-framework/doc/overview.md b/aptos-move/framework/supra-framework/doc/overview.md index 0c928186d09e4..fba052882a1f2 100644 --- a/aptos-move/framework/supra-framework/doc/overview.md +++ b/aptos-move/framework/supra-framework/doc/overview.md @@ -23,10 +23,10 @@ This is the reference documentation of the Aptos framework. - [`0x1::chain_status`](chain_status.md#0x1_chain_status) - [`0x1::code`](code.md#0x1_code) - [`0x1::coin`](coin.md#0x1_coin) +- [`0x1::committee_map`](committee_map.md#0x1_committee_map) - [`0x1::consensus_config`](consensus_config.md#0x1_consensus_config) - [`0x1::create_signer`](create_signer.md#0x1_create_signer) - [`0x1::delegation_pool`](delegation_pool.md#0x1_delegation_pool) -- [`0x1::dora_committee`](dora_committee.md#0x1_dora_committee) - [`0x1::event`](event.md#0x1_event) - [`0x1::execution_config`](execution_config.md#0x1_execution_config) - [`0x1::fungible_asset`](fungible_asset.md#0x1_fungible_asset) 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 dd880a3dc8db6..0dcbe59aa2d59 100644 --- a/aptos-move/framework/supra-framework/doc/pbo_delegation_pool.md +++ b/aptos-move/framework/supra-framework/doc/pbo_delegation_pool.md @@ -1416,6 +1416,26 @@ Scaling factor of shares pools used within the delegation pool + + +Active share is not the same in stake pool and delegation pool + + +
const ACTIVE_COIN_VALUE_NOT_SAME_STAKE_DELEGATION_POOL: u64 = 26;
+
+ + + + + +Balance below principle stake after unlock + + +
const BALANCE_BELOW_PRINCIPLE_STAKE: u64 = 25;
+
+ + + Coin value is not the same with principle stake. @@ -2168,14 +2188,14 @@ Ownership over setting the operator/voter is granted to owner who h move_to(owner, DelegationPoolOwnership { pool_address }); // Add stake to each delegator - while (vector::length(&delegator_address) > 0) { + while (vector::length(&delegator_address_copy) > 0) { let delegator = vector::pop_back(&mut delegator_address_copy); let stake = vector::pop_back(&mut principle_stake_copy); add_stake_initialization(delegator, pool_address, stake); }; let (active_stake, _, _, _)= stake::get_stake(pool_address); // fail if coin in StakePool.active does not match with the balance in active_shares pool. - assert!( active_stake == pool_u64::total_coins(&borrow_global<DelegationPool>(pool_address).active_shares), error::invalid_state(0)); + assert!( active_stake == pool_u64::total_coins(&borrow_global<DelegationPool>(pool_address).active_shares), error::invalid_state(ACTIVE_COIN_VALUE_NOT_SAME_STAKE_DELEGATION_POOL)); // All delegation pool enable partial governace voting by default once the feature flag is enabled. if (features::partial_governance_voting_enabled() && features::delegation_pool_partial_governance_voting_enabled()) { enable_partial_governance_voting(pool_address); @@ -3366,8 +3386,8 @@ at most how much active stake there is on the stake pool. let pool = borrow_global_mut<DelegationPool>(pool_address); let delegator_address = signer::address_of(delegator); // fail if the amount after withdraw is less than the principle stake and the lockup time is not expired - if (pool.principle_lockup_time > timestamp::now_seconds()) { - assert!(pool_u64::balance(&pool.active_shares,delegator_address) - amount >= *table::borrow(&pool.principle_stake, delegator_address), error::invalid_argument(0)); + if (table::contains(&pool.principle_stake, delegator_address) && pool.principle_lockup_time > timestamp::now_seconds()) { + assert!(pool_u64::balance(&pool.active_shares,delegator_address) - amount >= *table::borrow(&pool.principle_stake, delegator_address), error::invalid_argument(BALANCE_BELOW_PRINCIPLE_STAKE)); }; amount = coins_to_transfer_to_ensure_min_stake( &pool.active_shares, @@ -3389,6 +3409,8 @@ at most how much active stake there is on the stake pool. amount_unlocked: amount, }, ); + let (active_stake, _, pending_active, _)= stake::get_stake(pool_address); + assert!( active_stake + pending_active == pool_u64::total_coins(&pool.active_shares), error::invalid_state(ACTIVE_COIN_VALUE_NOT_SAME_STAKE_DELEGATION_POOL)); } diff --git a/aptos-move/framework/supra-framework/doc/stake.md b/aptos-move/framework/supra-framework/doc/stake.md index 67a1129572e6d..a0266ae21ef04 100644 --- a/aptos-move/framework/supra-framework/doc/stake.md +++ b/aptos-move/framework/supra-framework/doc/stake.md @@ -126,6 +126,7 @@ or if their stake drops below the min required, they would get removed at the en - [Function `add_stake`](#@Specification_1_add_stake) - [Function `add_stake_with_cap`](#@Specification_1_add_stake_with_cap) - [Function `reactivate_stake_with_cap`](#@Specification_1_reactivate_stake_with_cap) + - [Function `rotate_consensus_key_internal`](#@Specification_1_rotate_consensus_key_internal) - [Function `rotate_consensus_key`](#@Specification_1_rotate_consensus_key) - [Function `update_network_and_fullnode_addresses`](#@Specification_1_update_network_and_fullnode_addresses) - [Function `increase_lockup_with_cap`](#@Specification_1_increase_lockup_with_cap) @@ -3722,174 +3723,6 @@ Returns validator's next epoch voting power, including pending_active, active, a - - - - -
fun spec_validators_are_initialized(validators: vector<ValidatorInfo>): bool {
-   forall i in 0..len(validators):
-       spec_has_stake_pool(validators[i].addr) &&
-           spec_has_validator_config(validators[i].addr)
-}
-
- - - - - - - -
fun spec_validator_indices_are_valid(validators: vector<ValidatorInfo>): bool {
-   forall i in 0..len(validators):
-       global<ValidatorConfig>(validators[i].addr).validator_index < spec_validator_index_upper_bound()
-}
-
- - - - - - - -
fun spec_validator_index_upper_bound(): u64 {
-   len(global<ValidatorPerformance>(@supra_framework).validators)
-}
-
- - - - - - - -
fun spec_has_stake_pool(a: address): bool {
-   exists<StakePool>(a)
-}
-
- - - - - - - -
fun spec_has_validator_config(a: address): bool {
-   exists<ValidatorConfig>(a)
-}
-
- - - - - - - -
fun spec_rewards_amount(
-   stake_amount: u64,
-   num_successful_proposals: u64,
-   num_total_proposals: u64,
-   rewards_rate: u64,
-   rewards_rate_denominator: u64,
-): u64;
-
- - - - - - - -
fun spec_contains(validators: vector<ValidatorInfo>, addr: address): bool {
-   exists i in 0..len(validators): validators[i].addr == addr
-}
-
- - - - - - - -
fun spec_is_current_epoch_validator(pool_address: address): bool {
-   let validator_set = global<ValidatorSet>(@supra_framework);
-   !spec_contains(validator_set.pending_active, pool_address)
-       && (spec_contains(validator_set.active_validators, pool_address)
-       || spec_contains(validator_set.pending_inactive, pool_address))
-}
-
- - - - - - - -
schema ResourceRequirement {
-    requires exists<SupraCoinCapabilities>(@supra_framework);
-    requires exists<ValidatorPerformance>(@supra_framework);
-    requires exists<ValidatorSet>(@supra_framework);
-    requires exists<StakingConfig>(@supra_framework);
-    requires exists<StakingRewardsConfig>(@supra_framework) || !features::spec_periodical_reward_rate_decrease_enabled();
-    requires exists<timestamp::CurrentTimeMicroseconds>(@supra_framework);
-    requires exists<ValidatorFees>(@supra_framework);
-}
-
- - - - - - - -
fun spec_get_reward_rate_1(config: StakingConfig): num {
-   if (features::spec_periodical_reward_rate_decrease_enabled()) {
-       let epoch_rewards_rate = global<staking_config::StakingRewardsConfig>(@supra_framework).rewards_rate;
-       if (epoch_rewards_rate.value == 0) {
-           0
-       } else {
-           let denominator_0 = aptos_std::fixed_point64::spec_divide_u128(staking_config::MAX_REWARDS_RATE, epoch_rewards_rate);
-           let denominator = if (denominator_0 > MAX_U64) {
-               MAX_U64
-           } else {
-               denominator_0
-           };
-           let nominator = aptos_std::fixed_point64::spec_multiply_u128(denominator, epoch_rewards_rate);
-           nominator
-       }
-   } else {
-           config.rewards_rate
-   }
-}
-
- - - - - - - -
fun spec_get_reward_rate_2(config: StakingConfig): num {
-   if (features::spec_periodical_reward_rate_decrease_enabled()) {
-       let epoch_rewards_rate = global<staking_config::StakingRewardsConfig>(@supra_framework).rewards_rate;
-       if (epoch_rewards_rate.value == 0) {
-           1
-       } else {
-           let denominator_0 = aptos_std::fixed_point64::spec_divide_u128(staking_config::MAX_REWARDS_RATE, epoch_rewards_rate);
-           let denominator = if (denominator_0 > MAX_U64) {
-               MAX_U64
-           } else {
-               denominator_0
-           };
-           denominator
-       }
-   } else {
-           config.rewards_rate_denominator
-   }
-}
-
- - - ### Resource `ValidatorSet` @@ -4309,6 +4142,22 @@ Returns validator's next epoch voting power, including pending_active, active, a + + +### Function `rotate_consensus_key_internal` + + +
fun rotate_consensus_key_internal(operator: &signer, pool_address: address, new_consensus_pubkey: vector<u8>, genesis: bool)
+
+ + + + +
modifies global<ValidatorConfig>(pool_address);
+
+ + + ### Function `rotate_consensus_key` @@ -4980,4 +4829,102 @@ Returns validator's next epoch voting power, including pending_active, active, a + + + + + +
fun spec_validators_are_initialized(validators: vector<ValidatorInfo>): bool {
+   forall i in 0..len(validators):
+       spec_has_stake_pool(validators[i].addr) &&
+           spec_has_validator_config(validators[i].addr)
+}
+
+ + + + + + + +
fun spec_validator_indices_are_valid(validators: vector<ValidatorInfo>): bool {
+   forall i in 0..len(validators):
+       global<ValidatorConfig>(validators[i].addr).validator_index < spec_validator_index_upper_bound()
+}
+
+ + + + + + + +
fun spec_validator_index_upper_bound(): u64 {
+   len(global<ValidatorPerformance>(@supra_framework).validators)
+}
+
+ + + + + + + +
fun spec_has_stake_pool(a: address): bool {
+   exists<StakePool>(a)
+}
+
+ + + + + + + +
fun spec_has_validator_config(a: address): bool {
+   exists<ValidatorConfig>(a)
+}
+
+ + + + + + + +
fun spec_rewards_amount(
+   stake_amount: u64,
+   num_successful_proposals: u64,
+   num_total_proposals: u64,
+   rewards_rate: u64,
+   rewards_rate_denominator: u64,
+): u64;
+
+ + + + + + + +
fun spec_contains(validators: vector<ValidatorInfo>, addr: address): bool {
+   exists i in 0..len(validators): validators[i].addr == addr
+}
+
+ + + + + + + +
fun spec_is_current_epoch_validator(pool_address: address): bool {
+   let validator_set = global<ValidatorSet>(@supra_framework);
+   !spec_contains(validator_set.pending_active, pool_address)
+       && (spec_contains(validator_set.active_validators, pool_address)
+       || spec_contains(validator_set.pending_inactive, pool_address))
+}
+
+ + [move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/supra-framework/sources/genesis.move b/aptos-move/framework/supra-framework/sources/genesis.move index 0e4b2e3ed87b4..e819490670349 100644 --- a/aptos-move/framework/supra-framework/sources/genesis.move +++ b/aptos-move/framework/supra-framework/sources/genesis.move @@ -4,6 +4,8 @@ module supra_framework::genesis { use std::vector; use aptos_std::simple_map; + use supra_framework::delegation_pool; + use supra_framework::pbo_delegation_pool; use supra_framework::account; use supra_framework::aggregator_factory; @@ -29,15 +31,44 @@ module supra_framework::genesis { use supra_framework::transaction_validation; use supra_framework::version; use supra_framework::vesting; + use supra_framework::vesting_without_staking; - const EDUPLICATE_ACCOUNT: u64 = 1; + + const VESTING_CONTRACT_SEED: vector = b"VESTING_WIHOUT_STAKING_SEED"; + + const EDUPLICATE_ACCOUNT: u64 = 1; const EACCOUNT_DOES_NOT_EXIST: u64 = 2; + const EVESTING_SCHEDULE_IS_ZERO: u64 = 3; + const ENUMERATOR_IS_ZERO: u64 = 4; + const ENO_SHAREHOLDERS: u64 = 5; + const EPERCENTAGE_INVALID: u64 = 6; + const ENUMERATOR_GREATER_THAN_DENOMINATOR: u64 = 7; + const EDENOMINATOR_IS_ZERO: u64 = 8; + const EACCOUNT_NOT_REGISTERED_FOR_COIN: u64 = 9; + struct AccountMap has drop { account_address: address, balance: u64, } + struct VestingPoolsMap has copy, drop { + // Address of the admin of the vesting pool + admin_address: address, + // Percentage of account balance should be put in vesting pool + vpool_locking_percentage : u8, + vesting_numerators : vector, + vesting_denominator : u64, + //Withdrawal address for the pool + withdrawal_address: address, + // Shareholders in the vesting pool + shareholders : vector
, + //Cliff duration in seconds + cliff_period_in_seconds: u64, + // Each vesting period duration in seconds + period_duration_in_seconds: u64, + } + struct EmployeeAccountMap has copy, drop { accounts: vector
, validator: ValidatorConfigurationWithCommission, @@ -62,6 +93,19 @@ module supra_framework::genesis { join_during_genesis: bool, } + struct DelegatorConfiguration has copy, drop { + owner_address: address, + delegation_pool_creation_seed: vector, + validator: ValidatorConfigurationWithCommission, + delegator_addresses: vector
, + delegator_stakes: vector, + } + + struct PboDelegatorConfiguration has copy, drop { + delegator_config: DelegatorConfiguration, + principle_lockup_time: u64, + } + /// Genesis step 1: Initialize aptos framework account and core modules on chain. fun initialize( gas_schedule: vector, @@ -357,6 +401,200 @@ module supra_framework::genesis { }; } + fun create_delegation_pools( + delegator_configs: vector, + ) { + let unique_accounts: vector
= vector::empty(); + vector::for_each_ref(&delegator_configs, |delegator_config| { + let delegator_config: &DelegatorConfiguration = delegator_config; + //Ensure that there is a unique owner_address for each pool + //This is needed otherwise move_to of DelegationPoolOwnership at owner_address would fail + assert!(!vector::contains(&unique_accounts,&delegator_config.owner_address), + error::already_exists(EDUPLICATE_ACCOUNT)); + vector::push_back(&mut unique_accounts,delegator_config.owner_address); + create_delegation_pool(delegator_config); + }); + } + + fun create_delegation_pool( + delegator_config: &DelegatorConfiguration, + ) { + let unique_accounts:vector
= vector::empty(); + vector::for_each_ref(&delegator_config.delegator_addresses, |delegator_address| { + let delegator_address: &address = delegator_address; + assert!( + !vector::contains(&unique_accounts, delegator_address), + error::already_exists(EDUPLICATE_ACCOUNT), + ); + vector::push_back(&mut unique_accounts, *delegator_address); + }); + let owner_signer = create_signer(delegator_config.owner_address); + delegation_pool::initialize_delegation_pool( + &owner_signer, + delegator_config.validator.commission_percentage, + delegator_config.delegation_pool_creation_seed, + ); + let pool_address = delegation_pool::get_owned_pool_address(delegator_config.owner_address); + delegation_pool::set_operator(&owner_signer,delegator_config.validator.validator_config.operator_address); + delegation_pool::set_delegated_voter(&owner_signer,delegator_config.validator.validator_config.voter_address); + + let i = 0; + while (i < vector::length(&delegator_config.delegator_addresses)) { + let delegator_address = *vector::borrow(&delegator_config.delegator_addresses, i); + let delegator = &create_signer(delegator_address); + let delegator_stake = *vector::borrow(&delegator_config.delegator_stakes, i); + delegation_pool::add_stake(delegator, pool_address, delegator_stake); + i = i + 1; + }; + + let validator = delegator_config.validator.validator_config; + assert_validator_addresses_check(&validator); + + if (delegator_config.validator.join_during_genesis) { + initialize_validator(pool_address,&validator); + }; + + } + + fun create_pbo_delegation_pools( + pbo_delegator_configs: vector, + delegation_percentage: u64, + ) { + let unique_accounts: vector
= vector::empty(); + assert!(delegation_percentage > 0 && delegation_percentage <= 100, error::invalid_argument(EPERCENTAGE_INVALID)); + vector::for_each_ref(&pbo_delegator_configs, |pbo_delegator_config| { + let pbo_delegator_config: &PboDelegatorConfiguration = pbo_delegator_config; + assert!(!vector::contains(&unique_accounts,&pbo_delegator_config.delegator_config.owner_address), + error::invalid_argument(EDUPLICATE_ACCOUNT)); + vector::push_back(&mut unique_accounts,pbo_delegator_config.delegator_config.owner_address); + create_pbo_delegation_pool(pbo_delegator_config, delegation_percentage); + }); + } + + fun create_pbo_delegation_pool( + pbo_delegator_config: &PboDelegatorConfiguration, + delegation_percentage: u64, + ) { + assert!(delegation_percentage>0 && delegation_percentage<=100,error::invalid_argument(EPERCENTAGE_INVALID)); + let unique_accounts:vector
= vector::empty(); + vector::for_each_ref(&pbo_delegator_config.delegator_config.delegator_addresses, |delegator_address| { + let delegator_address: &address = delegator_address; + assert!( + !vector::contains(&unique_accounts, delegator_address), + error::already_exists(EDUPLICATE_ACCOUNT), + ); + vector::push_back(&mut unique_accounts, *delegator_address); + }); + let owner_signer = create_signer(pbo_delegator_config.delegator_config.owner_address); + // get a list of delegator addresses, withdraw the coin from them and merge them into a single account + let delegator_addresses = pbo_delegator_config.delegator_config.delegator_addresses; + let coinInitialization = coin::zero(); + vector::for_each(delegator_addresses, |delegator_address| { + let delegator = &create_signer(delegator_address); + let total = coin::balance(delegator_address); + let withdraw_amount = total * delegation_percentage / 100; + let coins = coin::withdraw(delegator, withdraw_amount); + coin::merge(&mut coinInitialization, coins); + }); + pbo_delegation_pool::initialize_delegation_pool( + &owner_signer, + pbo_delegator_config.delegator_config.validator.commission_percentage, + pbo_delegator_config.delegator_config.delegation_pool_creation_seed, + pbo_delegator_config.delegator_config.delegator_addresses, + pbo_delegator_config.delegator_config.delegator_stakes, + coinInitialization, + pbo_delegator_config.principle_lockup_time, + ); + + let pool_address = pbo_delegation_pool::get_owned_pool_address(pbo_delegator_config.delegator_config.owner_address); + let validator = pbo_delegator_config.delegator_config.validator.validator_config; + pbo_delegation_pool::set_operator(&owner_signer,validator.operator_address); + pbo_delegation_pool::set_delegated_voter(&owner_signer,validator.voter_address); + assert_validator_addresses_check(&validator); + + if (pbo_delegator_config.delegator_config.validator.join_during_genesis) { + initialize_validator(pool_address,&validator); + }; + } + + fun assert_validator_addresses_check(validator: &ValidatorConfiguration) { + assert!( + account::exists_at(validator.owner_address), + error::not_found(EACCOUNT_DOES_NOT_EXIST), + ); + assert!( + account::exists_at(validator.operator_address), + error::not_found(EACCOUNT_DOES_NOT_EXIST), + ); + assert!( + account::exists_at(validator.voter_address), + error::not_found(EACCOUNT_DOES_NOT_EXIST), + ); + } + + fun create_vesting_without_staking_pools( + vesting_pool_map : vector + ) { + let unique_accounts: vector
= vector::empty(); + vector::for_each_ref(&vesting_pool_map, |pool_config|{ + let pool_config: &VestingPoolsMap = pool_config; + let schedule = vector::empty(); + let schedule_length = vector::length(&pool_config.vesting_numerators); + assert!(schedule_length > 0, error::invalid_argument(EVESTING_SCHEDULE_IS_ZERO)); + assert!(pool_config.vesting_denominator > 0, error::invalid_argument(EDENOMINATOR_IS_ZERO)); + assert!(pool_config.vpool_locking_percentage > 0 && pool_config.vpool_locking_percentage <=100 , + error::invalid_argument(EPERCENTAGE_INVALID)); + //check the sum of numerator are <= denominator. + let sum = vector::fold(pool_config.vesting_numerators,0,|acc, x| acc + x); + // Check that total of all fraction in `vesting_schedule` is not greater than 1 + assert!(sum <= pool_config.vesting_denominator, + error::invalid_argument(ENUMERATOR_GREATER_THAN_DENOMINATOR)); + //assert that withdrawal_address is registered to receive SupraCoin + assert!(coin::is_account_registered(pool_config.withdrawal_address), error::invalid_argument(EACCOUNT_NOT_REGISTERED_FOR_COIN)); + //assertion on admin_address? + let admin = create_signer(pool_config.admin_address); + + //Create the vesting schedule + let j=0; + while (j < schedule_length) { + let numerator = *vector::borrow(&pool_config.vesting_numerators,j); + assert!(numerator > 0, error::invalid_argument(ENUMERATOR_IS_ZERO)); + let event = fixed_point32::create_from_rational(numerator,pool_config.vesting_denominator); + vector::push_back(&mut schedule,event); + j = j + 1; + }; + + let vesting_schedule = vesting_without_staking::create_vesting_schedule( + schedule, + timestamp::now_seconds() + pool_config.cliff_period_in_seconds, + pool_config.period_duration_in_seconds, + ); + + let buy_ins = simple_map::create(); + let num_shareholders = vector::length(&pool_config.shareholders); + assert!(num_shareholders > 0, error::invalid_argument(ENO_SHAREHOLDERS)); + let j = 0; + while (j < num_shareholders) { + let shareholder = *vector::borrow(&pool_config.shareholders,j); + assert!(!vector::contains(&unique_accounts,&shareholder), error::already_exists(EDUPLICATE_ACCOUNT)); + vector::push_back(&mut unique_accounts,shareholder); + let shareholder_signer = create_signer(shareholder); + let amount = coin::balance(shareholder); + let amount_to_extract = (amount * (pool_config.vpool_locking_percentage as u64)) / 100; + let coin_share = coin::withdraw(&shareholder_signer, amount_to_extract); + simple_map::add(&mut buy_ins,shareholder,coin_share); + j = j + 1; + }; + vesting_without_staking::create_vesting_contract( + &admin, + buy_ins, + vesting_schedule, + pool_config.withdrawal_address, + VESTING_CONTRACT_SEED + ); + }); + } + fun initialize_validator(pool_address: address, validator: &ValidatorConfiguration) { let operator = &create_signer(validator.operator_address); @@ -436,6 +674,9 @@ module supra_framework::genesis { set_genesis_end(supra_framework); } + #[test_only] + const ONE_APT: u64 = 100000000; + #[test_only] public fun setup() { initialize( @@ -446,7 +687,7 @@ module supra_framework::genesis { x"13", 1, 0, - 1, + 1000 * ONE_APT, 1, true, 1, @@ -509,4 +750,307 @@ module supra_framework::genesis { create_account(supra_framework, addr0, 23456); assert!(coin::balance(addr0) == 12345, 2); } + + #[test_only] + use aptos_std::ed25519; + + + #[test(supra_framework = @0x1)] + fun test_create_delegation_pool(supra_framework: &signer) { + setup(); + initialize_supra_coin(supra_framework); + let owner = @0x121341; + create_account(supra_framework, owner, 0); + create_account(supra_framework,@0x121344,0); + let (_, pk_1) = stake::generate_identity(); + let _pk_1 = ed25519::unvalidated_public_key_to_bytes(&pk_1); + let validator_config_commission = ValidatorConfigurationWithCommission{ + validator_config: ValidatorConfiguration{ + owner_address: @0x121342, + operator_address: @0x121343, + voter_address: @0x121344, + stake_amount: 100 * ONE_APT, + consensus_pubkey: _pk_1, + network_addresses: x"222222", + full_node_network_addresses: x"333333", + }, + commission_percentage: 10, + join_during_genesis: true, + }; + let delegation_pool_creation_seed = x"121341"; + let delegator_addresses = vector[@0x121342, @0x121343]; + let delegator_stakes = vector[100 * ONE_APT, 200 * ONE_APT]; + let i = 0; + while (i < vector::length(&delegator_addresses)) { + create_account(supra_framework, *vector::borrow(&delegator_addresses, i), *vector::borrow(&delegator_stakes, i)); + i = i + 1; + }; + let delegator_config = DelegatorConfiguration{ + owner_address: owner, + validator: validator_config_commission, + delegation_pool_creation_seed: delegation_pool_creation_seed, + delegator_addresses, + delegator_stakes + }; + create_delegation_pool(&delegator_config); + let pool_address = delegation_pool::get_owned_pool_address(owner); + assert!(delegation_pool::delegation_pool_exists(pool_address), 0); + delegation_pool::assert_delegation(@0x121342, pool_address, 100 * ONE_APT, 0, 0); + delegation_pool::assert_delegation(@0x121343, pool_address, 200 * ONE_APT, 0, 0); + } + + #[test(supra_framework = @0x1)] + fun test_create_delegation_pools(supra_framework: &signer) { + setup(); + initialize_supra_coin(supra_framework); + let owner1 = @0x121341; + create_account(supra_framework, owner1, 0); + + let (_, pk_1)=stake::generate_identity(); + let (_, pk_2)=stake::generate_identity(); + let _pk_1 = ed25519::unvalidated_public_key_to_bytes(&pk_1); + let _pk_2 = ed25519::unvalidated_public_key_to_bytes(&pk_2); + let validator_config_commission1 = ValidatorConfigurationWithCommission{ + validator_config: ValidatorConfiguration{ + owner_address: @0x121341, + operator_address: @0x121342, + voter_address: @0x121343, + stake_amount: 100 * ONE_APT, + consensus_pubkey: _pk_1, + network_addresses: x"222222", + full_node_network_addresses: x"333333", + }, + commission_percentage: 10, + join_during_genesis: true, + }; + let delegation_pool_creation_seed1 = x"121341"; + let delegator_addresses1 = vector[@0x121342, @0x121343]; + let delegator_stakes1 = vector[100 * ONE_APT, 200 * ONE_APT]; + let i = 0; + while (i < vector::length(&delegator_addresses1)) { + create_account(supra_framework, *vector::borrow(&delegator_addresses1, i), *vector::borrow(&delegator_stakes1, i)); + i = i + 1; + }; + let delegator_config1 = DelegatorConfiguration{ + owner_address: owner1, + validator: validator_config_commission1, + delegation_pool_creation_seed: delegation_pool_creation_seed1, + delegator_addresses: delegator_addresses1, + delegator_stakes: delegator_stakes1 + }; + let owner2 = @0x121344; + create_account(supra_framework, owner2, 0); + let validator_config_commission2 = ValidatorConfigurationWithCommission{ + validator_config: ValidatorConfiguration{ + owner_address: @0x121344, + operator_address: @0x121345, + voter_address: @0x121346, + stake_amount: 100 * ONE_APT, + consensus_pubkey: _pk_2, + network_addresses: x"222222", + full_node_network_addresses: x"333333", + }, + commission_percentage: 20, + join_during_genesis: true, + }; + let delegation_pool_creation_seed2 = x"121344"; + let delegator_addresses2 = vector[@0x121345, @0x121346]; + let delegator_stakes2 = vector[100 * ONE_APT, 200 * ONE_APT]; + let i = 0; + while (i < vector::length(&delegator_addresses2)) { + create_account(supra_framework, *vector::borrow(&delegator_addresses2, i), *vector::borrow(&delegator_stakes2, i)); + i = i + 1; + }; + let delegator_config2 = DelegatorConfiguration{ + owner_address: owner2, + validator: validator_config_commission2, + delegation_pool_creation_seed: delegation_pool_creation_seed2, + delegator_addresses: delegator_addresses2, + delegator_stakes: delegator_stakes2 + }; + let delegator_configs = vector[delegator_config1, delegator_config2]; + create_delegation_pools(delegator_configs); + let pool_address1 = delegation_pool::get_owned_pool_address(owner1); + let pool_address2 = delegation_pool::get_owned_pool_address(owner2); + assert!(delegation_pool::delegation_pool_exists(pool_address1), 0); + assert!(delegation_pool::delegation_pool_exists(pool_address2), 1); + } + + #[test(supra_framework = @0x1)] + fun test_create_pbo_delegation_pool(supra_framework: &signer) { + setup(); + initialize_supra_coin(supra_framework); + let owner = @0x121341; + let (_, pk_1) = stake::generate_identity(); + let _pk_1 = ed25519::unvalidated_public_key_to_bytes(&pk_1); + create_account(supra_framework, owner, 0); + let validator_config_commission = ValidatorConfigurationWithCommission{ + validator_config: ValidatorConfiguration{ + owner_address: @0x121341, + operator_address: @0x121342, + voter_address: @0x121343, + stake_amount: 0, + consensus_pubkey: _pk_1, + network_addresses: x"222222", + full_node_network_addresses: x"333333", + }, + commission_percentage: 10, + join_during_genesis: true, + }; + let delegation_pool_creation_seed = x"121341"; + let delegator_addresses = vector[@0x121342, @0x121343]; + let initial_balance = vector[100 * ONE_APT, 200 * ONE_APT]; + let i = 0; + let delegation_percentage = 10; + let delegator_stakes : vector = vector::empty(); + while (i < vector::length(&delegator_addresses)) { + create_account(supra_framework, *vector::borrow(&delegator_addresses, i), *vector::borrow(&initial_balance, i)); + vector::push_back(&mut delegator_stakes, *vector::borrow(&initial_balance, i) * delegation_percentage / 100); + i = i + 1; + }; + let principle_lockup_time = 100; + let pbo_delegator_config = PboDelegatorConfiguration{ + delegator_config: DelegatorConfiguration{ + owner_address: owner, + validator: validator_config_commission, + delegation_pool_creation_seed, + delegator_addresses, + delegator_stakes, + }, + principle_lockup_time, + }; + create_pbo_delegation_pool(&pbo_delegator_config, delegation_percentage); + let pool_address = pbo_delegation_pool::get_owned_pool_address(owner); + assert!(pbo_delegation_pool::delegation_pool_exists(pool_address), 0); + } + + #[test(supra_framework = @0x1)] + fun test_create_pbo_delegation_pools(supra_framework: &signer) { + setup(); + initialize_supra_coin(supra_framework); + let owner1 = @0x121341; + create_account(supra_framework,@0x121341,0); + let (_, pk_1)=stake::generate_identity(); + let (_, pk_2)=stake::generate_identity(); + let _pk_1 = ed25519::unvalidated_public_key_to_bytes(&pk_1); + let _pk_2 = ed25519::unvalidated_public_key_to_bytes(&pk_2); + let validator_config_commission1 = ValidatorConfigurationWithCommission{ + validator_config: ValidatorConfiguration{ + owner_address: @0x121341, + operator_address: @0x121342, + voter_address: @0x121343, + stake_amount: 100 * ONE_APT, + consensus_pubkey: _pk_1, + network_addresses: x"222222", + full_node_network_addresses: x"333333", + }, + commission_percentage: 10, + join_during_genesis: true, + }; + let delegation_pool_creation_seed1 = x"121341"; + let delegator_address1 = vector[@0x121342, @0x121343]; + let initial_balance1 = vector[100 * ONE_APT, 200 * ONE_APT]; + let delegator_stakes1:vector = vector::empty(); + let delegation_percentage: u64 = 10; + let i = 0; + while (i < vector::length(&delegator_address1)) { + create_account(supra_framework, *vector::borrow(&delegator_address1, i), *vector::borrow(&initial_balance1, i)); + vector::push_back(&mut delegator_stakes1, *vector::borrow(&initial_balance1, i) * delegation_percentage / 100); + i = i + 1; + }; + let principle_lockup_time1 = 100; + let pbo_delegator_config1 = PboDelegatorConfiguration{ + delegator_config: DelegatorConfiguration{ + owner_address: owner1, + validator: validator_config_commission1, + delegation_pool_creation_seed: delegation_pool_creation_seed1, + delegator_addresses: delegator_address1, + delegator_stakes: delegator_stakes1, + }, + principle_lockup_time: principle_lockup_time1, + }; + + let owner2 = @0x121344; + create_account(supra_framework, owner2, 0); + let validator_config_commission2 = ValidatorConfigurationWithCommission{ + validator_config: ValidatorConfiguration{ + owner_address: @0x121344, + operator_address: @0x121345, + voter_address: @0x121346, + stake_amount: 100 * ONE_APT, + consensus_pubkey: _pk_2, + network_addresses: x"222222", + full_node_network_addresses: x"333333", + }, + commission_percentage: 20, + join_during_genesis: true, + }; + let delegation_pool_creation_seed2 = x"121344"; + let delegator_address2 = vector[@0x121345, @0x121346]; + let initial_balance2 = vector[300 * ONE_APT, 400 * ONE_APT]; + let j = 0; + let delegator_stakes2:vector = vector::empty(); + while (j < vector::length(&delegator_address2)) { + let bal = vector::borrow(&initial_balance2,j); + create_account(supra_framework, *vector::borrow(&delegator_address2, j), *bal); + vector::push_back(&mut delegator_stakes2, (*bal) * delegation_percentage / 100); + j = j + 1; + }; + let principle_lockup_time2 = 200; + let pbo_delegator_config2 = PboDelegatorConfiguration{ + delegator_config: DelegatorConfiguration{ + owner_address: owner2, + validator: validator_config_commission2, + delegation_pool_creation_seed: delegation_pool_creation_seed2, + delegator_addresses: delegator_address2, + delegator_stakes: delegator_stakes2, + }, + principle_lockup_time: principle_lockup_time2, + }; + let pbo_delegator_configs = vector[pbo_delegator_config1, pbo_delegator_config2]; + create_pbo_delegation_pools(pbo_delegator_configs, delegation_percentage); + let pool_address1 = pbo_delegation_pool::get_owned_pool_address(owner1); + let pool_address2 = pbo_delegation_pool::get_owned_pool_address(owner2); + assert!(pbo_delegation_pool::delegation_pool_exists(pool_address1), 0); + assert!(pbo_delegation_pool::delegation_pool_exists(pool_address2), 1); + } + + #[test(supra_framework = @0x1)] + fun test_create_vesting_without_staking_pools(supra_framework: &signer) { + // use supra_framework::aptos_account::create_account; + setup(); + initialize_supra_coin(supra_framework); + timestamp::set_time_has_started_for_testing(supra_framework); + stake::initialize_for_test(supra_framework); + let admin_address = @0x121341; + let vpool_locking_percentage = 10; + let vesting_numerators = vector[1, 2, 3]; + let vesting_denominator = 6; + let withdrawal_address = @0x121342; + let shareholders = vector[@0x121343, @0x121344]; + create_account(supra_framework, admin_address , 0); + create_account(supra_framework, withdrawal_address , 0); + vector::for_each_ref(&shareholders, |addr| { + let addr: address = *addr; + if (!account::exists_at(addr)) { + create_account(supra_framework, addr, 100 * ONE_APT); + }; + }); + let cliff_period_in_seconds = 100; + let period_duration_in_seconds = 200; + let pool_config = VestingPoolsMap{ + admin_address: admin_address, + vpool_locking_percentage: vpool_locking_percentage, + vesting_numerators: vesting_numerators, + vesting_denominator: vesting_denominator, + withdrawal_address: withdrawal_address, + shareholders: shareholders, + cliff_period_in_seconds: cliff_period_in_seconds, + period_duration_in_seconds: period_duration_in_seconds, + }; + let vesting_pool_map = vector[pool_config]; + create_vesting_without_staking_pools(vesting_pool_map); + let vesting_contracts = vesting_without_staking::vesting_contracts(admin_address); + assert!(vector::length(&vesting_contracts) == 1, 0); + } }