Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minimal value assertion for Delegation pool action #145

Merged
merged 3 commits into from
Dec 21, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 63 additions & 53 deletions aptos-move/framework/supra-framework/sources/pbo_delegation_pool.move
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,11 @@ module supra_framework::pbo_delegation_pool {

const ENEW_IS_SAME_AS_OLD_DELEGATOR: u64 = 37;

/// Minimum amount of coins to be unlocked.
const EMINIMUM_UNLOCK_AMOUNT: u64 = 38;

/// Balance is not enough.
const EBALANCE_NOT_SUFFICIENT: u64 = 38;
const EBALANCE_NOT_SUFFICIENT: u64 = 39;

const MAX_U64: u64 = 18446744073709551615;

Expand Down Expand Up @@ -1539,6 +1542,8 @@ module supra_framework::pbo_delegation_pool {
) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage {
// short-circuit if 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));
// synchronize delegation and stake pools before any user operation
synchronize_delegation_pool(pool_address);

Expand Down Expand Up @@ -1836,6 +1841,8 @@ module supra_framework::pbo_delegation_pool {
) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage {
// 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));
// fail unlock of more stake than `active` on the stake pool
let (active, _, _, _) = stake::get_stake(pool_address);
assert!(
Expand Down Expand Up @@ -1884,6 +1891,8 @@ module supra_framework::pbo_delegation_pool {
) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage {
// 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));
// synchronize delegation and stake pools before any user operation
synchronize_delegation_pool(pool_address);

Expand Down Expand Up @@ -3203,7 +3212,7 @@ module supra_framework::pbo_delegation_pool {
);

// successfully delete the pending withdrawal (redeem all owned shares even worth 0 coins)
reactivate_stake(delegator, pool_address, 1);
reactivate_stake(delegator, pool_address, MIN_COINS_ON_SHARES_POOL);
assert_delegation(
delegator_address,
pool_address,
Expand Down Expand Up @@ -3243,7 +3252,7 @@ module supra_framework::pbo_delegation_pool {
1
);

reactivate_stake(delegator, pool_address, 1);
reactivate_stake(delegator, pool_address, MIN_COINS_ON_SHARES_POOL);
// redeem 1 coins >= delegator balance -> all shares are redeemed and pending withdrawal is deleted
assert_delegation(
delegator_address,
Expand All @@ -3263,8 +3272,9 @@ module supra_framework::pbo_delegation_pool {
);
}

// The test case abort because the amount of stake is less than the minimum amount of stake
#[test(supra_framework = @supra_framework, validator = @0x123)]
#[expected_failure(abort_code = 0x10008, location = Self)]
#[expected_failure(abort_code = 65574, location = Self)]
axiongsupra marked this conversation as resolved.
Show resolved Hide resolved
public entry fun test_add_stake_min_amount(
supra_framework: &signer, validator: &signer
) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage {
Expand Down Expand Up @@ -6375,27 +6385,27 @@ module supra_framework::pbo_delegation_pool {
0
);
// pending_inactive balance would be under threshold => move MIN_COINS_ON_SHARES_POOL coins
unlock(delegator1, pool_address, MIN_COINS_ON_SHARES_POOL - 1);
unlock(delegator1, pool_address, MIN_COINS_ON_SHARES_POOL);
assert_delegation(
delegator1_address,
pool_address,
4899999999,
4900000000,
0,
100000001
100000000
);

// pending_inactive balance is over threshold
reactivate_stake(delegator1, pool_address, 1);
reactivate_stake(delegator1, pool_address, MIN_COINS_ON_SHARES_POOL);
assert_delegation(
delegator1_address,
pool_address,
4900000000,
5000000000,
0,
100000000
0
);

// pending_inactive balance would be under threshold => move entire balance
reactivate_stake(delegator1, pool_address, 1);
reactivate_stake(delegator1, pool_address, MIN_COINS_ON_SHARES_POOL);
assert_delegation(
delegator1_address,
pool_address,
Expand All @@ -6419,23 +6429,23 @@ module supra_framework::pbo_delegation_pool {
);

// active balance would be under threshold => move MIN_COINS_ON_SHARES_POOL coins
reactivate_stake(delegator1, pool_address, 1);
reactivate_stake(delegator1, pool_address, MIN_COINS_ON_SHARES_POOL);
assert_delegation(
delegator1_address,
pool_address,
100000001,
100000000,
0,
4899999999
4900000000
);

// active balance is over threshold
unlock(delegator1, pool_address, 1);
unlock(delegator1, pool_address, MIN_COINS_ON_SHARES_POOL);
assert_delegation(
delegator1_address,
pool_address,
100000000,
0,
4900000000
0,
5000000000
);

// pending_inactive balance would be under threshold => move entire balance
Expand All @@ -6447,9 +6457,9 @@ module supra_framework::pbo_delegation_pool {
assert_delegation(
delegator1_address,
pool_address,
4000000001,
3900000001,
0,
999999999
1099999999
);

// active + pending_inactive balance < 2 * MIN_COINS_ON_SHARES_POOL
Expand All @@ -6461,30 +6471,30 @@ module supra_framework::pbo_delegation_pool {
0,
0
);
unlock(delegator2, pool_address, 1);
unlock(delegator2, pool_address, MIN_COINS_ON_SHARES_POOL);
assert_delegation(
delegator2_address,
pool_address,
1499999999,
1500000000,
0,
100000001
100000000
);
reactivate_stake(delegator2, pool_address, 1);
reactivate_stake(delegator2, pool_address, MIN_COINS_ON_SHARES_POOL);
assert_delegation(
delegator2_address,
pool_address,
1500000000,
1600000000,
0,
100000000
0
);

unlock(delegator2, pool_address, ONE_SUPRA);
assert_delegation(
delegator2_address,
pool_address,
1400000000,
1500000000,
0,
200000000
100000000
);
reactivate_stake(delegator2, pool_address, 2 * ONE_SUPRA);
assert_delegation(
Expand All @@ -6496,92 +6506,92 @@ module supra_framework::pbo_delegation_pool {
);

// share price becomes 1.01 on both pools
unlock(delegator1, pool_address, 1);
unlock(delegator1, pool_address, MIN_COINS_ON_SHARES_POOL);
assert_delegation(
delegator1_address,
pool_address,
4000000000,
3800000001,
0,
1000000000
1199999999
);
end_aptos_epoch();
assert_delegation(
delegator1_address,
pool_address,
4040000000,
3838000001,
0,
1010000000
1211999998
);

// pending_inactive balance is over threshold
reactivate_stake(delegator1, pool_address, 10000001);
reactivate_stake(delegator1, pool_address, MIN_COINS_ON_SHARES_POOL);
assert_delegation(
delegator1_address,
pool_address,
4049999999,
3938000000,
0,
1000000000
1111999999
);

// 1 coin < 1.01 so no shares are redeemed
reactivate_stake(delegator1, pool_address, 1);
reactivate_stake(delegator1, pool_address, MIN_COINS_ON_SHARES_POOL);
assert_delegation(
delegator1_address,
pool_address,
4049999999,
4037999999,
0,
1000000000
1012000000
);

// pending_inactive balance is over threshold
// requesting 2 coins actually redeems 1 coin from pending_inactive pool
reactivate_stake(delegator1, pool_address, 2);
reactivate_stake(delegator1, pool_address, MIN_COINS_ON_SHARES_POOL);
assert_delegation(
delegator1_address,
pool_address,
4050000000,
4137999998,
0,
999999999
912000001
);

// 1 coin < 1.01 so no shares are redeemed
reactivate_stake(delegator1, pool_address, 1);
reactivate_stake(delegator1, pool_address, MIN_COINS_ON_SHARES_POOL);
assert_delegation(
delegator1_address,
pool_address,
4050000000,
4237999997,
0,
999999999
812000002
);

// pending_inactive balance would be under threshold => move entire balance
reactivate_stake(delegator1, pool_address, 2);
reactivate_stake(delegator1, pool_address, MIN_COINS_ON_SHARES_POOL);
assert_delegation(
delegator1_address,
pool_address,
4050000001,
4337999996,
0,
999999998
712000003
);

// pending_inactive balance would be under threshold => move MIN_COINS_ON_SHARES_POOL coins
unlock(delegator1, pool_address, MIN_COINS_ON_SHARES_POOL - 1);
unlock(delegator1, pool_address, MIN_COINS_ON_SHARES_POOL);
assert_delegation(
delegator1_address,
pool_address,
3950000003,
4237999996,
0,
1099999996
812000002
);

// pending_inactive balance would be under threshold => move entire balance
reactivate_stake(delegator1, pool_address, 1);
reactivate_stake(delegator1, pool_address, MIN_COINS_ON_SHARES_POOL);
assert_delegation(
delegator1_address,
pool_address,
3950000003,
4337999995,
0,
1099999996
712000003
);
}

Expand Down