From b67f9edfdf49dd5e9dc1314508ffba23d6dffcf3 Mon Sep 17 00:00:00 2001 From: axiongsupra Date: Thu, 9 Jan 2025 21:32:27 -0500 Subject: [PATCH] Update markdown document by running tests --- .../aptos-stdlib/doc/fixed_point64.md | 31 + .../src/aptos_framework_sdk_builder.rs | 275 +++++++++ .../move-stdlib/doc/fixed_point32.md | 31 + .../framework/supra-framework/doc/genesis.md | 35 +- .../doc/pbo_delegation_pool.md | 461 ++++++++++++-- .../framework/supra-framework/doc/stake.md | 1 - .../doc/vesting_without_staking.md | 584 +++++++++++++----- 7 files changed, 1176 insertions(+), 242 deletions(-) diff --git a/aptos-move/framework/aptos-stdlib/doc/fixed_point64.md b/aptos-move/framework/aptos-stdlib/doc/fixed_point64.md index 22571462f6c30..642601dc34a1b 100644 --- a/aptos-move/framework/aptos-stdlib/doc/fixed_point64.md +++ b/aptos-move/framework/aptos-stdlib/doc/fixed_point64.md @@ -12,6 +12,7 @@ a 64-bit fractional part. - [Function `sub`](#0x1_fixed_point64_sub) - [Function `add`](#0x1_fixed_point64_add) - [Function `multiply_u128`](#0x1_fixed_point64_multiply_u128) +- [Function `multiply_u128_return_fixpoint64`](#0x1_fixed_point64_multiply_u128_return_fixpoint64) - [Function `divide_u128`](#0x1_fixed_point64_divide_u128) - [Function `create_from_rational`](#0x1_fixed_point64_create_from_rational) - [Function `create_from_raw_value`](#0x1_fixed_point64_create_from_raw_value) @@ -255,6 +256,36 @@ overflows. + + + + +## Function `multiply_u128_return_fixpoint64` + + + +
public fun multiply_u128_return_fixpoint64(val: u128, multiplier: fixed_point64::FixedPoint64): fixed_point64::FixedPoint64
+
+ + + +
+Implementation + + +
public fun multiply_u128_return_fixpoint64(val: u128, multiplier: FixedPoint64): FixedPoint64 {
+    // The product of two 128 bit values has 256 bits, so perform the
+    // multiplication with u256 types and keep the full 256 bit product
+    // to avoid losing accuracy.
+    let unscaled_product = (val as u256) * (multiplier.value as u256);
+    // Check whether the value is too large.
+    assert!(unscaled_product <= MAX_U128, EMULTIPLICATION);
+    create_from_raw_value((unscaled_product as u128))
+}
+
+ + +
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 bb0301ff16c20..f6eafa7f6bae3 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 @@ -550,6 +550,33 @@ pub enum EntryFunctionCall { stakes: Vec, }, + /// Initialize a delegation pool without actual coin but withdraw from the owner's account. + PboDelegationPoolInitializeDelegationPoolWithAmount { + multisig_admin: AccountAddress, + amount: u64, + operator_commission_percentage: u64, + delegation_pool_creation_seed: Vec, + delegator_address: Vec, + principle_stake: Vec, + unlock_numerators: Vec, + unlock_denominator: u64, + unlock_start_time: u64, + unlock_duration: u64, + }, + + /// Initialize a delegation pool without actual coin but withdraw from the owner's account. + PboDelegationPoolInitializeDelegationPoolWithAmountWithoutMultisigAdmin { + amount: u64, + operator_commission_percentage: u64, + delegation_pool_creation_seed: Vec, + delegator_address: Vec, + principle_stake: Vec, + unlock_numerators: Vec, + unlock_denominator: u64, + unlock_start_time: u64, + unlock_duration: u64, + }, + /// Updates the `principle_stake` of each `delegator` in `delegators` according to the amount specified /// at the corresponding index of `new_principle_stakes`. Also ensures that the `delegator`'s `active` stake /// is as close to the specified amount as possible. The locked amount is subject to the vesting schedule @@ -622,6 +649,20 @@ pub enum EntryFunctionCall { new_commission_percentage: u64, }, + /// Pre-condition: `cumulative_unlocked_fraction` should be zero, which would indicate that even + /// though there are principle stake holders, none of those have yet called `unlock` on the pool + /// thus it is ``safe'' to change the schedule + /// This is a temporary measure to allow Supra Foundation to change the schedule for those pools + /// there were initialized with ``dummy/default'' schedule. This method must be disabled + /// before external validators are allowed to join the validator set. + PboDelegationPoolUpdateUnlockingSchedule { + pool_address: AccountAddress, + unlock_numerators: Vec, + unlock_denominator: u64, + unlock_start_time: u64, + unlock_duration: u64, + }, + /// Withdraw `amount` of owned inactive stake from the delegation pool at `pool_address`. PboDelegationPoolWithdraw { pool_address: AccountAddress, @@ -1530,6 +1571,50 @@ impl EntryFunctionCall { delegators, stakes, } => pbo_delegation_pool_fund_delegators_with_stake(pool_address, delegators, stakes), + PboDelegationPoolInitializeDelegationPoolWithAmount { + multisig_admin, + amount, + operator_commission_percentage, + delegation_pool_creation_seed, + delegator_address, + principle_stake, + unlock_numerators, + unlock_denominator, + unlock_start_time, + unlock_duration, + } => pbo_delegation_pool_initialize_delegation_pool_with_amount( + multisig_admin, + amount, + operator_commission_percentage, + delegation_pool_creation_seed, + delegator_address, + principle_stake, + unlock_numerators, + unlock_denominator, + unlock_start_time, + unlock_duration, + ), + PboDelegationPoolInitializeDelegationPoolWithAmountWithoutMultisigAdmin { + amount, + operator_commission_percentage, + delegation_pool_creation_seed, + delegator_address, + principle_stake, + unlock_numerators, + unlock_denominator, + unlock_start_time, + unlock_duration, + } => pbo_delegation_pool_initialize_delegation_pool_with_amount_without_multisig_admin( + amount, + operator_commission_percentage, + delegation_pool_creation_seed, + delegator_address, + principle_stake, + unlock_numerators, + unlock_denominator, + unlock_start_time, + unlock_duration, + ), PboDelegationPoolLockDelegatorsStakes { pool_address, delegators, @@ -1567,6 +1652,19 @@ impl EntryFunctionCall { PboDelegationPoolUpdateCommissionPercentage { new_commission_percentage, } => pbo_delegation_pool_update_commission_percentage(new_commission_percentage), + PboDelegationPoolUpdateUnlockingSchedule { + pool_address, + unlock_numerators, + unlock_denominator, + unlock_start_time, + unlock_duration, + } => pbo_delegation_pool_update_unlocking_schedule( + pool_address, + unlock_numerators, + unlock_denominator, + unlock_start_time, + unlock_duration, + ), PboDelegationPoolWithdraw { pool_address, amount, @@ -3336,6 +3434,80 @@ pub fn pbo_delegation_pool_fund_delegators_with_stake( )) } +/// Initialize a delegation pool without actual coin but withdraw from the owner's account. +pub fn pbo_delegation_pool_initialize_delegation_pool_with_amount( + multisig_admin: AccountAddress, + amount: u64, + operator_commission_percentage: u64, + delegation_pool_creation_seed: Vec, + delegator_address: Vec, + principle_stake: Vec, + unlock_numerators: Vec, + unlock_denominator: u64, + unlock_start_time: u64, + unlock_duration: 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!("pbo_delegation_pool").to_owned(), + ), + ident_str!("initialize_delegation_pool_with_amount").to_owned(), + vec![], + vec![ + bcs::to_bytes(&multisig_admin).unwrap(), + bcs::to_bytes(&amount).unwrap(), + bcs::to_bytes(&operator_commission_percentage).unwrap(), + bcs::to_bytes(&delegation_pool_creation_seed).unwrap(), + bcs::to_bytes(&delegator_address).unwrap(), + bcs::to_bytes(&principle_stake).unwrap(), + bcs::to_bytes(&unlock_numerators).unwrap(), + bcs::to_bytes(&unlock_denominator).unwrap(), + bcs::to_bytes(&unlock_start_time).unwrap(), + bcs::to_bytes(&unlock_duration).unwrap(), + ], + )) +} + +/// Initialize a delegation pool without actual coin but withdraw from the owner's account. +pub fn pbo_delegation_pool_initialize_delegation_pool_with_amount_without_multisig_admin( + amount: u64, + operator_commission_percentage: u64, + delegation_pool_creation_seed: Vec, + delegator_address: Vec, + principle_stake: Vec, + unlock_numerators: Vec, + unlock_denominator: u64, + unlock_start_time: u64, + unlock_duration: 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!("pbo_delegation_pool").to_owned(), + ), + ident_str!("initialize_delegation_pool_with_amount_without_multisig_admin").to_owned(), + vec![], + vec![ + bcs::to_bytes(&amount).unwrap(), + bcs::to_bytes(&operator_commission_percentage).unwrap(), + bcs::to_bytes(&delegation_pool_creation_seed).unwrap(), + bcs::to_bytes(&delegator_address).unwrap(), + bcs::to_bytes(&principle_stake).unwrap(), + bcs::to_bytes(&unlock_numerators).unwrap(), + bcs::to_bytes(&unlock_denominator).unwrap(), + bcs::to_bytes(&unlock_start_time).unwrap(), + bcs::to_bytes(&unlock_duration).unwrap(), + ], + )) +} + /// Updates the `principle_stake` of each `delegator` in `delegators` according to the amount specified /// at the corresponding index of `new_principle_stakes`. Also ensures that the `delegator`'s `active` stake /// is as close to the specified amount as possible. The locked amount is subject to the vesting schedule @@ -3532,6 +3704,39 @@ pub fn pbo_delegation_pool_update_commission_percentage( )) } +/// Pre-condition: `cumulative_unlocked_fraction` should be zero, which would indicate that even +/// though there are principle stake holders, none of those have yet called `unlock` on the pool +/// thus it is ``safe'' to change the schedule +/// This is a temporary measure to allow Supra Foundation to change the schedule for those pools +/// there were initialized with ``dummy/default'' schedule. This method must be disabled +/// before external validators are allowed to join the validator set. +pub fn pbo_delegation_pool_update_unlocking_schedule( + pool_address: AccountAddress, + unlock_numerators: Vec, + unlock_denominator: u64, + unlock_start_time: u64, + unlock_duration: 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!("pbo_delegation_pool").to_owned(), + ), + ident_str!("update_unlocking_schedule").to_owned(), + vec![], + vec![ + bcs::to_bytes(&pool_address).unwrap(), + bcs::to_bytes(&unlock_numerators).unwrap(), + bcs::to_bytes(&unlock_denominator).unwrap(), + bcs::to_bytes(&unlock_start_time).unwrap(), + bcs::to_bytes(&unlock_duration).unwrap(), + ], + )) +} + /// Withdraw `amount` of owned inactive stake from the delegation pool at `pool_address`. pub fn pbo_delegation_pool_withdraw( pool_address: AccountAddress, @@ -6040,6 +6245,49 @@ mod decoder { } } + pub fn pbo_delegation_pool_initialize_delegation_pool_with_amount( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some( + EntryFunctionCall::PboDelegationPoolInitializeDelegationPoolWithAmount { + multisig_admin: bcs::from_bytes(script.args().get(0)?).ok()?, + amount: bcs::from_bytes(script.args().get(1)?).ok()?, + operator_commission_percentage: bcs::from_bytes(script.args().get(2)?).ok()?, + delegation_pool_creation_seed: bcs::from_bytes(script.args().get(3)?).ok()?, + delegator_address: bcs::from_bytes(script.args().get(4)?).ok()?, + principle_stake: bcs::from_bytes(script.args().get(5)?).ok()?, + unlock_numerators: bcs::from_bytes(script.args().get(6)?).ok()?, + unlock_denominator: bcs::from_bytes(script.args().get(7)?).ok()?, + unlock_start_time: bcs::from_bytes(script.args().get(8)?).ok()?, + unlock_duration: bcs::from_bytes(script.args().get(9)?).ok()?, + }, + ) + } else { + None + } + } + + pub fn pbo_delegation_pool_initialize_delegation_pool_with_amount_without_multisig_admin( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::PboDelegationPoolInitializeDelegationPoolWithAmountWithoutMultisigAdmin { + amount : bcs::from_bytes(script.args().get(0)?).ok()?, + operator_commission_percentage : bcs::from_bytes(script.args().get(1)?).ok()?, + delegation_pool_creation_seed : bcs::from_bytes(script.args().get(2)?).ok()?, + delegator_address : bcs::from_bytes(script.args().get(3)?).ok()?, + principle_stake : bcs::from_bytes(script.args().get(4)?).ok()?, + unlock_numerators : bcs::from_bytes(script.args().get(5)?).ok()?, + unlock_denominator : bcs::from_bytes(script.args().get(6)?).ok()?, + unlock_start_time : bcs::from_bytes(script.args().get(7)?).ok()?, + unlock_duration : bcs::from_bytes(script.args().get(8)?).ok()?, + }) + } else { + None + } + } + pub fn pbo_delegation_pool_lock_delegators_stakes( payload: &TransactionPayload, ) -> Option { @@ -6158,6 +6406,24 @@ mod decoder { } } + pub fn pbo_delegation_pool_update_unlocking_schedule( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some( + EntryFunctionCall::PboDelegationPoolUpdateUnlockingSchedule { + pool_address: bcs::from_bytes(script.args().get(0)?).ok()?, + unlock_numerators: bcs::from_bytes(script.args().get(1)?).ok()?, + unlock_denominator: bcs::from_bytes(script.args().get(2)?).ok()?, + unlock_start_time: bcs::from_bytes(script.args().get(3)?).ok()?, + unlock_duration: bcs::from_bytes(script.args().get(4)?).ok()?, + }, + ) + } else { + None + } + } + pub fn pbo_delegation_pool_withdraw(payload: &TransactionPayload) -> Option { if let TransactionPayload::EntryFunction(script) = payload { Some(EntryFunctionCall::PboDelegationPoolWithdraw { @@ -7410,6 +7676,11 @@ static SCRIPT_FUNCTION_DECODER_MAP: once_cell::sync::Lazy + + + +## Function `multiply_u64_return_fixpoint32` + + + +
public fun multiply_u64_return_fixpoint32(val: u64, multiplier: fixed_point32::FixedPoint32): fixed_point32::FixedPoint32
+
+ + + +
+Implementation + + +
public fun multiply_u64_return_fixpoint32(val: u64, multiplier: FixedPoint32): FixedPoint32 {
+    // The product of two 64 bit values has 128 bits, so perform the
+    // multiplication with u128 types and keep the full 128 bit product
+    // to avoid losing accuracy.
+    let unscaled_product = (val as u128) * (multiplier.value as u128);
+    // Check whether the value is too large.
+    assert!(unscaled_product <= MAX_U64, EMULTIPLICATION);
+    create_from_raw_value((unscaled_product as u64))
+}
+
+ + +
diff --git a/aptos-move/framework/supra-framework/doc/genesis.md b/aptos-move/framework/supra-framework/doc/genesis.md index 8823b5d9a6d32..000797d28384f 100644 --- a/aptos-move/framework/supra-framework/doc/genesis.md +++ b/aptos-move/framework/supra-framework/doc/genesis.md @@ -797,17 +797,23 @@ If it exists, it just returns the signer. Implementation -
fun create_multiple_multisig_accounts_with_schema(supra_framework: &signer,
-owner: address, additional_owners: vector<address>,num_signatures_required:u64,metadata_keys:vector<String>,metadata_values:vector<vector<u8>>,
-timeout_duration:u64, balance:u64, num_of_accounts: u32): vector<address> {
-
+
fun create_multiple_multisig_accounts_with_schema(
+    supra_framework: &signer,
+    owner: address,
+    additional_owners: vector<address>,
+    num_signatures_required:u64,
+    metadata_keys:vector<String>,
+    metadata_values:vector<vector<u8>>,
+    timeout_duration:u64,
+    balance:u64,
+    num_of_accounts: u32
+): vector<address> {
     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
@@ -833,20 +839,25 @@ timeout_duration:u64, balance:u64, num_of_accounts: u32): create_multisig_account_with_balance(supra_framework: &signer, owner: address, additional_owners: vector<address>,
-                            num_signatures_required:u64, metadata_keys: vector<String>,
-                            metadata_values: vector<vector<u8>>, timeout_duration: u64, balance:u64 ) : address {
-
-
+
fun create_multisig_account_with_balance(
+    supra_framework: &signer,
+    owner: address,
+    additional_owners: vector<address>,
+    num_signatures_required:u64,
+    metadata_keys: vector<String>,
+    metadata_values: vector<vector<u8>>,
+    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);
+    account::increment_sequence_number(owner);
     addr
-
-    }
+}
 
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 0929cbb5b22bd..4e17e991cc979 100644 --- a/aptos-move/framework/supra-framework/doc/pbo_delegation_pool.md +++ b/aptos-move/framework/supra-framework/doc/pbo_delegation_pool.md @@ -131,6 +131,7 @@ transferred to A - [Struct `UnlockStakeEvent`](#0x1_pbo_delegation_pool_UnlockStakeEvent) - [Struct `WithdrawStakeEvent`](#0x1_pbo_delegation_pool_WithdrawStakeEvent) - [Struct `DistributeCommissionEvent`](#0x1_pbo_delegation_pool_DistributeCommissionEvent) +- [Struct `UnlockScheduleUpdated`](#0x1_pbo_delegation_pool_UnlockScheduleUpdated) - [Struct `DistributeCommission`](#0x1_pbo_delegation_pool_DistributeCommission) - [Struct `DelegatorReplacemendEvent`](#0x1_pbo_delegation_pool_DelegatorReplacemendEvent) - [Struct `VoteEvent`](#0x1_pbo_delegation_pool_VoteEvent) @@ -159,6 +160,11 @@ transferred to A - [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) - [Function `initialize_delegation_pool_with_amount`](#0x1_pbo_delegation_pool_initialize_delegation_pool_with_amount) +- [Function `initialize_delegation_pool_with_amount_without_multisig_admin`](#0x1_pbo_delegation_pool_initialize_delegation_pool_with_amount_without_multisig_admin) +- [Function `get_unlock_schedule`](#0x1_pbo_delegation_pool_get_unlock_schedule) +- [Function `create_schedule_fractions`](#0x1_pbo_delegation_pool_create_schedule_fractions) +- [Function `update_unlocking_schedule`](#0x1_pbo_delegation_pool_update_unlocking_schedule) +- [Function `validate_unlock_schedule_params`](#0x1_pbo_delegation_pool_validate_unlock_schedule_params) - [Function `initialize_delegation_pool`](#0x1_pbo_delegation_pool_initialize_delegation_pool) - [Function `fund_delegators_with_locked_stake`](#0x1_pbo_delegation_pool_fund_delegators_with_locked_stake) - [Function `fund_delegators_with_stake`](#0x1_pbo_delegation_pool_fund_delegators_with_stake) @@ -918,6 +924,58 @@ This struct should be stored in the delegation pool resource account. + + + + +## Struct `UnlockScheduleUpdated` + + + +
#[event]
+struct UnlockScheduleUpdated has drop, store
+
+ + + +
+Fields + + +
+
+pool_address: address +
+
+ +
+
+unlock_numerators: vector<u64> +
+
+ +
+
+unlock_denominator: u64 +
+
+ +
+
+unlock_start_time: u64 +
+
+ +
+
+unlock_duration: u64 +
+
+ +
+
+ +
@@ -1660,6 +1718,15 @@ Commission percentage change is too late in this lockup period, and should be do + + + + +
const EUNLOCKING_ALREADY_STARTED: u64 = 41;
+
+ + + Vector length is not the same. @@ -2112,6 +2179,7 @@ in each of its individual states: (active,inactive,assert_delegation_pool_exists(pool_address); let pool = borrow_global<DelegationPool>(pool_address); let (lockup_cycle_ended, active, _, commission_active, commission_pending_inactive) = + calculate_stake_pool_drift(pool); let total_active_shares = pool_u64::total_shares(&pool.active_shares); @@ -2378,7 +2446,7 @@ Return the minimum remaining time in seconds for commission change, which is one Initialize a delegation pool without actual coin but withdraw from the owner's account. -
public fun initialize_delegation_pool_with_amount(owner: &signer, multisig_admin: option::Option<address>, amount: u64, operator_commission_percentage: u64, delegation_pool_creation_seed: vector<u8>, delegator_address: vector<address>, principle_stake: vector<u64>, unlock_numerators: vector<u64>, unlock_denominator: u64, unlock_start_time: u64, unlock_duration: u64)
+
public entry fun initialize_delegation_pool_with_amount(owner: &signer, multisig_admin: address, amount: u64, operator_commission_percentage: u64, delegation_pool_creation_seed: vector<u8>, delegator_address: vector<address>, principle_stake: vector<u64>, unlock_numerators: vector<u64>, unlock_denominator: u64, unlock_start_time: u64, unlock_duration: u64)
 
@@ -2387,9 +2455,9 @@ Initialize a delegation pool without actual coin but withdraw from the owner's a Implementation -
public fun initialize_delegation_pool_with_amount(
+
public entry fun initialize_delegation_pool_with_amount(
     owner: &signer,
-    multisig_admin: option::Option<address>,
+    multisig_admin: address,
     amount: u64,
     operator_commission_percentage: u64,
     delegation_pool_creation_seed: vector<u8>,
@@ -2408,7 +2476,7 @@ Initialize a delegation pool without actual coin but withdraw from the owner's a
 
     initialize_delegation_pool(
         owner,
-        multisig_admin,
+        option::some(multisig_admin),
         operator_commission_percentage,
         delegation_pool_creation_seed,
         delegator_address,
@@ -2424,6 +2492,266 @@ Initialize a delegation pool without actual coin but withdraw from the owner's a
 
 
 
+
+
+
+
+## Function `initialize_delegation_pool_with_amount_without_multisig_admin`
+
+Initialize a delegation pool without actual coin but withdraw from the owner's account.
+
+
+
public entry fun initialize_delegation_pool_with_amount_without_multisig_admin(owner: &signer, amount: u64, operator_commission_percentage: u64, delegation_pool_creation_seed: vector<u8>, delegator_address: vector<address>, principle_stake: vector<u64>, unlock_numerators: vector<u64>, unlock_denominator: u64, unlock_start_time: u64, unlock_duration: u64)
+
+ + + +
+Implementation + + +
public entry fun initialize_delegation_pool_with_amount_without_multisig_admin(
+    owner: &signer,
+    amount: u64,
+    operator_commission_percentage: u64,
+    delegation_pool_creation_seed: vector<u8>,
+    delegator_address: vector<address>,
+    principle_stake: vector<u64>,
+    unlock_numerators: vector<u64>,
+    unlock_denominator: u64,
+    unlock_start_time: u64,
+    unlock_duration: u64
+) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage {
+    assert!(
+        coin::balance<SupraCoin>(signer::address_of(owner)) >= amount,
+        error::invalid_argument(EBALANCE_NOT_SUFFICIENT)
+    );
+    let coin = coin::withdraw<SupraCoin>(owner, amount);
+
+    initialize_delegation_pool(
+        owner,
+        option::none<address>(),
+        operator_commission_percentage,
+        delegation_pool_creation_seed,
+        delegator_address,
+        principle_stake,
+        coin,
+        unlock_numerators,
+        unlock_denominator,
+        unlock_start_time,
+        unlock_duration
+    )
+}
+
+ + + +
+ + + +## Function `get_unlock_schedule` + +Return the unlock schedule of the pool as (schedule, start_time, period_duration, last_unlock_period, cumulative_unlocked_fraction) + + +
#[view]
+public fun get_unlock_schedule(pool_address: address): (vector<fixed_point64::FixedPoint64>, u64, u64, u64, fixed_point64::FixedPoint64)
+
+ + + +
+Implementation + + +
public fun get_unlock_schedule(
+    pool_address: address
+): (vector<FixedPoint64>, u64, u64, u64, FixedPoint64) acquires DelegationPool {
+    let uschedule =
+        borrow_global<DelegationPool>(pool_address).principle_unlock_schedule;
+    (
+        uschedule.schedule,
+        uschedule.start_timestamp_secs,
+        uschedule.period_duration,
+        uschedule.last_unlock_period,
+        uschedule.cumulative_unlocked_fraction
+    )
+
+}
+
+ + + +
+ + + +## Function `create_schedule_fractions` + + + +
fun create_schedule_fractions(unlock_numerators: &vector<u64>, unlock_denominator: u64): vector<fixed_point64::FixedPoint64>
+
+ + + +
+Implementation + + +
fun create_schedule_fractions(unlock_numerators: &vector<u64>, unlock_denominator: u64) : vector<FixedPoint64> {
+
+//Create unlock schedule
+    let schedule = vector::empty();
+    vector::for_each_ref(
+        unlock_numerators,
+        |e| {
+            let fraction =
+                fixed_point64::create_from_rational(
+                    (*e as u128), (unlock_denominator as u128)
+                );
+            vector::push_back(&mut schedule, fraction);
+        }
+    );
+
+    schedule
+
+}
+
+ + + +
+ + + +## Function `update_unlocking_schedule` + +Pre-condition: cumulative_unlocked_fraction should be zero, which would indicate that even +though there are principle stake holders, none of those have yet called unlock on the pool +thus it is ```safe'' to change the schedule +This is a temporary measure to allow Supra Foundation to change the schedule for those pools +there were initialized with ```dummy/default'' schedule. This method must be disabled +before external validators are allowed to join the validator set. + + +
public entry fun update_unlocking_schedule(multisig_admin: &signer, pool_address: address, unlock_numerators: vector<u64>, unlock_denominator: u64, unlock_start_time: u64, unlock_duration: u64)
+
+ + + +
+Implementation + + +
public entry fun update_unlocking_schedule(
+    multisig_admin: &signer,
+    pool_address: address,
+    unlock_numerators: vector<u64>,
+    unlock_denominator: u64,
+    unlock_start_time: u64,
+    unlock_duration: u64
+) acquires DelegationPool {
+    assert!(
+        is_admin(signer::address_of(multisig_admin), pool_address),
+        error::permission_denied(ENOT_AUTHORIZED)
+    );
+    let pool = borrow_global_mut<DelegationPool>(pool_address);
+    assert!(
+        fixed_point64::is_zero(
+            pool.principle_unlock_schedule.cumulative_unlocked_fraction
+        ),
+        error::invalid_state(EUNLOCKING_ALREADY_STARTED)
+    );
+
+    validate_unlock_schedule_params(
+        &unlock_numerators,
+        unlock_denominator,
+        unlock_start_time,
+        unlock_duration
+    );
+
+    //Create unlock schedule fractions
+    let schedule = create_schedule_fractions(&unlock_numerators,unlock_denominator);
+
+    pool.principle_unlock_schedule = UnlockSchedule {
+        schedule: schedule,
+        start_timestamp_secs: unlock_start_time,
+        period_duration: unlock_duration,
+        last_unlock_period: 0,
+        cumulative_unlocked_fraction: fixed_point64::create_from_rational(0, 1)
+    };
+    event::emit(
+        UnlockScheduleUpdated {
+            pool_address,
+            unlock_numerators,
+            unlock_denominator,
+            unlock_start_time,
+            unlock_duration
+        }
+    );
+
+}
+
+ + + +
+ + + +## Function `validate_unlock_schedule_params` + + + +
fun validate_unlock_schedule_params(unlock_numerators: &vector<u64>, unlock_denominator: u64, _unlock_start_time: u64, unlock_duration: u64)
+
+ + + +
+Implementation + + +
fun validate_unlock_schedule_params(
+    unlock_numerators: &vector<u64>,
+    unlock_denominator: u64,
+    _unlock_start_time: u64,
+    unlock_duration: u64
+) {
+    //Unlock duration can not be zero
+    assert!(unlock_duration > 0, error::invalid_argument(EPERIOD_DURATION_IS_ZERO));
+    //Fraction denominator can not be zero
+    assert!(unlock_denominator != 0, error::invalid_argument(EDENOMINATOR_IS_ZERO));
+    let numerator_length = vector::length(unlock_numerators);
+    //Fraction numerators can not be empty
+    assert!(
+        numerator_length > 0,
+        error::invalid_argument(EEMPTY_UNLOCK_SCHEDULE)
+    );
+    //First and last numerator can not be zero
+    assert!(
+        *vector::borrow(unlock_numerators, 0) != 0,
+        error::invalid_argument(ESCHEDULE_WITH_ZERO_FRACTION)
+    );
+    assert!(
+        *vector::borrow(unlock_numerators, numerator_length - 1) != 0,
+        error::invalid_argument(ESCHEDULE_WITH_ZERO_FRACTION)
+    );
+
+    let sum = vector::foldr(*unlock_numerators, 0, |e, a| { e + a });
+    //Sum of numerators can not be greater than denominators
+    assert!(
+        sum <= unlock_denominator,
+        error::invalid_argument(ENUMERATORS_GRATER_THAN_DENOMINATOR)
+    );
+
+}
+
+ + +
@@ -2482,26 +2810,13 @@ Ownership over setting the operator/voter is granted to owner who h features::delegation_pools_enabled(), error::invalid_state(EDELEGATION_POOLS_DISABLED) ); - //Unlock duration can not be zero - assert!(unlock_duration > 0, error::invalid_argument(EPERIOD_DURATION_IS_ZERO)); - //Fraction denominator can not be zero - assert!(unlock_denominator != 0, error::invalid_argument(EDENOMINATOR_IS_ZERO)); - //Fraction numerators can not be empty - assert!( - vector::length(&unlock_numerators) > 0, - error::invalid_argument(EEMPTY_UNLOCK_SCHEDULE) - ); - //Fraction numerators can not be zero - assert!( - !vector::any(&unlock_numerators, |e| { *e == 0 }), - error::invalid_argument(ESCHEDULE_WITH_ZERO_FRACTION) - ); - let sum = vector::foldr(unlock_numerators, 0, |e, a| { e + a }); - //Sum of numerators can not be greater than denominators - assert!( - sum <= unlock_denominator, - error::invalid_argument(ENUMERATORS_GRATER_THAN_DENOMINATOR) + + validate_unlock_schedule_params( + &unlock_numerators, + unlock_denominator, + unlock_start_time, + unlock_duration ); let owner_address = signer::address_of(owner); @@ -2556,17 +2871,7 @@ Ownership over setting the operator/voter is granted to owner who h }; //Create unlock schedule - let schedule = vector::empty(); - vector::for_each_ref( - &unlock_numerators, - |e| { - let fraction = - fixed_point64::create_from_rational( - (*e as u128), (unlock_denominator as u128) - ); - vector::push_back(&mut schedule, fraction); - } - ); + let schedule = create_schedule_fractions(&unlock_numerators,unlock_denominator); move_to( &stake_pool_signer, @@ -2685,11 +2990,7 @@ Ownership over setting the operator/voter is granted to owner who h // Record the details of the lockup event. Note that only the newly locked // amount is reported and not the total locked amount. event::emit( - UnlockScheduleApplied { - pool_address, - delegator, - amount: stake - } + UnlockScheduleApplied { pool_address, delegator, amount: stake } ); } } @@ -3868,7 +4169,10 @@ Add amount of coins to the delegation pool pool_addressif amount to add is 0 so no event is emitted if (amount == 0) { return }; // fail unlock of less than `MIN_COINS_ON_SHARES_POOL` - assert!(amount >= MIN_COINS_ON_SHARES_POOL, error::invalid_argument(EMINIMUM_UNLOCK_AMOUNT)); + assert!( + amount >= MIN_COINS_ON_SHARES_POOL, + error::invalid_argument(EMINIMUM_UNLOCK_AMOUNT) + ); // synchronize delegation and stake pools before any user operation synchronize_delegation_pool(pool_address); @@ -4003,7 +4307,10 @@ authorized to reactivate their own stake. // short-circuit if amount to reactivate is 0 so no event is emitted if (amount == 0) { return }; // fail unlock of less than `MIN_COINS_ON_SHARES_POOL` - assert!(amount >= MIN_COINS_ON_SHARES_POOL, error::invalid_argument(EMINIMUM_UNLOCK_AMOUNT)); + assert!( + amount >= MIN_COINS_ON_SHARES_POOL, + error::invalid_argument(EMINIMUM_UNLOCK_AMOUNT) + ); // synchronize delegation and stake pools before any user operation synchronize_delegation_pool(pool_address); @@ -4016,12 +4323,7 @@ authorized to reactivate their own stake. amount ); let observed_lockup_cycle = pool.observed_lockup_cycle; - amount = redeem_inactive_shares( - pool, - delegator, - amount, - observed_lockup_cycle - ); + amount = redeem_inactive_shares(pool, delegator, amount, observed_lockup_cycle); stake::reactivate_stake(&retrieve_stake_pool_owner(pool), amount); @@ -4066,7 +4368,10 @@ validator-owners to prevent it from being abused.
fun admin_withdraw(
-    multisig_admin: &signer, pool_address: address, delegator_address: address, amount: u64
+    multisig_admin: &signer,
+    pool_address: address,
+    delegator_address: address,
+    amount: u64
 ) acquires DelegationPool, GovernanceRecords {
     // Ensure that the caller is the admin of the delegation pool.
     {
@@ -4080,7 +4385,7 @@ validator-owners to prevent it from being abused.
         borrow_global_mut<DelegationPool>(pool_address),
         delegator_address,
         amount,
-        signer::address_of(multisig_admin),
+        signer::address_of(multisig_admin)
     );
 }
 
@@ -4136,7 +4441,8 @@ validator-owners to prevent it from being abused. delegators, new_principle_stakes, |delegator, principle_stake| { - let (active, inactive, pending_inactive) = get_stake(pool_address, delegator); + let (active, inactive, pending_inactive) = + get_stake(pool_address, delegator); // Ensure that all stake to be locked is made `active`. if (active < principle_stake) { @@ -4154,14 +4460,17 @@ validator-owners to prevent it from being abused. if (amount_to_reactivate > MIN_COINS_ON_SHARES_POOL) { // Reactivate the required amount of `pending_inactive` stake first. - authorized_reactivate_stake(delegator, pool_address, amount_to_reactivate); + authorized_reactivate_stake( + delegator, pool_address, amount_to_reactivate + ); }; let active_and_pending_inactive = active + pending_inactive; if (active_and_pending_inactive < principle_stake) { // Need to reactivate some of the `inactive` stake. - let amount_to_withdraw = principle_stake - active_and_pending_inactive; + let amount_to_withdraw = + principle_stake - active_and_pending_inactive; // Ensure that we do not try to withdraw more stake than the `inactive` stake. if (amount_to_withdraw > inactive) { @@ -4177,7 +4486,12 @@ validator-owners to prevent it from being abused. amount_to_withdraw ); // Then allocate it to the delegator again. - fund_delegator_stake(multisig_admin, pool_address, delegator, amount_to_withdraw); + fund_delegator_stake( + multisig_admin, + pool_address, + delegator, + amount_to_withdraw + ); } } }; @@ -4515,16 +4829,26 @@ Note: this does not synchronize with stake pool, therefore the answer may be con let last_unlocked_period = unlock_schedule.last_unlock_period; let schedule_length = vector::length(&unlock_schedule.schedule); let cfraction = unlock_schedule.cumulative_unlocked_fraction; - while (last_unlocked_period < unlock_periods_passed && fixed_point64::less(cfraction, one) - && last_unlocked_period < schedule_length) { - let next_fraction = *vector::borrow(&unlock_schedule.schedule, last_unlocked_period); + while (last_unlocked_period < unlock_periods_passed + && fixed_point64::less(cfraction, one) + && last_unlocked_period < schedule_length) { + let next_fraction = + *vector::borrow(&unlock_schedule.schedule, last_unlocked_period); cfraction = fixed_point64::add(cfraction, next_fraction); last_unlocked_period = last_unlocked_period + 1; }; - if (last_unlocked_period < unlock_periods_passed && fixed_point64::less(cfraction, one)) { - let final_fraction= *vector::borrow(&unlock_schedule.schedule, schedule_length - 1); + if (last_unlocked_period < unlock_periods_passed + && fixed_point64::less(cfraction, one)) { + let final_fraction = + *vector::borrow(&unlock_schedule.schedule, schedule_length - 1); // Acclerate calculation to current period and don't update last_unlocked_period since it is not used anymore - cfraction = fixed_point64::add(cfraction, fixed_point64::multiply_u128_return_fixpoint64((unlock_periods_passed - last_unlocked_period as u128), final_fraction)); + cfraction = fixed_point64::add( + cfraction, + fixed_point64::multiply_u128_return_fixpoint64( + (unlock_periods_passed - last_unlocked_period as u128), + final_fraction + ) + ); cfraction = fixed_point64::min(cfraction, one); }; unlock_schedule.cumulative_unlocked_fraction = cfraction; @@ -4561,7 +4885,10 @@ at most how much active stake there is on the stake pool. // short-circuit if amount to unlock is 0 so no event is emitted if (amount == 0) { return }; // fail unlock of less than `MIN_COINS_ON_SHARES_POOL` - assert!(amount >= MIN_COINS_ON_SHARES_POOL, error::invalid_argument(EMINIMUM_UNLOCK_AMOUNT)); + assert!( + amount >= MIN_COINS_ON_SHARES_POOL, + error::invalid_argument(EMINIMUM_UNLOCK_AMOUNT) + ); // fail unlock of more stake than `active` on the stake pool let (active, _, _, _) = stake::get_stake(pool_address); assert!( @@ -4664,7 +4991,7 @@ Withdraw amount of owned inactive stake from the delegation pool at borrow_global_mut<DelegationPool>(pool_address), delegator_address, amount, - delegator_address, + delegator_address ); }
@@ -4689,7 +5016,10 @@ Withdraw amount of owned inactive stake from the delegation pool at
fun withdraw_internal(
-    pool: &mut DelegationPool, delegator_address: address, amount: u64, recipient_address: address
+    pool: &mut DelegationPool,
+    delegator_address: address,
+    amount: u64,
+    recipient_address: address
 ) acquires GovernanceRecords {
     // TODO: recycle storage when a delegator fully exits the delegation pool.
     // short-circuit if amount to withdraw is 0 so no event is emitted
@@ -4869,7 +5199,12 @@ be explicitly withdrawn by delegator
         pending_withdrawal_exists(pool, delegator_address);
     if (withdrawal_exists
         && withdrawal_olc.index < pool.observed_lockup_cycle.index) {
-        withdraw_internal(pool, delegator_address, MAX_U64, delegator_address);
+        withdraw_internal(
+            pool,
+            delegator_address,
+            MAX_U64,
+            delegator_address
+        );
     }
 }
 
diff --git a/aptos-move/framework/supra-framework/doc/stake.md b/aptos-move/framework/supra-framework/doc/stake.md index 6f8c32f667cc2..20ce522964df5 100644 --- a/aptos-move/framework/supra-framework/doc/stake.md +++ b/aptos-move/framework/supra-framework/doc/stake.md @@ -5491,7 +5491,6 @@ Returns validator's next epoch voting power, including pending_active, active, a
pragma verify = false;
-pragma disable_invariants_in_body;
 include ResourceRequirement;
 include GetReconfigStartTimeRequirement;
 include staking_config::StakingRewardsConfigRequirement;
diff --git a/aptos-move/framework/supra-framework/doc/vesting_without_staking.md b/aptos-move/framework/supra-framework/doc/vesting_without_staking.md
index 8b6ddf1f8ef2e..c334e70ebaf48 100644
--- a/aptos-move/framework/supra-framework/doc/vesting_without_staking.md
+++ b/aptos-move/framework/supra-framework/doc/vesting_without_staking.md
@@ -21,6 +21,9 @@ Vesting without staking contract
 -  [Constants](#@Constants_0)
 -  [Function `vesting_start_secs`](#0x1_vesting_without_staking_vesting_start_secs)
 -  [Function `period_duration_secs`](#0x1_vesting_without_staking_period_duration_secs)
+-  [Function `get_withdrawal_addr`](#0x1_vesting_without_staking_get_withdrawal_addr)
+-  [Function `get_contract_admin`](#0x1_vesting_without_staking_get_contract_admin)
+-  [Function `get_vesting_record`](#0x1_vesting_without_staking_get_vesting_record)
 -  [Function `remaining_grant`](#0x1_vesting_without_staking_remaining_grant)
 -  [Function `beneficiary`](#0x1_vesting_without_staking_beneficiary)
 -  [Function `vesting_contracts`](#0x1_vesting_without_staking_vesting_contracts)
@@ -735,6 +738,8 @@ Admin can only withdraw from an inactive (paused or terminated) vesting contract
 
 
 
+Deprecated.
+
 Vesting cannot start before or at the current block timestamp. Has to be in the future.
 
 
@@ -861,6 +866,93 @@ This errors out if the vesting contract with the provided address doesn't exist.
 
 
 
+
+
+
+
+## Function `get_withdrawal_addr`
+
+
+
+
#[view]
+public fun get_withdrawal_addr(vesting_contract_addr: address): address
+
+ + + +
+Implementation + + +
public fun get_withdrawal_addr(vesting_contract_addr: address): address acquires VestingContract {
+    borrow_global<VestingContract>(vesting_contract_addr).withdrawal_address
+}
+
+ + + +
+ + + +## Function `get_contract_admin` + + + +
#[view]
+public fun get_contract_admin(vesting_contract_addr: address): address
+
+ + + +
+Implementation + + +
public fun get_contract_admin(vesting_contract_addr: address): address acquires VestingContract {
+    borrow_global<VestingContract>(vesting_contract_addr).admin
+}
+
+ + + +
+ + + +## Function `get_vesting_record` + + + +
#[view]
+public fun get_vesting_record(vesting_contract_address: address, shareholder_address: address): (u64, u64, u64)
+
+ + + +
+Implementation + + +
public fun get_vesting_record(
+    vesting_contract_address: address, shareholder_address: address
+): (u64, u64, u64) acquires VestingContract {
+    assert_vesting_contract_exists(vesting_contract_address);
+    let vesting_record =
+        simple_map::borrow(
+            &borrow_global<VestingContract>(vesting_contract_address).shareholders,
+            &shareholder_address
+        );
+    (
+        vesting_record.init_amount,
+        vesting_record.left_amount,
+        vesting_record.last_vested_period
+    )
+}
+
+ + +
@@ -880,11 +972,14 @@ Return the remaining grant of shareholder Implementation -
public fun remaining_grant(vesting_contract_address: address, shareholder_address: address)
-    : u64 acquires VestingContract {
+
public fun remaining_grant(
+    vesting_contract_address: address, shareholder_address: address
+): u64 acquires VestingContract {
     assert_vesting_contract_exists(vesting_contract_address);
-    simple_map::borrow(&borrow_global<VestingContract>(vesting_contract_address).shareholders,
-        &shareholder_address).left_amount
+    simple_map::borrow(
+        &borrow_global<VestingContract>(vesting_contract_address).shareholders,
+        &shareholder_address
+    ).left_amount
 }
 
@@ -912,10 +1007,13 @@ This errors out if the vesting contract with the provided address doesn't exist. Implementation -
public fun beneficiary(vesting_contract_address: address, shareholder: address): address acquires VestingContract {
+
public fun beneficiary(
+    vesting_contract_address: address, shareholder: address
+): address acquires VestingContract {
     assert_vesting_contract_exists(vesting_contract_address);
-    get_beneficiary(borrow_global<VestingContract>(vesting_contract_address),
-        shareholder)
+    get_beneficiary(
+        borrow_global<VestingContract>(vesting_contract_address), shareholder
+    )
 }
 
@@ -978,7 +1076,9 @@ This errors out if the vesting contract with the provided address doesn't exist. Implementation -
public fun vesting_schedule(vesting_contract_address: address): VestingSchedule acquires VestingContract {
+
public fun vesting_schedule(
+    vesting_contract_address: address
+): VestingSchedule acquires VestingContract {
     assert_vesting_contract_exists(vesting_contract_address);
     borrow_global<VestingContract>(vesting_contract_address).vesting_schedule
 }
@@ -1005,7 +1105,9 @@ Return the list of all shareholders in the vesting contract.
 Implementation
 
 
-
public fun shareholders(vesting_contract_address: address): vector<address> acquires VestingContract {
+
public fun shareholders(
+    vesting_contract_address: address
+): vector<address> acquires VestingContract {
     assert_active_vesting_contract(vesting_contract_address);
 
     let vesting_contract = borrow_global<VestingContract>(vesting_contract_address);
@@ -1039,8 +1141,9 @@ This returns 0x0 if no shareholder is found for the given beneficiary / the addr
 Implementation
 
 
-
public fun shareholder(vesting_contract_address: address, shareholder_or_beneficiary: address)
-    : address acquires VestingContract {
+
public fun shareholder(
+    vesting_contract_address: address, shareholder_or_beneficiary: address
+): address acquires VestingContract {
     assert_active_vesting_contract(vesting_contract_address);
 
     let shareholders = &shareholders(vesting_contract_address);
@@ -1050,7 +1153,9 @@ This returns 0x0 if no shareholder is found for the given beneficiary / the addr
     let vesting_contract = borrow_global<VestingContract>(vesting_contract_address);
     let result = @0x0;
     let (sh_vec, ben_vec) = simple_map::to_vec_pair(vesting_contract.beneficiaries);
-    let (found, found_index) = vector::index_of(&ben_vec, &shareholder_or_beneficiary);
+    let (found, found_index) = vector::index_of(
+        &ben_vec, &shareholder_or_beneficiary
+    );
     if (found) {
         result = *vector::borrow(&sh_vec, found_index);
     };
@@ -1079,27 +1184,31 @@ Create a vesting schedule with the given schedule of distributions, a vesting st
 
 
 
public fun create_vesting_schedule(
-    schedule: vector<FixedPoint32>, start_timestamp_secs: u64, period_duration: u64,
+    schedule: vector<FixedPoint32>,
+    start_timestamp_secs: u64,
+    period_duration: u64
 ): VestingSchedule {
     let schedule_len = vector::length(&schedule);
     assert!(schedule_len > 0, error::invalid_argument(EEMPTY_VESTING_SCHEDULE));
     // If the first vesting fraction is zero, we can replace it with nonzero by increasing start time
-    assert!(fixed_point32::get_raw_value(*vector::borrow(&schedule, 0)) != 0,
-        error::invalid_argument(EEMPTY_VESTING_SCHEDULE));
+    assert!(
+        fixed_point32::get_raw_value(*vector::borrow(&schedule, 0)) != 0,
+        error::invalid_argument(EEMPTY_VESTING_SCHEDULE)
+    );
     // last vesting fraction must be non zero to ensure that no amount remains unvested forever.
-    assert!(fixed_point32::get_raw_value(*vector::borrow(&schedule, schedule_len - 1))
-        != 0,
-        error::invalid_argument(EEMPTY_VESTING_SCHEDULE));
-
-    assert!(period_duration > 0, error::invalid_argument(EZERO_VESTING_SCHEDULE_PERIOD));
-    assert!(start_timestamp_secs >= timestamp::now_seconds(),
-        error::invalid_argument(EVESTING_START_TOO_SOON),);
-
+    assert!(
+        fixed_point32::get_raw_value(*vector::borrow(&schedule, schedule_len - 1))
+            != 0,
+        error::invalid_argument(EEMPTY_VESTING_SCHEDULE)
+    );
+    assert!(
+        period_duration > 0, error::invalid_argument(EZERO_VESTING_SCHEDULE_PERIOD)
+    );
     VestingSchedule {
         schedule,
         start_timestamp_secs,
         period_duration,
-        last_vested_period: 0,
+        last_vested_period: 0
     }
 }
 
@@ -1114,7 +1223,7 @@ Create a vesting schedule with the given schedule of distributions, a vesting st -
public entry fun create_vesting_contract_with_amounts(admin: &signer, shareholders: vector<address>, amounts: vector<u64>, schedule_numerator: vector<u64>, schedule_denominator: u64, start_timestamp_secs: u64, period_duration: u64, withdrawal_address: address, contract_creation_seed: vector<u8>)
+
public entry fun create_vesting_contract_with_amounts(admin: &signer, shareholders: vector<address>, shares: vector<u64>, vesting_numerators: vector<u64>, vesting_denominator: u64, start_timestamp_secs: u64, period_duration: u64, withdrawal_address: address, contract_creation_seed: vector<u8>)
 
@@ -1123,91 +1232,115 @@ Create a vesting schedule with the given schedule of distributions, a vesting st Implementation -
public entry fun create_vesting_contract_with_amounts (
+
public entry fun create_vesting_contract_with_amounts(
     admin: &signer,
     shareholders: vector<address>,
-    amounts: vector<u64>,
-    schedule_numerator: vector<u64>,
-    schedule_denominator: u64,
+    shares: vector<u64>,
+    vesting_numerators: vector<u64>,
+    vesting_denominator: u64,
     start_timestamp_secs: u64,
     period_duration: u64,
     withdrawal_address: address,
-    contract_creation_seed: vector<u8>,
+    contract_creation_seed: vector<u8>
 ) acquires AdminStore {
-    assert!(!system_addresses::is_reserved_address(withdrawal_address),
-        error::invalid_argument(EINVALID_WITHDRAWAL_ADDRESS),);
-    assert_account_is_registered_for_apt(withdrawal_address);
-    assert!(vector::length(&shareholders) > 0,
-        error::invalid_argument(ENO_SHAREHOLDERS));
     assert!(
-        vector::length(&shareholders) == vector::length(&amounts),
-        error::invalid_argument(ESHARES_LENGTH_MISMATCH),
+        !system_addresses::is_reserved_address(withdrawal_address),
+        error::invalid_argument(EINVALID_WITHDRAWAL_ADDRESS)
+    );
+    assert_account_is_registered_for_supra(withdrawal_address);
+    assert!(
+        vector::length(&shareholders) > 0,
+        error::invalid_argument(ENO_SHAREHOLDERS)
+    );
+    assert!(
+        vector::length(&shareholders) == vector::length(&shares),
+        error::invalid_argument(ESHARES_LENGTH_MISMATCH)
     );
 
     // If this is the first time this admin account has created a vesting contract, initialize the admin store.
     let admin_address = signer::address_of(admin);
     if (!exists<AdminStore>(admin_address)) {
-        move_to(admin,
+        move_to(
+            admin,
             AdminStore {
                 vesting_contracts: vector::empty<address>(),
                 nonce: 0,
-                create_events: new_event_handle<CreateVestingContractEvent>(admin),
-            });
+                create_events: new_event_handle<CreateVestingContractEvent>(admin)
+            }
+        );
     };
 
     // Initialize the vesting contract in a new resource account. This allows the same admin to create multiple
     // pools.
-    let (contract_signer, contract_signer_cap) = create_vesting_contract_account(admin,
-        contract_creation_seed);
+    let (contract_signer, contract_signer_cap) =
+        create_vesting_contract_account(admin, contract_creation_seed);
     let contract_signer_address = signer::address_of(&contract_signer);
-    let schedule = vector::map_ref(&schedule_numerator, |numerator| {
-        let event = fixed_point32::create_from_rational(*numerator, schedule_denominator);
-        event
-    });
+    let schedule = vector::map_ref(
+        &vesting_numerators,
+        |numerator| {
+            let event =
+                fixed_point32::create_from_rational(*numerator, vesting_denominator);
+            event
+        }
+    );
 
-    let vesting_schedule = create_vesting_schedule(schedule, start_timestamp_secs, period_duration);
+    let vesting_schedule =
+        create_vesting_schedule(schedule, start_timestamp_secs, period_duration);
     let shareholders_map = simple_map::create<address, VestingRecord>();
     let grant_amount = 0;
-    vector::for_each_reverse(amounts, |amount| {
-        let shareholder = vector::pop_back(&mut shareholders);
-        simple_map::add(&mut shareholders_map,
-            shareholder,
-            VestingRecord {
-                init_amount: amount,
-                left_amount: amount,
-                last_vested_period: vesting_schedule.last_vested_period,
-            }
-        );
-        grant_amount = grant_amount + amount;
-    });
+    vector::for_each_reverse(
+        shares,
+        |amount| {
+            let shareholder = vector::pop_back(&mut shareholders);
+            simple_map::add(
+                &mut shareholders_map,
+                shareholder,
+                VestingRecord {
+                    init_amount: amount,
+                    left_amount: amount,
+                    last_vested_period: vesting_schedule.last_vested_period
+                }
+            );
+            grant_amount = grant_amount + amount;
+        }
+    );
     assert!(grant_amount > 0, error::invalid_argument(EZERO_GRANT));
     coin::transfer<SupraCoin>(admin, contract_signer_address, grant_amount);
 
     let admin_store = borrow_global_mut<AdminStore>(admin_address);
     vector::push_back(&mut admin_store.vesting_contracts, contract_signer_address);
-    emit_event(&mut admin_store.create_events,
+    emit_event(
+        &mut admin_store.create_events,
         CreateVestingContractEvent {
             withdrawal_address,
             grant_amount,
-            vesting_contract_address: contract_signer_address,
-        },
+            vesting_contract_address: contract_signer_address
+        }
     );
 
-    move_to(&contract_signer,
+    move_to(
+        &contract_signer,
         VestingContract {
             state: VESTING_POOL_ACTIVE,
             admin: admin_address,
-            shareholders:shareholders_map,
+            shareholders: shareholders_map,
             beneficiaries: simple_map::create<address, address>(),
             vesting_schedule,
             withdrawal_address,
             signer_cap: contract_signer_cap,
-            set_beneficiary_events: new_event_handle<SetBeneficiaryEvent>(&contract_signer),
+            set_beneficiary_events: new_event_handle<SetBeneficiaryEvent>(
+                &contract_signer
+            ),
             vest_events: new_event_handle<VestEvent>(&contract_signer),
             terminate_events: new_event_handle<TerminateEvent>(&contract_signer),
-            admin_withdraw_events: new_event_handle<AdminWithdrawEvent>(&contract_signer),
-            shareholder_removed_events: new_event_handle<ShareHolderRemovedEvent>(&contract_signer),
-        });
+            admin_withdraw_events: new_event_handle<AdminWithdrawEvent>(
+                &contract_signer
+            ),
+            shareholder_removed_events: new_event_handle<ShareHolderRemovedEvent>(
+                &contract_signer
+            )
+        }
+    );
 }
 
@@ -1236,14 +1369,18 @@ Create a vesting contract with a given configurations. buy_ins: SimpleMap<address, Coin<SupraCoin>>, vesting_schedule: VestingSchedule, withdrawal_address: address, - contract_creation_seed: vector<u8>, + contract_creation_seed: vector<u8> ): address acquires AdminStore { - assert!(!system_addresses::is_reserved_address(withdrawal_address), - error::invalid_argument(EINVALID_WITHDRAWAL_ADDRESS),); + assert!( + !system_addresses::is_reserved_address(withdrawal_address), + error::invalid_argument(EINVALID_WITHDRAWAL_ADDRESS) + ); assert_account_is_registered_for_supra(withdrawal_address); let shareholders_address = &simple_map::keys(&buy_ins); - assert!(vector::length(shareholders_address) > 0, - error::invalid_argument(ENO_SHAREHOLDERS)); + assert!( + vector::length(shareholders_address) > 0, + error::invalid_argument(ENO_SHAREHOLDERS) + ); let shareholders = simple_map::create<address, VestingRecord>(); let grant = coin::zero<SupraCoin>(); @@ -1254,12 +1391,13 @@ Create a vesting contract with a given configurations. let buy_in = vector::pop_back(&mut buy_ins); let init = coin::value(&buy_in); coin::merge(&mut grant, buy_in); - simple_map::add(&mut shareholders, + simple_map::add( + &mut shareholders, shareholder, VestingRecord { init_amount: init, left_amount: init, - last_vested_period: vesting_schedule.last_vested_period, + last_vested_period: vesting_schedule.last_vested_period } ); grant_amount = grant_amount + init; @@ -1269,32 +1407,36 @@ Create a vesting contract with a given configurations. // If this is the first time this admin account has created a vesting contract, initialize the admin store. let admin_address = signer::address_of(admin); if (!exists<AdminStore>(admin_address)) { - move_to(admin, + move_to( + admin, AdminStore { vesting_contracts: vector::empty<address>(), nonce: 0, - create_events: new_event_handle<CreateVestingContractEvent>(admin), - }); + create_events: new_event_handle<CreateVestingContractEvent>(admin) + } + ); }; // Initialize the vesting contract in a new resource account. This allows the same admin to create multiple // pools. - let (contract_signer, contract_signer_cap) = create_vesting_contract_account(admin, - contract_creation_seed); + let (contract_signer, contract_signer_cap) = + create_vesting_contract_account(admin, contract_creation_seed); let contract_signer_address = signer::address_of(&contract_signer); coin::deposit(contract_signer_address, grant); let admin_store = borrow_global_mut<AdminStore>(admin_address); vector::push_back(&mut admin_store.vesting_contracts, contract_signer_address); - emit_event(&mut admin_store.create_events, + emit_event( + &mut admin_store.create_events, CreateVestingContractEvent { withdrawal_address, grant_amount, - vesting_contract_address: contract_signer_address, - }, + vesting_contract_address: contract_signer_address + } ); - move_to(&contract_signer, + move_to( + &contract_signer, VestingContract { state: VESTING_POOL_ACTIVE, admin: admin_address, @@ -1303,12 +1445,19 @@ Create a vesting contract with a given configurations. vesting_schedule, withdrawal_address, signer_cap: contract_signer_cap, - set_beneficiary_events: new_event_handle<SetBeneficiaryEvent>(&contract_signer), + set_beneficiary_events: new_event_handle<SetBeneficiaryEvent>( + &contract_signer + ), vest_events: new_event_handle<VestEvent>(&contract_signer), terminate_events: new_event_handle<TerminateEvent>(&contract_signer), - admin_withdraw_events: new_event_handle<AdminWithdrawEvent>(&contract_signer), - shareholder_removed_events: new_event_handle<ShareHolderRemovedEvent>(&contract_signer), - }); + admin_withdraw_events: new_event_handle<AdminWithdrawEvent>( + &contract_signer + ), + shareholder_removed_events: new_event_handle<ShareHolderRemovedEvent>( + &contract_signer + ) + } + ); vector::destroy_empty(buy_ins); contract_signer_address @@ -1339,7 +1488,8 @@ Unlock any vested portion of the grant. assert_active_vesting_contract(contract_address); let vesting_contract = borrow_global_mut<VestingContract>(contract_address); // Short-circuit if vesting hasn't started yet. - if (vesting_contract.vesting_schedule.start_timestamp_secs > timestamp::now_seconds()) { return }; + if (vesting_contract.vesting_schedule.start_timestamp_secs + > timestamp::now_seconds()) { return }; let shareholders = simple_map::keys(&vesting_contract.shareholders); while (vector::length(&shareholders) > 0) { @@ -1372,16 +1522,22 @@ Unlock any vested portion of the grant. Implementation -
public entry fun vest_individual(contract_address: address, shareholder_address: address) acquires VestingContract {
+
public entry fun vest_individual(
+    contract_address: address, shareholder_address: address
+) acquires VestingContract {
     //check if contract exist, active and shareholder is a member of the contract
     assert_shareholder_exists(contract_address, shareholder_address);
 
     let vesting_contract = borrow_global_mut<VestingContract>(contract_address);
     let beneficiary = get_beneficiary(vesting_contract, shareholder_address);
     // Short-circuit if vesting hasn't started yet.
-    if (vesting_contract.vesting_schedule.start_timestamp_secs > timestamp::now_seconds()) { return };
+    if (vesting_contract.vesting_schedule.start_timestamp_secs
+        > timestamp::now_seconds()) { return };
 
-    let vesting_record = simple_map::borrow_mut(&mut vesting_contract.shareholders, &shareholder_address);
+    let vesting_record =
+        simple_map::borrow_mut(
+            &mut vesting_contract.shareholders, &shareholder_address
+        );
     let signer_cap = &vesting_contract.signer_cap;
 
     // Check if the next vested period has already passed. If not, short-circuit since there's nothing to vest.
@@ -1389,29 +1545,58 @@ Unlock any vested portion of the grant.
     let schedule = &vesting_schedule.schedule;
     let last_vested_period = vesting_record.last_vested_period;
     let next_period_to_vest = last_vested_period + 1;
-    let last_completed_period = (timestamp::now_seconds() - vesting_schedule.start_timestamp_secs)
-        / vesting_schedule.period_duration;
+    let last_completed_period =
+        (timestamp::now_seconds() - vesting_schedule.start_timestamp_secs)
+            / vesting_schedule.period_duration;
 
     // Index is 0-based while period is 1-based so we need to subtract 1.
-    while (last_completed_period >= next_period_to_vest && vesting_record.left_amount > 0) {
+
+    while (last_completed_period >= next_period_to_vest && vesting_record.left_amount > 0 && next_period_to_vest <= vector::length(schedule)) {
         let schedule_index = next_period_to_vest - 1;
-        let vesting_fraction = if (schedule_index < vector::length(schedule)) {
-            *vector::borrow(schedule, schedule_index)
+        let vesting_fraction = *vector::borrow(schedule, schedule_index);
+        vest_transfer(vesting_record, signer_cap, beneficiary, vesting_fraction);
+        emit_event(&mut vesting_contract.vest_events,
+            VestEvent {
+                admin: vesting_contract.admin,
+                shareholder_address,
+                vesting_contract_address: contract_address,
+                period_vested: next_period_to_vest
+            }
+        );
+        next_period_to_vest = next_period_to_vest + 1;
+    };
+
+    if(last_completed_period >= next_period_to_vest && vesting_record.left_amount > 0) {
+        let final_fraction = *vector::borrow(schedule, vector::length(schedule) - 1);
+        let final_fraction_amount = fixed_point32::multiply_u64(vesting_record.init_amount, final_fraction);
+        // Determine how many periods is needed based on the left_amount
+        let added_fraction = fixed_point32::multiply_u64_return_fixpoint32(last_completed_period - next_period_to_vest + 1, final_fraction);
+        // If the added_fraction is greater than or equal to the left_amount, then we can vest all the left_amount
+        let periods_need =
+            if (fixed_point32::multiply_u64(vesting_record.init_amount, added_fraction) >= vesting_record.left_amount){
+            let result =  vesting_record.left_amount / final_fraction_amount;
+                // check if `left_amount` is perfectly divisible by `final_fraction_amount`
+                  if (vesting_record.left_amount == final_fraction_amount*result) {
+                   result
+                } else {
+                   result + 1
+                }
         } else {
-            // Last vesting schedule fraction will repeat until the grant runs out.
-            *vector::borrow(schedule, vector::length(schedule) - 1)
+            last_completed_period - next_period_to_vest + 1
         };
-        vest_transfer(vesting_record, signer_cap, beneficiary, vesting_fraction);
 
+        let total_fraction = fixed_point32::multiply_u64_return_fixpoint32(periods_need, final_fraction);
+        // We don't need to check vesting_record.left_amount > 0 because vest_transfer will handle that.
+        vest_transfer(vesting_record, signer_cap, beneficiary, total_fraction);
+        next_period_to_vest = next_period_to_vest + periods_need;
         emit_event(&mut vesting_contract.vest_events,
             VestEvent {
                 admin: vesting_contract.admin,
-                shareholder_address: shareholder_address,
+                shareholder_address,
                 vesting_contract_address: contract_address,
                 period_vested: next_period_to_vest,
             },
         );
-        next_period_to_vest = next_period_to_vest + 1;
     };
 
     //update last_vested_period for the shareholder
@@ -1447,8 +1632,13 @@ Unlock any vested portion of the grant.
     let vesting_signer = account::create_signer_with_capability(signer_cap);
 
     //amount to be transfer is minimum of what is left and vesting fraction due of init_amount
-    let amount = min(vesting_record.left_amount,
-        fixed_point32::multiply_u64(vesting_record.init_amount, vesting_fraction));
+    let amount =
+        min(
+            vesting_record.left_amount,
+            fixed_point32::multiply_u64(
+                vesting_record.init_amount, vesting_fraction
+            )
+        );
     //update left_amount for the shareholder
     vesting_record.left_amount = vesting_record.left_amount - amount;
     coin::transfer<SupraCoin>(&vesting_signer, beneficiary, amount);
@@ -1483,38 +1673,43 @@ Example usage: If admin find shareholder suspicious, admin can remove it.
     let vesting_contract = borrow_global_mut<VestingContract>(contract_address);
     verify_admin(admin, vesting_contract);
     let vesting_signer = get_vesting_account_signer_internal(vesting_contract);
-    let shareholder_amount = simple_map::borrow(&vesting_contract.shareholders, &shareholder_address)
-        .left_amount;
-    coin::transfer<SupraCoin>(&vesting_signer, vesting_contract.withdrawal_address,
-        shareholder_amount);
-    emit_event(&mut vesting_contract.admin_withdraw_events,
+    let shareholder_amount =
+        simple_map::borrow(&vesting_contract.shareholders, &shareholder_address).left_amount;
+    coin::transfer<SupraCoin>(
+        &vesting_signer, vesting_contract.withdrawal_address, shareholder_amount
+    );
+    emit_event(
+        &mut vesting_contract.admin_withdraw_events,
         AdminWithdrawEvent {
             admin: vesting_contract.admin,
             vesting_contract_address: contract_address,
-            amount: shareholder_amount,
-        },
+            amount: shareholder_amount
+        }
     );
 
     // remove `shareholder_address`` from `vesting_contract.shareholders`
     let shareholders = &mut vesting_contract.shareholders;
-    let (_, shareholders_vesting) = simple_map::remove(shareholders, &shareholder_address);
+    let (_, shareholders_vesting) =
+        simple_map::remove(shareholders, &shareholder_address);
 
     // remove `shareholder_address` from `vesting_contract.beneficiaries`
     let beneficiary = option::none();
     let shareholder_beneficiaries = &mut vesting_contract.beneficiaries;
     // Not all shareholders have their beneficiaries, so before removing them, we need to check if the beneficiary exists
     if (simple_map::contains_key(shareholder_beneficiaries, &shareholder_address)) {
-        let (_, shareholder_baneficiary) = simple_map::remove(shareholder_beneficiaries, &shareholder_address);
+        let (_, shareholder_baneficiary) =
+            simple_map::remove(shareholder_beneficiaries, &shareholder_address);
         beneficiary = option::some(shareholder_baneficiary);
     };
 
     // Emit ShareHolderRemovedEvent
-    emit_event(&mut vesting_contract.shareholder_removed_events,
+    emit_event(
+        &mut vesting_contract.shareholder_removed_events,
         ShareHolderRemovedEvent {
             shareholder: shareholder_address,
             beneficiary,
-            amount: shareholders_vesting.left_amount,
-        },
+            amount: shareholders_vesting.left_amount
+        }
     );
 }
 
@@ -1539,7 +1734,9 @@ Terminate the vesting contract and send all funds back to the withdrawal address Implementation -
public entry fun terminate_vesting_contract(admin: &signer, contract_address: address) acquires VestingContract {
+
public entry fun terminate_vesting_contract(
+    admin: &signer, contract_address: address
+) acquires VestingContract {
     assert_active_vesting_contract(contract_address);
 
     vest(contract_address);
@@ -1549,12 +1746,16 @@ Terminate the vesting contract and send all funds back to the withdrawal address
 
     // Distribute remaining coins to withdrawal address of vesting contract.
     let shareholders_address = simple_map::keys(&vesting_contract.shareholders);
-    vector::for_each_ref(&shareholders_address,
+    vector::for_each_ref(
+        &shareholders_address,
         |shareholder| {
-            let shareholder_amount = simple_map::borrow_mut(&mut vesting_contract.shareholders,
-                shareholder);
+            let shareholder_amount =
+                simple_map::borrow_mut(
+                    &mut vesting_contract.shareholders, shareholder
+                );
             shareholder_amount.left_amount = 0;
-        });
+        }
+    );
     set_terminate_vesting_contract(contract_address);
 }
 
@@ -1580,24 +1781,30 @@ has already been terminated. Implementation -
public entry fun admin_withdraw(admin: &signer, contract_address: address) acquires VestingContract {
+
public entry fun admin_withdraw(
+    admin: &signer, contract_address: address
+) acquires VestingContract {
     let vesting_contract = borrow_global<VestingContract>(contract_address);
-    assert!(vesting_contract.state == VESTING_POOL_TERMINATED,
-        error::invalid_state(EVESTING_CONTRACT_STILL_ACTIVE));
+    assert!(
+        vesting_contract.state == VESTING_POOL_TERMINATED,
+        error::invalid_state(EVESTING_CONTRACT_STILL_ACTIVE)
+    );
 
     let vesting_contract = borrow_global_mut<VestingContract>(contract_address);
     verify_admin(admin, vesting_contract);
     let total_balance = coin::balance<SupraCoin>(contract_address);
     let vesting_signer = get_vesting_account_signer_internal(vesting_contract);
-    coin::transfer<SupraCoin>(&vesting_signer, vesting_contract.withdrawal_address,
-        total_balance);
+    coin::transfer<SupraCoin>(
+        &vesting_signer, vesting_contract.withdrawal_address, total_balance
+    );
 
-    emit_event(&mut vesting_contract.admin_withdraw_events,
+    emit_event(
+        &mut vesting_contract.admin_withdraw_events,
         AdminWithdrawEvent {
             admin: vesting_contract.admin,
             vesting_contract_address: contract_address,
-            amount: total_balance,
-        },
+            amount: total_balance
+        }
     );
 }
 
@@ -1625,7 +1832,7 @@ has already been terminated. admin: &signer, contract_address: address, shareholder: address, - new_beneficiary: address, + new_beneficiary: address ) acquires VestingContract { // Verify that the beneficiary account is set up to receive SUPRA. This is a requirement so distribute() wouldn't // fail and block all other accounts from receiving SUPRA if one beneficiary is not registered. @@ -1638,14 +1845,15 @@ has already been terminated. let beneficiaries = &mut vesting_contract.beneficiaries; simple_map::upsert(beneficiaries, shareholder, new_beneficiary); - emit_event(&mut vesting_contract.set_beneficiary_events, + emit_event( + &mut vesting_contract.set_beneficiary_events, SetBeneficiaryEvent { admin: vesting_contract.admin, vesting_contract_address: contract_address, shareholder, old_beneficiary, - new_beneficiary, - }, + new_beneficiary + } ); }
@@ -1672,13 +1880,20 @@ account.
public entry fun reset_beneficiary(
-    account: &signer, contract_address: address, shareholder: address,
+    account: &signer,
+    contract_address: address,
+    shareholder: address
 ) acquires VestingAccountManagement, VestingContract {
     let vesting_contract = borrow_global_mut<VestingContract>(contract_address);
     let addr = signer::address_of(account);
-    assert!(addr == vesting_contract.admin || addr == get_role_holder(contract_address,
-            utf8(ROLE_BENEFICIARY_RESETTER)),
-        error::permission_denied(EPERMISSION_DENIED),);
+    assert!(
+        addr == vesting_contract.admin
+            || addr
+                == get_role_holder(
+                    contract_address, utf8(ROLE_BENEFICIARY_RESETTER)
+                ),
+        error::permission_denied(EPERMISSION_DENIED)
+    );
 
     let beneficiaries = &mut vesting_contract.beneficiaries;
     if (simple_map::contains_key(beneficiaries, &shareholder)) {
@@ -1710,17 +1925,22 @@ account.
     admin: &signer,
     contract_address: address,
     role: String,
-    role_holder: address,
+    role_holder: address
 ) acquires VestingAccountManagement, VestingContract {
     let vesting_contract = borrow_global_mut<VestingContract>(contract_address);
     verify_admin(admin, vesting_contract);
 
     if (!exists<VestingAccountManagement>(contract_address)) {
         let contract_signer = &get_vesting_account_signer_internal(vesting_contract);
-        move_to(contract_signer,
-            VestingAccountManagement { roles: simple_map::create<String, address>(), })
+        move_to(
+            contract_signer,
+            VestingAccountManagement {
+                roles: simple_map::create<String, address>()
+            }
+        )
     };
-    let roles = &mut borrow_global_mut<VestingAccountManagement>(contract_address).roles;
+    let roles =
+        &mut borrow_global_mut<VestingAccountManagement>(contract_address).roles;
     simple_map::upsert(roles, role, role_holder);
 }
 
@@ -1745,10 +1965,16 @@ account.
public entry fun set_beneficiary_resetter(
-    admin: &signer, contract_address: address, beneficiary_resetter: address,
+    admin: &signer,
+    contract_address: address,
+    beneficiary_resetter: address
 ) acquires VestingAccountManagement, VestingContract {
-    set_management_role(admin, contract_address, utf8(ROLE_BENEFICIARY_RESETTER),
-        beneficiary_resetter);
+    set_management_role(
+        admin,
+        contract_address,
+        utf8(ROLE_BENEFICIARY_RESETTER),
+        beneficiary_resetter
+    );
 }
 
@@ -1771,11 +1997,17 @@ account. Implementation -
public fun get_role_holder(contract_address: address, role: String): address acquires VestingAccountManagement {
-    assert!(exists<VestingAccountManagement>(contract_address),
-        error::not_found(EVESTING_ACCOUNT_HAS_NO_ROLES));
+
public fun get_role_holder(
+    contract_address: address, role: String
+): address acquires VestingAccountManagement {
+    assert!(
+        exists<VestingAccountManagement>(contract_address),
+        error::not_found(EVESTING_ACCOUNT_HAS_NO_ROLES)
+    );
     let roles = &borrow_global<VestingAccountManagement>(contract_address).roles;
-    assert!(simple_map::contains_key(roles, &role), error::not_found(EROLE_NOT_FOUND));
+    assert!(
+        simple_map::contains_key(roles, &role), error::not_found(EROLE_NOT_FOUND)
+    );
     *simple_map::borrow(roles, &role)
 }
 
@@ -1800,7 +2032,9 @@ For emergency use in case the admin needs emergency control of vesting contract Implementation -
public fun get_vesting_account_signer(admin: &signer, contract_address: address): signer acquires VestingContract {
+
public fun get_vesting_account_signer(
+    admin: &signer, contract_address: address
+): signer acquires VestingContract {
     let vesting_contract = borrow_global_mut<VestingContract>(contract_address);
     verify_admin(admin, vesting_contract);
     get_vesting_account_signer_internal(vesting_contract)
@@ -1826,7 +2060,9 @@ For emergency use in case the admin needs emergency control of vesting contract
 Implementation
 
 
-
fun get_vesting_account_signer_internal(vesting_contract: &VestingContract): signer {
+
fun get_vesting_account_signer_internal(
+    vesting_contract: &VestingContract
+): signer {
     account::create_signer_with_capability(&vesting_contract.signer_cap)
 }
 
@@ -1852,8 +2088,9 @@ This address should be deterministic for the same admin and vesting contract cre Implementation -
fun create_vesting_contract_account(admin: &signer, contract_creation_seed: vector<u8>,)
-    : (signer, SignerCapability) acquires AdminStore {
+
fun create_vesting_contract_account(
+    admin: &signer, contract_creation_seed: vector<u8>
+): (signer, SignerCapability) acquires AdminStore {
     let admin_store = borrow_global_mut<AdminStore>(signer::address_of(admin));
     let seed = bcs::to_bytes(&signer::address_of(admin));
     vector::append(&mut seed, bcs::to_bytes(&admin_store.nonce));
@@ -1892,8 +2129,10 @@ This address should be deterministic for the same admin and vesting contract cre
 
 
 
fun verify_admin(admin: &signer, vesting_contract: &VestingContract) {
-    assert!(signer::address_of(admin) == vesting_contract.admin,
-        error::unauthenticated(ENOT_ADMIN));
+    assert!(
+        signer::address_of(admin) == vesting_contract.admin,
+        error::unauthenticated(ENOT_ADMIN)
+    );
 }
 
@@ -1917,8 +2156,10 @@ This address should be deterministic for the same admin and vesting contract cre
fun assert_vesting_contract_exists(contract_address: address) {
-    assert!(exists<VestingContract>(contract_address),
-        error::not_found(EVESTING_CONTRACT_NOT_FOUND));
+    assert!(
+        exists<VestingContract>(contract_address),
+        error::not_found(EVESTING_CONTRACT_NOT_FOUND)
+    );
 }
 
@@ -1941,11 +2182,17 @@ This address should be deterministic for the same admin and vesting contract cre Implementation -
fun assert_shareholder_exists(contract_address: address, shareholder_address: address) acquires VestingContract {
+
fun assert_shareholder_exists(
+    contract_address: address, shareholder_address: address
+) acquires VestingContract {
     assert_active_vesting_contract(contract_address);
-    assert!(simple_map::contains_key(&borrow_global<VestingContract>(contract_address)
-                .shareholders, &shareholder_address),
-        error::not_found(ESHAREHOLDER_NOT_EXIST));
+    assert!(
+        simple_map::contains_key(
+            &borrow_global<VestingContract>(contract_address).shareholders,
+            &shareholder_address
+        ),
+        error::not_found(ESHAREHOLDER_NOT_EXIST)
+    );
 }
 
@@ -1971,8 +2218,10 @@ This address should be deterministic for the same admin and vesting contract cre
fun assert_active_vesting_contract(contract_address: address) acquires VestingContract {
     assert_vesting_contract_exists(contract_address);
     let vesting_contract = borrow_global<VestingContract>(contract_address);
-    assert!(vesting_contract.state == VESTING_POOL_ACTIVE,
-        error::invalid_state(EVESTING_CONTRACT_NOT_ACTIVE));
+    assert!(
+        vesting_contract.state == VESTING_POOL_ACTIVE,
+        error::invalid_state(EVESTING_CONTRACT_NOT_ACTIVE)
+    );
 }
 
@@ -1998,7 +2247,9 @@ This address should be deterministic for the same admin and vesting contract cre
fun get_beneficiary(contract: &VestingContract, shareholder: address): address {
     if (simple_map::contains_key(&contract.beneficiaries, &shareholder)) {
         *simple_map::borrow(&contract.beneficiaries, &shareholder)
-    } else { shareholder }
+    } else {
+        shareholder
+    }
 }
 
@@ -2024,11 +2275,12 @@ This address should be deterministic for the same admin and vesting contract cre
fun set_terminate_vesting_contract(contract_address: address) acquires VestingContract {
     let vesting_contract = borrow_global_mut<VestingContract>(contract_address);
     vesting_contract.state = VESTING_POOL_TERMINATED;
-    emit_event(&mut vesting_contract.terminate_events,
+    emit_event(
+        &mut vesting_contract.terminate_events,
         TerminateEvent {
             admin: vesting_contract.admin,
-            vesting_contract_address: contract_address,
-        },
+            vesting_contract_address: contract_address
+        }
     );
 }