use 0x1::aptos_coin;
use 0x1::coin;
use 0x1::error;
use 0x1::signer;
use 0x1::stake;
use 0xc0ded0c0::delegation_state;
use 0xc0ded0c0::stake_pool_helpers;
Resource ManagedStakePool
The struct which holds the OwnerCapability of the StakePool and stores config parameters.
struct ManagedStakePool has key
Fields
stake_pool_owner_cap: stake::OwnerCapabilitystores the OwnerCapability of the StakePool owner.in_self_destruct: boolstores whether self-destruct has been called by the owner. The ManagedStakingPool does not accept new delegations in self-destruct mode.min_delegation_amount: u64max_commission: u64
Struct ManageCapability
Holders of ManageCapability can call permissioned functions. It is returned during initialization.
struct ManageCapability has store
Fields
managed_pool_address: address
Constants
The minimum stake that can be delegated to a managed stake pool.
public fun pay_commission_to_owner(manage_cap: &delegation_service::ManageCapability): u64
Implementation
public fun pay_commission_to_owner(
manage_cap: &ManageCapability,
): u64 {
assert_pool_exists(manage_cap.managed_pool_address);
delegation_state::pay_commission_to_owner(
manage_cap.managed_pool_address
)
}
Function initialize
Allows a StakePool owner managed_pool_owner to start a ManagedStakePool that can accept delegations from outside delegators. The maximum commission that can be charged is given by max_commission. The address of the Tortuga protocol delegator is given by protocol_delegator_address and the commission charged to the protocol delegator is given by protocol_commission.
Note: Commissions are specified in 6 decimal precision, following the value of COMMISSION_NORMALIZER in delegation_state module (i.e. commission of 1000000 = 100%).
Restrictions
To be associated with Tortuga protocol, this function should be called from validator_router module.
If the delegation amount is less than min_delegation_amount.
public fun delegate(delegator: &signer, managed_pool_address: address, amount: u64)
Implementation
public entry fun delegate(
delegator: &signer,
managed_pool_address: address,
amount: u64,
) acquires ManagedStakePool {
assert_not_self_destructing(managed_pool_address);
let delegator_address = signer::address_of(delegator);
certify_delegation(managed_pool_address, delegator_address, amount);
let coins_to_delegate = coin::withdraw<AptosCoin>(delegator, amount);
let managed_stake_pool = borrow_global<ManagedStakePool>(
managed_pool_address
);
// make sure that newly minted shares for the delegator are not subject
// to any commissions by paying outstanding commissions first
delegation_state::pay_commission_to_owner(managed_pool_address);
delegation_state::disperse_all_payouts(
managed_pool_address,
&managed_stake_pool.stake_pool_owner_cap
);
delegation_state::delegate_internal(
delegator,
coins_to_delegate,
managed_pool_address,
&managed_stake_pool.stake_pool_owner_cap
);
}
public fun change_commission_recipient(pool_owner: &signer, new_commission_recipient_address: address)
Implementation
public entry fun change_commission_recipient(
pool_owner: &signer,
new_commission_recipient_address: address,
) {
let managed_pool_address = signer::address_of(pool_owner);
assert_pool_exists(managed_pool_address);
// pay outstanding commission to the old recipient
delegation_state::pay_commission_to_owner(managed_pool_address);
delegation_state::change_commission_recipient_internal(
managed_pool_address,
new_commission_recipient_address,
);
}
Function reserve_shares_for_withdraw
delegator can call this function to withdraw num_shares from the ManagedStakePool at address managed_pool_address. This will move delegator shares from unreserved_pool to reserved_pool and move corresponding StakePool funds from 'active' to 'pending_inactive' state.. May have to call trigger_payout_dispersal when the stake unlocks (i.e., changes state from 'pending_inactive' to 'inactive').
Restrictions
Only the delegator can call this function for themselves.
Abort conditions
If the withdrawal amount will leave less than min_delegation_amount in the delegator's account. However, it allows all the funds to be atomically withdrawn.
public fun reserve_shares_for_withdraw(delegator: &signer, managed_pool_address: address, num_shares: u64)
Implementation
public entry fun reserve_shares_for_withdraw(
delegator: &signer,
managed_pool_address: address,
num_shares: u64,
) acquires ManagedStakePool {
assert_pool_exists(managed_pool_address);
let delegator_address = signer::address_of(delegator);
// Check for min violation
ensure_minimum_delegation_remaining(
managed_pool_address,
delegator_address,
num_shares
);
let managed_stake_pool = borrow_global<ManagedStakePool>(
managed_pool_address
);
// make sure there is no outstanding commission in either pool before
// transferring
delegation_state::pay_commission_to_owner(managed_pool_address);
delegation_state::disperse_all_payouts(
managed_pool_address,
&managed_stake_pool.stake_pool_owner_cap
);
delegation_state::reserve_shares_for_withdraw_internal(
delegator_address,
num_shares,
managed_pool_address,
&managed_stake_pool.stake_pool_owner_cap
);
}
Function trigger_payout_dispersal
Disperses all APT if there is inactive stake in the StakePool. Can be called permissionlessly.
public fun trigger_payout_dispersal(managed_pool_address: address)
Implementation
public entry fun trigger_payout_dispersal(
managed_pool_address: address
) acquires ManagedStakePool {
assert_pool_exists(managed_pool_address);
let stake_pool_address = delegation_state::get_stake_pool_address(
managed_pool_address
);
// nothing to disperse
if (
stake_pool_helpers::get_stake_pool_total_withdrawable_amount(
stake_pool_address
) == 0
) {
return
};
// first pay commission to the owner
delegation_state::pay_commission_to_owner(managed_pool_address);
let managed_stake_pool = borrow_global<ManagedStakePool>(
managed_pool_address
);
delegation_state::disperse_all_payouts(
managed_pool_address,
&managed_stake_pool.stake_pool_owner_cap
);
}
Function remove_non_owner_delegator
Reserve all shares for withdrawal for delegator_address. Can be called by anyone but only when pool is in self-destruct state. This ensures the owner can remove all delegators and retrieve their owner_capability.
fun assert_pool_exists(managed_pool_address: address)
Implementation
fun assert_pool_exists(managed_pool_address: address) {
assert!(
exists<ManagedStakePool>(managed_pool_address),
error::invalid_argument(EPOOL_DOES_NOT_EXIST)
);
}
Function certify_delegation
Certifies that a delegation with amount from delegator_address can be made. Aborts if criteria are not met. The protocol_delegator and the pool_owner, and existing delegators are not subject to these conditions.