@0x/contracts-staking
: Add some computeRewardBalanceOfOperator()
tests.
This commit is contained in:
parent
0270777cfc
commit
d064543108
@ -68,6 +68,7 @@ contract MixinStakingPoolRewards is
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Computes the reward balance in ETH of the operator of a pool.
|
/// @dev Computes the reward balance in ETH of the operator of a pool.
|
||||||
|
/// This does not include the balance in the ETH vault.
|
||||||
/// @param poolId Unique id of pool.
|
/// @param poolId Unique id of pool.
|
||||||
/// @return totalReward Balance in ETH.
|
/// @return totalReward Balance in ETH.
|
||||||
function computeRewardBalanceOfOperator(bytes32 poolId)
|
function computeRewardBalanceOfOperator(bytes32 poolId)
|
||||||
@ -75,6 +76,9 @@ contract MixinStakingPoolRewards is
|
|||||||
view
|
view
|
||||||
returns (uint256 reward)
|
returns (uint256 reward)
|
||||||
{
|
{
|
||||||
|
// Because operator rewards are immediately sent to the ETH vault
|
||||||
|
// on finalization, the only factor in this function are unfinalized
|
||||||
|
// rewards.
|
||||||
IStructs.Pool memory pool = _poolById[poolId];
|
IStructs.Pool memory pool = _poolById[poolId];
|
||||||
// Get any unfinalized rewards.
|
// Get any unfinalized rewards.
|
||||||
(uint256 unfinalizedTotalRewards, uint256 unfinalizedMembersStake) =
|
(uint256 unfinalizedTotalRewards, uint256 unfinalizedMembersStake) =
|
||||||
@ -88,6 +92,7 @@ contract MixinStakingPoolRewards is
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Computes the reward balance in ETH of a specific member of a pool.
|
/// @dev Computes the reward balance in ETH of a specific member of a pool.
|
||||||
|
/// This does not include the balance in the ETH vault.
|
||||||
/// @param poolId Unique id of pool.
|
/// @param poolId Unique id of pool.
|
||||||
/// @param member The member of the pool.
|
/// @param member The member of the pool.
|
||||||
/// @return totalReward Balance in ETH.
|
/// @return totalReward Balance in ETH.
|
||||||
|
@ -75,6 +75,7 @@ contract TestDelegatorRewards is
|
|||||||
/// @dev Set unfinalized rewards for a pool in the current epoch.
|
/// @dev Set unfinalized rewards for a pool in the current epoch.
|
||||||
function setUnfinalizedPoolReward(
|
function setUnfinalizedPoolReward(
|
||||||
bytes32 poolId,
|
bytes32 poolId,
|
||||||
|
address payable operatorAddress,
|
||||||
uint256 operatorReward,
|
uint256 operatorReward,
|
||||||
uint256 membersReward,
|
uint256 membersReward,
|
||||||
uint256 membersStake
|
uint256 membersStake
|
||||||
@ -87,7 +88,32 @@ contract TestDelegatorRewards is
|
|||||||
membersReward: membersReward,
|
membersReward: membersReward,
|
||||||
membersStake: membersStake
|
membersStake: membersStake
|
||||||
});
|
});
|
||||||
|
// Lazily initialize this pool.
|
||||||
|
_poolById[poolId].operator = operatorAddress;
|
||||||
_setOperatorShare(poolId, operatorReward, membersReward);
|
_setOperatorShare(poolId, operatorReward, membersReward);
|
||||||
|
_initGenesisCumulativeRewards(poolId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Expose/wrap `_recordStakingPoolRewards`.
|
||||||
|
function recordStakingPoolRewards(
|
||||||
|
bytes32 poolId,
|
||||||
|
address payable operatorAddress,
|
||||||
|
uint256 operatorReward,
|
||||||
|
uint256 membersReward,
|
||||||
|
uint256 membersStake
|
||||||
|
)
|
||||||
|
external
|
||||||
|
{
|
||||||
|
// Lazily initialize this pool.
|
||||||
|
_poolById[poolId].operator = operatorAddress;
|
||||||
|
_setOperatorShare(poolId, operatorReward, membersReward);
|
||||||
|
_initGenesisCumulativeRewards(poolId);
|
||||||
|
|
||||||
|
_recordStakingPoolRewards(
|
||||||
|
poolId,
|
||||||
|
operatorReward + membersReward,
|
||||||
|
membersStake
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Advance the epoch.
|
/// @dev Advance the epoch.
|
||||||
@ -207,23 +233,6 @@ contract TestDelegatorRewards is
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Expose `_recordStakingPoolRewards`.
|
|
||||||
function recordStakingPoolRewards(
|
|
||||||
bytes32 poolId,
|
|
||||||
uint256 operatorReward,
|
|
||||||
uint256 membersReward,
|
|
||||||
uint256 membersStake
|
|
||||||
)
|
|
||||||
external
|
|
||||||
{
|
|
||||||
_setOperatorShare(poolId, operatorReward, membersReward);
|
|
||||||
_recordStakingPoolRewards(
|
|
||||||
poolId,
|
|
||||||
operatorReward + membersReward,
|
|
||||||
membersStake
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @dev Overridden to realize `unfinalizedPoolRewardsByEpoch` in
|
/// @dev Overridden to realize `unfinalizedPoolRewardsByEpoch` in
|
||||||
/// the current epoch and emit a event,
|
/// the current epoch and emit a event,
|
||||||
function _finalizePool(bytes32 poolId)
|
function _finalizePool(bytes32 poolId)
|
||||||
|
@ -3,7 +3,9 @@ import {
|
|||||||
constants,
|
constants,
|
||||||
expect,
|
expect,
|
||||||
filterLogsToArguments,
|
filterLogsToArguments,
|
||||||
|
hexHash,
|
||||||
hexRandom,
|
hexRandom,
|
||||||
|
hexSlice,
|
||||||
Numberish,
|
Numberish,
|
||||||
} from '@0x/contracts-test-utils';
|
} from '@0x/contracts-test-utils';
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
@ -35,23 +37,28 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
interface RewardPoolMembersOpts {
|
interface RewardPoolOpts {
|
||||||
poolId: string;
|
poolId: string;
|
||||||
|
operator: string;
|
||||||
membersReward: Numberish;
|
membersReward: Numberish;
|
||||||
operatorReward: Numberish;
|
operatorReward: Numberish;
|
||||||
membersStake: Numberish;
|
membersStake: Numberish;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function rewardPoolMembersAsync(opts?: Partial<RewardPoolMembersOpts>): Promise<RewardPoolMembersOpts> {
|
async function rewardPoolAsync(opts?: Partial<RewardPoolOpts>): Promise<RewardPoolOpts> {
|
||||||
const _opts = {
|
const _opts = {
|
||||||
poolId: hexRandom(),
|
poolId: hexRandom(),
|
||||||
|
operator: constants.NULL_ADDRESS,
|
||||||
membersReward: getRandomInteger(1, toBaseUnitAmount(100)),
|
membersReward: getRandomInteger(1, toBaseUnitAmount(100)),
|
||||||
operatorReward: getRandomInteger(1, toBaseUnitAmount(100)),
|
operatorReward: getRandomInteger(1, toBaseUnitAmount(100)),
|
||||||
membersStake: getRandomInteger(1, toBaseUnitAmount(10)),
|
membersStake: getRandomInteger(1, toBaseUnitAmount(10)),
|
||||||
...opts,
|
...opts,
|
||||||
};
|
};
|
||||||
|
// Generate a deterministic operator address based on the poolId.
|
||||||
|
_opts.operator = poolIdToOperator(_opts.poolId);
|
||||||
await testContract.recordStakingPoolRewards.awaitTransactionSuccessAsync(
|
await testContract.recordStakingPoolRewards.awaitTransactionSuccessAsync(
|
||||||
_opts.poolId,
|
_opts.poolId,
|
||||||
|
_opts.operator,
|
||||||
new BigNumber(_opts.operatorReward),
|
new BigNumber(_opts.operatorReward),
|
||||||
new BigNumber(_opts.membersReward),
|
new BigNumber(_opts.membersReward),
|
||||||
new BigNumber(_opts.membersStake),
|
new BigNumber(_opts.membersStake),
|
||||||
@ -64,20 +71,24 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
return _opts;
|
return _opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SetUnfinalizedMembersRewardsOpts extends RewardPoolMembersOpts {}
|
interface SetUnfinalizedMembersRewardsOpts extends RewardPoolOpts {}
|
||||||
|
|
||||||
async function setUnfinalizedPoolRewardAsync(
|
async function setUnfinalizedPoolRewardAsync(
|
||||||
opts?: Partial<SetUnfinalizedMembersRewardsOpts>,
|
opts?: Partial<SetUnfinalizedMembersRewardsOpts>,
|
||||||
): Promise<SetUnfinalizedMembersRewardsOpts> {
|
): Promise<SetUnfinalizedMembersRewardsOpts> {
|
||||||
const _opts = {
|
const _opts = {
|
||||||
poolId: hexRandom(),
|
poolId: hexRandom(),
|
||||||
|
operator: constants.NULL_ADDRESS,
|
||||||
membersReward: getRandomInteger(1, toBaseUnitAmount(100)),
|
membersReward: getRandomInteger(1, toBaseUnitAmount(100)),
|
||||||
operatorReward: getRandomInteger(1, toBaseUnitAmount(100)),
|
operatorReward: getRandomInteger(1, toBaseUnitAmount(100)),
|
||||||
membersStake: getRandomInteger(1, toBaseUnitAmount(10)),
|
membersStake: getRandomInteger(1, toBaseUnitAmount(10)),
|
||||||
...opts,
|
...opts,
|
||||||
};
|
};
|
||||||
|
// Generate a deterministic operator address based on the poolId.
|
||||||
|
_opts.operator = poolIdToOperator(_opts.poolId);
|
||||||
await testContract.setUnfinalizedPoolReward.awaitTransactionSuccessAsync(
|
await testContract.setUnfinalizedPoolReward.awaitTransactionSuccessAsync(
|
||||||
_opts.poolId,
|
_opts.poolId,
|
||||||
|
_opts.operator,
|
||||||
new BigNumber(_opts.operatorReward),
|
new BigNumber(_opts.operatorReward),
|
||||||
new BigNumber(_opts.membersReward),
|
new BigNumber(_opts.membersReward),
|
||||||
new BigNumber(_opts.membersStake),
|
new BigNumber(_opts.membersStake),
|
||||||
@ -90,6 +101,11 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
return _opts;
|
return _opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generates a deterministic operator address given a pool ID.
|
||||||
|
function poolIdToOperator(poolId: string): string {
|
||||||
|
return hexSlice(hexHash(poolId), -20);
|
||||||
|
}
|
||||||
|
|
||||||
// Converts pre-split rewards to the amounts the contracts will calculate
|
// Converts pre-split rewards to the amounts the contracts will calculate
|
||||||
// after suffering precision loss from the low-precision `operatorShare`.
|
// after suffering precision loss from the low-precision `operatorShare`.
|
||||||
function toActualRewards(operatorReward: Numberish, membersReward: Numberish): [BigNumber, BigNumber] {
|
function toActualRewards(operatorReward: Numberish, membersReward: Numberish): [BigNumber, BigNumber] {
|
||||||
@ -197,6 +213,10 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
return testContract.computeRewardBalanceOfDelegator.callAsync(poolId, delegator);
|
return testContract.computeRewardBalanceOfDelegator.callAsync(poolId, delegator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getOperatorRewardBalanceAsync(poolId: string): Promise<BigNumber> {
|
||||||
|
return testContract.computeRewardBalanceOfOperator.callAsync(poolId);
|
||||||
|
}
|
||||||
|
|
||||||
async function touchStakeAsync(poolId: string, delegator: string): Promise<ResultWithDeposits<{}>> {
|
async function touchStakeAsync(poolId: string, delegator: string): Promise<ResultWithDeposits<{}>> {
|
||||||
return undelegateStakeAsync(poolId, delegator, 0);
|
return undelegateStakeAsync(poolId, delegator, 0);
|
||||||
}
|
}
|
||||||
@ -225,9 +245,65 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
.integerValue(BigNumber.ROUND_DOWN);
|
.integerValue(BigNumber.ROUND_DOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
describe('computeRewardBalanceOfOperator()', () => {
|
||||||
|
it('nothing in epoch 0', async () => {
|
||||||
|
const { poolId } = await rewardPoolAsync();
|
||||||
|
const operatorReward = await getOperatorRewardBalanceAsync(poolId);
|
||||||
|
expect(operatorReward).to.bignumber.eq(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('nothing in epoch 1', async () => {
|
||||||
|
await advanceEpochAsync();
|
||||||
|
const { poolId } = await rewardPoolAsync();
|
||||||
|
const operatorReward = await getOperatorRewardBalanceAsync(poolId);
|
||||||
|
expect(operatorReward).to.bignumber.eq(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('nothing one epoch after rewards', async () => {
|
||||||
|
const { poolId } = await rewardPoolAsync();
|
||||||
|
await advanceEpochAsync();
|
||||||
|
const operatorReward = await getOperatorRewardBalanceAsync(poolId);
|
||||||
|
expect(operatorReward).to.bignumber.eq(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with unfinalized rewards', () => {
|
||||||
|
it('something with unfinalized rewards', async () => {
|
||||||
|
const { poolId, operatorReward: expectedOperatorReward } = await setUnfinalizedPoolRewardAsync();
|
||||||
|
const operatorReward = await getOperatorRewardBalanceAsync(poolId);
|
||||||
|
assertRoughlyEquals(operatorReward, expectedOperatorReward);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('nothing for operator with 0% share', async () => {
|
||||||
|
// We define operator shares implicitly, so we set the operator
|
||||||
|
// reward to 0, which kind of makes this silly.
|
||||||
|
const { poolId } = await setUnfinalizedPoolRewardAsync({ operatorReward: 0 });
|
||||||
|
const operatorReward = await getOperatorRewardBalanceAsync(poolId);
|
||||||
|
expect(operatorReward).to.bignumber.eq(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('everything for operator with 100% share', async () => {
|
||||||
|
// We define operator shares implicitly, so we set the members
|
||||||
|
// reward to 0.
|
||||||
|
const { poolId, operatorReward: expectedOperatorReward } = await setUnfinalizedPoolRewardAsync({
|
||||||
|
membersReward: 0,
|
||||||
|
});
|
||||||
|
const operatorReward = await getOperatorRewardBalanceAsync(poolId);
|
||||||
|
assertRoughlyEquals(operatorReward, expectedOperatorReward);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('nothing once rewards are finalized', async () => {
|
||||||
|
const { poolId } = await setUnfinalizedPoolRewardAsync();
|
||||||
|
// Delegate some stake to trigger finalization.
|
||||||
|
await delegateStakeAsync(poolId);
|
||||||
|
const operatorReward = await getOperatorRewardBalanceAsync(poolId);
|
||||||
|
expect(operatorReward).to.bignumber.eq(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('computeRewardBalanceOfDelegator()', () => {
|
describe('computeRewardBalanceOfDelegator()', () => {
|
||||||
it('nothing in epoch 0 for delegator with no stake', async () => {
|
it('nothing in epoch 0 for delegator with no stake', async () => {
|
||||||
const { poolId } = await rewardPoolMembersAsync();
|
const { poolId } = await rewardPoolAsync();
|
||||||
const delegator = randomAddress();
|
const delegator = randomAddress();
|
||||||
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
||||||
expect(delegatorReward).to.bignumber.eq(0);
|
expect(delegatorReward).to.bignumber.eq(0);
|
||||||
@ -235,14 +311,14 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
|
|
||||||
it('nothing in epoch 1 for delegator with no stake', async () => {
|
it('nothing in epoch 1 for delegator with no stake', async () => {
|
||||||
await advanceEpochAsync(); // epoch 1
|
await advanceEpochAsync(); // epoch 1
|
||||||
const { poolId } = await rewardPoolMembersAsync();
|
const { poolId } = await rewardPoolAsync();
|
||||||
const delegator = randomAddress();
|
const delegator = randomAddress();
|
||||||
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
||||||
expect(delegatorReward).to.bignumber.eq(0);
|
expect(delegatorReward).to.bignumber.eq(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('nothing in epoch 0 for delegator staked in epoch 0', async () => {
|
it('nothing in epoch 0 for delegator staked in epoch 0', async () => {
|
||||||
const { poolId } = await rewardPoolMembersAsync();
|
const { poolId } = await rewardPoolAsync();
|
||||||
// Assign active stake to pool in epoch 0, which is usuaslly not
|
// Assign active stake to pool in epoch 0, which is usuaslly not
|
||||||
// possible due to delegating delays.
|
// possible due to delegating delays.
|
||||||
const { delegator } = await delegateStakeNowAsync(poolId);
|
const { delegator } = await delegateStakeNowAsync(poolId);
|
||||||
@ -252,7 +328,7 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
|
|
||||||
it('nothing in epoch 1 for delegator delegating in epoch 1', async () => {
|
it('nothing in epoch 1 for delegator delegating in epoch 1', async () => {
|
||||||
await advanceEpochAsync(); // epoch 1
|
await advanceEpochAsync(); // epoch 1
|
||||||
const { poolId } = await rewardPoolMembersAsync();
|
const { poolId } = await rewardPoolAsync();
|
||||||
const { delegator } = await delegateStakeAsync(poolId);
|
const { delegator } = await delegateStakeAsync(poolId);
|
||||||
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
||||||
expect(delegatorReward).to.bignumber.eq(0);
|
expect(delegatorReward).to.bignumber.eq(0);
|
||||||
@ -263,7 +339,7 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
const { delegator, stake } = await delegateStakeAsync(poolId);
|
const { delegator, stake } = await delegateStakeAsync(poolId);
|
||||||
await advanceEpochAsync(); // epoch 1 (stake now active)
|
await advanceEpochAsync(); // epoch 1 (stake now active)
|
||||||
// rewards paid for stake in epoch 0.
|
// rewards paid for stake in epoch 0.
|
||||||
await rewardPoolMembersAsync({ poolId, membersStake: stake });
|
await rewardPoolAsync({ poolId, membersStake: stake });
|
||||||
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
||||||
expect(delegatorReward).to.bignumber.eq(0);
|
expect(delegatorReward).to.bignumber.eq(0);
|
||||||
});
|
});
|
||||||
@ -274,7 +350,7 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
await advanceEpochAsync(); // epoch 1 (stake now active)
|
await advanceEpochAsync(); // epoch 1 (stake now active)
|
||||||
await advanceEpochAsync(); // epoch 2
|
await advanceEpochAsync(); // epoch 2
|
||||||
// rewards paid for stake in epoch 1.
|
// rewards paid for stake in epoch 1.
|
||||||
const { membersReward: reward } = await rewardPoolMembersAsync({ poolId, membersStake: stake });
|
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: stake });
|
||||||
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
||||||
expect(delegatorReward).to.bignumber.eq(reward);
|
expect(delegatorReward).to.bignumber.eq(reward);
|
||||||
});
|
});
|
||||||
@ -284,9 +360,9 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
const { delegator, stake } = await delegateStakeAsync(poolId);
|
const { delegator, stake } = await delegateStakeAsync(poolId);
|
||||||
await advanceEpochAsync(); // epoch 1 (stake now active)
|
await advanceEpochAsync(); // epoch 1 (stake now active)
|
||||||
await advanceEpochAsync(); // epoch 2
|
await advanceEpochAsync(); // epoch 2
|
||||||
const { membersReward: reward1 } = await rewardPoolMembersAsync({ poolId, membersStake: stake });
|
const { membersReward: reward1 } = await rewardPoolAsync({ poolId, membersStake: stake });
|
||||||
await advanceEpochAsync(); // epoch 3
|
await advanceEpochAsync(); // epoch 3
|
||||||
const { membersReward: reward2 } = await rewardPoolMembersAsync({ poolId, membersStake: stake });
|
const { membersReward: reward2 } = await rewardPoolAsync({ poolId, membersStake: stake });
|
||||||
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
||||||
assertRoughlyEquals(delegatorReward, BigNumber.sum(reward1, reward2));
|
assertRoughlyEquals(delegatorReward, BigNumber.sum(reward1, reward2));
|
||||||
});
|
});
|
||||||
@ -297,7 +373,7 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
await advanceEpochAsync(); // epoch 1 (stake now active)
|
await advanceEpochAsync(); // epoch 1 (stake now active)
|
||||||
await advanceEpochAsync(); // epoch 2
|
await advanceEpochAsync(); // epoch 2
|
||||||
// rewards paid for stake in epoch 1.
|
// rewards paid for stake in epoch 1.
|
||||||
const { membersReward: reward, membersStake: rewardStake } = await rewardPoolMembersAsync({
|
const { membersReward: reward, membersStake: rewardStake } = await rewardPoolAsync({
|
||||||
poolId,
|
poolId,
|
||||||
membersStake: new BigNumber(delegatorStake).times(2),
|
membersStake: new BigNumber(delegatorStake).times(2),
|
||||||
});
|
});
|
||||||
@ -312,7 +388,7 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
await advanceEpochAsync(); // epoch 1 (stake now active)
|
await advanceEpochAsync(); // epoch 1 (stake now active)
|
||||||
await advanceEpochAsync(); // epoch 2
|
await advanceEpochAsync(); // epoch 2
|
||||||
// rewards paid for stake in epoch 1.
|
// rewards paid for stake in epoch 1.
|
||||||
const { membersReward: reward } = await rewardPoolMembersAsync({ poolId, membersStake: stake });
|
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: stake });
|
||||||
const { ethVaultDeposit: deposit } = await undelegateStakeAsync(poolId, delegator);
|
const { ethVaultDeposit: deposit } = await undelegateStakeAsync(poolId, delegator);
|
||||||
assertRoughlyEquals(deposit, reward);
|
assertRoughlyEquals(deposit, reward);
|
||||||
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
||||||
@ -325,7 +401,7 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
await advanceEpochAsync(); // epoch 1 (stake now active)
|
await advanceEpochAsync(); // epoch 1 (stake now active)
|
||||||
await advanceEpochAsync(); // epoch 2
|
await advanceEpochAsync(); // epoch 2
|
||||||
// rewards paid for stake in epoch 1.
|
// rewards paid for stake in epoch 1.
|
||||||
const { membersReward: reward } = await rewardPoolMembersAsync({ poolId, membersStake: stake });
|
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: stake });
|
||||||
const { ethVaultDeposit: deposit } = await undelegateStakeAsync(poolId, delegator);
|
const { ethVaultDeposit: deposit } = await undelegateStakeAsync(poolId, delegator);
|
||||||
assertRoughlyEquals(deposit, reward);
|
assertRoughlyEquals(deposit, reward);
|
||||||
await delegateStakeAsync(poolId, { delegator, stake });
|
await delegateStakeAsync(poolId, { delegator, stake });
|
||||||
@ -339,13 +415,13 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
await advanceEpochAsync(); // epoch 1 (stake now active)
|
await advanceEpochAsync(); // epoch 1 (stake now active)
|
||||||
await advanceEpochAsync(); // epoch 2
|
await advanceEpochAsync(); // epoch 2
|
||||||
// rewards paid for stake in epoch 1.
|
// rewards paid for stake in epoch 1.
|
||||||
await rewardPoolMembersAsync({ poolId, membersStake: stake });
|
await rewardPoolAsync({ poolId, membersStake: stake });
|
||||||
await undelegateStakeAsync(poolId, delegator);
|
await undelegateStakeAsync(poolId, delegator);
|
||||||
await delegateStakeAsync(poolId, { delegator, stake });
|
await delegateStakeAsync(poolId, { delegator, stake });
|
||||||
await advanceEpochAsync(); // epoch 3
|
await advanceEpochAsync(); // epoch 3
|
||||||
await advanceEpochAsync(); // epoch 4
|
await advanceEpochAsync(); // epoch 4
|
||||||
// rewards paid for stake in epoch 3.
|
// rewards paid for stake in epoch 3.
|
||||||
const { membersReward: reward } = await rewardPoolMembersAsync({ poolId, membersStake: stake });
|
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: stake });
|
||||||
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
||||||
expect(delegatorReward).to.bignumber.eq(reward);
|
expect(delegatorReward).to.bignumber.eq(reward);
|
||||||
});
|
});
|
||||||
@ -358,7 +434,7 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
// Pay rewards for epoch 0.
|
// Pay rewards for epoch 0.
|
||||||
await advanceEpochAsync(); // epoch 2
|
await advanceEpochAsync(); // epoch 2
|
||||||
// Pay rewards for epoch 1.
|
// Pay rewards for epoch 1.
|
||||||
const { membersReward: reward } = await rewardPoolMembersAsync({ poolId, membersStake: stake });
|
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: stake });
|
||||||
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
||||||
expect(delegatorReward).to.bignumber.eq(reward);
|
expect(delegatorReward).to.bignumber.eq(reward);
|
||||||
});
|
});
|
||||||
@ -375,14 +451,14 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
// receives 100% of rewards.
|
// receives 100% of rewards.
|
||||||
const rewardStake = totalStake.times(2);
|
const rewardStake = totalStake.times(2);
|
||||||
// Pay rewards for epoch 1.
|
// Pay rewards for epoch 1.
|
||||||
const { membersReward: reward1 } = await rewardPoolMembersAsync({ poolId, membersStake: rewardStake });
|
const { membersReward: reward1 } = await rewardPoolAsync({ poolId, membersStake: rewardStake });
|
||||||
// add extra stake
|
// add extra stake
|
||||||
const { ethVaultDeposit: deposit } = await delegateStakeAsync(poolId, { delegator, stake: stake2 });
|
const { ethVaultDeposit: deposit } = await delegateStakeAsync(poolId, { delegator, stake: stake2 });
|
||||||
await advanceEpochAsync(); // epoch 3 (stake2 now active)
|
await advanceEpochAsync(); // epoch 3 (stake2 now active)
|
||||||
// Pay rewards for epoch 2.
|
// Pay rewards for epoch 2.
|
||||||
await advanceEpochAsync(); // epoch 4
|
await advanceEpochAsync(); // epoch 4
|
||||||
// Pay rewards for epoch 3.
|
// Pay rewards for epoch 3.
|
||||||
const { membersReward: reward2 } = await rewardPoolMembersAsync({ poolId, membersStake: rewardStake });
|
const { membersReward: reward2 } = await rewardPoolAsync({ poolId, membersStake: rewardStake });
|
||||||
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
||||||
const expectedDelegatorReward = BigNumber.sum(
|
const expectedDelegatorReward = BigNumber.sum(
|
||||||
computeDelegatorRewards(reward1, stake1, rewardStake),
|
computeDelegatorRewards(reward1, stake1, rewardStake),
|
||||||
@ -404,10 +480,10 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
// receives 100% of rewards.
|
// receives 100% of rewards.
|
||||||
const rewardStake = totalStake.times(2);
|
const rewardStake = totalStake.times(2);
|
||||||
// Pay rewards for epoch 1.
|
// Pay rewards for epoch 1.
|
||||||
const { membersReward: reward1 } = await rewardPoolMembersAsync({ poolId, membersStake: rewardStake });
|
const { membersReward: reward1 } = await rewardPoolAsync({ poolId, membersStake: rewardStake });
|
||||||
await advanceEpochAsync(); // epoch 3
|
await advanceEpochAsync(); // epoch 3
|
||||||
// Pay rewards for epoch 2.
|
// Pay rewards for epoch 2.
|
||||||
const { membersReward: reward2 } = await rewardPoolMembersAsync({ poolId, membersStake: rewardStake });
|
const { membersReward: reward2 } = await rewardPoolAsync({ poolId, membersStake: rewardStake });
|
||||||
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
||||||
const expectedDelegatorReward = BigNumber.sum(
|
const expectedDelegatorReward = BigNumber.sum(
|
||||||
computeDelegatorRewards(reward1, stake1, rewardStake),
|
computeDelegatorRewards(reward1, stake1, rewardStake),
|
||||||
@ -424,10 +500,10 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
const totalStake = BigNumber.sum(stakeA, stakeB);
|
const totalStake = BigNumber.sum(stakeA, stakeB);
|
||||||
await advanceEpochAsync(); // epoch 2 (stake B now active)
|
await advanceEpochAsync(); // epoch 2 (stake B now active)
|
||||||
// rewards paid for stake in epoch 1 (delegator A only)
|
// rewards paid for stake in epoch 1 (delegator A only)
|
||||||
const { membersReward: reward1 } = await rewardPoolMembersAsync({ poolId, membersStake: stakeA });
|
const { membersReward: reward1 } = await rewardPoolAsync({ poolId, membersStake: stakeA });
|
||||||
await advanceEpochAsync(); // epoch 3
|
await advanceEpochAsync(); // epoch 3
|
||||||
// rewards paid for stake in epoch 2 (delegator A and B)
|
// rewards paid for stake in epoch 2 (delegator A and B)
|
||||||
const { membersReward: reward2 } = await rewardPoolMembersAsync({ poolId, membersStake: totalStake });
|
const { membersReward: reward2 } = await rewardPoolAsync({ poolId, membersStake: totalStake });
|
||||||
const delegatorRewardA = await getDelegatorRewardBalanceAsync(poolId, delegatorA);
|
const delegatorRewardA = await getDelegatorRewardBalanceAsync(poolId, delegatorA);
|
||||||
const expectedDelegatorRewardA = BigNumber.sum(
|
const expectedDelegatorRewardA = BigNumber.sum(
|
||||||
computeDelegatorRewards(reward1, stakeA, stakeA),
|
computeDelegatorRewards(reward1, stakeA, stakeA),
|
||||||
@ -447,11 +523,11 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
const totalStake = BigNumber.sum(stakeA, stakeB);
|
const totalStake = BigNumber.sum(stakeA, stakeB);
|
||||||
await advanceEpochAsync(); // epoch 2 (stake B now active)
|
await advanceEpochAsync(); // epoch 2 (stake B now active)
|
||||||
// rewards paid for stake in epoch 1 (delegator A only)
|
// rewards paid for stake in epoch 1 (delegator A only)
|
||||||
const { membersReward: reward1 } = await rewardPoolMembersAsync({ poolId, membersStake: stakeA });
|
const { membersReward: reward1 } = await rewardPoolAsync({ poolId, membersStake: stakeA });
|
||||||
await advanceEpochAsync(); // epoch 3
|
await advanceEpochAsync(); // epoch 3
|
||||||
await advanceEpochAsync(); // epoch 4
|
await advanceEpochAsync(); // epoch 4
|
||||||
// rewards paid for stake in epoch 3 (delegator A and B)
|
// rewards paid for stake in epoch 3 (delegator A and B)
|
||||||
const { membersReward: reward2 } = await rewardPoolMembersAsync({ poolId, membersStake: totalStake });
|
const { membersReward: reward2 } = await rewardPoolAsync({ poolId, membersStake: totalStake });
|
||||||
const delegatorRewardA = await getDelegatorRewardBalanceAsync(poolId, delegatorA);
|
const delegatorRewardA = await getDelegatorRewardBalanceAsync(poolId, delegatorA);
|
||||||
const expectedDelegatorRewardA = BigNumber.sum(
|
const expectedDelegatorRewardA = BigNumber.sum(
|
||||||
computeDelegatorRewards(reward1, stakeA, stakeA),
|
computeDelegatorRewards(reward1, stakeA, stakeA),
|
||||||
@ -469,13 +545,13 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
await advanceEpochAsync(); // epoch 1 (stake now active)
|
await advanceEpochAsync(); // epoch 1 (stake now active)
|
||||||
await advanceEpochAsync(); // epoch 2
|
await advanceEpochAsync(); // epoch 2
|
||||||
// rewards paid for stake in epoch 1.
|
// rewards paid for stake in epoch 1.
|
||||||
const { membersReward: reward1, membersStake: rewardStake1 } = await rewardPoolMembersAsync({
|
const { membersReward: reward1, membersStake: rewardStake1 } = await rewardPoolAsync({
|
||||||
poolId,
|
poolId,
|
||||||
membersStake: new BigNumber(delegatorStake).times(2),
|
membersStake: new BigNumber(delegatorStake).times(2),
|
||||||
});
|
});
|
||||||
await advanceEpochAsync(); // epoch 3
|
await advanceEpochAsync(); // epoch 3
|
||||||
// rewards paid for stake in epoch 2
|
// rewards paid for stake in epoch 2
|
||||||
const { membersReward: reward2, membersStake: rewardStake2 } = await rewardPoolMembersAsync({
|
const { membersReward: reward2, membersStake: rewardStake2 } = await rewardPoolAsync({
|
||||||
poolId,
|
poolId,
|
||||||
membersStake: new BigNumber(delegatorStake).times(3),
|
membersStake: new BigNumber(delegatorStake).times(3),
|
||||||
});
|
});
|
||||||
@ -538,7 +614,7 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
const { delegator, stake } = await delegateStakeAsync(poolId);
|
const { delegator, stake } = await delegateStakeAsync(poolId);
|
||||||
await advanceEpochAsync(); // epoch 1
|
await advanceEpochAsync(); // epoch 1
|
||||||
await advanceEpochAsync(); // epoch 2
|
await advanceEpochAsync(); // epoch 2
|
||||||
const { membersReward: prevReward } = await rewardPoolMembersAsync({ poolId, membersStake: stake });
|
const { membersReward: prevReward } = await rewardPoolAsync({ poolId, membersStake: stake });
|
||||||
await advanceEpochAsync(); // epoch 3
|
await advanceEpochAsync(); // epoch 3
|
||||||
const { membersReward: unfinalizedReward } = await setUnfinalizedPoolRewardAsync({
|
const { membersReward: unfinalizedReward } = await setUnfinalizedPoolRewardAsync({
|
||||||
poolId,
|
poolId,
|
||||||
@ -554,7 +630,7 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
const { delegator, stake } = await delegateStakeAsync(poolId);
|
const { delegator, stake } = await delegateStakeAsync(poolId);
|
||||||
await advanceEpochAsync(); // epoch 1
|
await advanceEpochAsync(); // epoch 1
|
||||||
await advanceEpochAsync(); // epoch 2
|
await advanceEpochAsync(); // epoch 2
|
||||||
const { membersReward: prevReward } = await rewardPoolMembersAsync({ poolId, membersStake: stake });
|
const { membersReward: prevReward } = await rewardPoolAsync({ poolId, membersStake: stake });
|
||||||
await advanceEpochAsync(); // epoch 3
|
await advanceEpochAsync(); // epoch 3
|
||||||
await advanceEpochAsync(); // epoch 4
|
await advanceEpochAsync(); // epoch 4
|
||||||
const { membersReward: unfinalizedReward } = await setUnfinalizedPoolRewardAsync({
|
const { membersReward: unfinalizedReward } = await setUnfinalizedPoolRewardAsync({
|
||||||
@ -571,7 +647,7 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
const { delegator, stake } = await delegateStakeAsync(poolId);
|
const { delegator, stake } = await delegateStakeAsync(poolId);
|
||||||
await advanceEpochAsync(); // epoch 1
|
await advanceEpochAsync(); // epoch 1
|
||||||
await advanceEpochAsync(); // epoch 2
|
await advanceEpochAsync(); // epoch 2
|
||||||
const { membersReward: prevReward, membersStake: prevStake } = await rewardPoolMembersAsync({
|
const { membersReward: prevReward, membersStake: prevStake } = await rewardPoolAsync({
|
||||||
poolId,
|
poolId,
|
||||||
membersStake: new BigNumber(stake).times(2),
|
membersStake: new BigNumber(stake).times(2),
|
||||||
});
|
});
|
||||||
@ -601,7 +677,7 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
await advanceEpochAsync(); // epoch 1 (stake now active)
|
await advanceEpochAsync(); // epoch 1 (stake now active)
|
||||||
await advanceEpochAsync(); // epoch 2
|
await advanceEpochAsync(); // epoch 2
|
||||||
// rewards paid for stake in epoch 1
|
// rewards paid for stake in epoch 1
|
||||||
const { membersReward: reward } = await rewardPoolMembersAsync({ poolId, membersStake: stake });
|
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: stake });
|
||||||
const { ethVaultDeposit: deposit } = await touchStakeAsync(poolId, delegator);
|
const { ethVaultDeposit: deposit } = await touchStakeAsync(poolId, delegator);
|
||||||
const finalRewardBalance = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
const finalRewardBalance = await getDelegatorRewardBalanceAsync(poolId, delegator);
|
||||||
expect(deposit).to.bignumber.eq(reward);
|
expect(deposit).to.bignumber.eq(reward);
|
||||||
@ -621,7 +697,7 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
await advanceEpochAsync(); // epoch 1 (2 * stake now active)
|
await advanceEpochAsync(); // epoch 1 (2 * stake now active)
|
||||||
// reward for epoch 1, using 2 * stake so delegator should
|
// reward for epoch 1, using 2 * stake so delegator should
|
||||||
// only be entitled to a fraction of the rewards.
|
// only be entitled to a fraction of the rewards.
|
||||||
const { membersReward: reward } = await rewardPoolMembersAsync({ poolId, membersStake: rewardStake });
|
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: rewardStake });
|
||||||
await advanceEpochAsync(); // epoch 2
|
await advanceEpochAsync(); // epoch 2
|
||||||
// touch the stake one last time
|
// touch the stake one last time
|
||||||
stakeResults.push(await touchStakeAsync(poolId, delegator));
|
stakeResults.push(await touchStakeAsync(poolId, delegator));
|
||||||
@ -640,18 +716,18 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
const rewardStake = new BigNumber(stake).times(2);
|
const rewardStake = new BigNumber(stake).times(2);
|
||||||
await advanceEpochAsync(); // epoch 1 (full stake now active)
|
await advanceEpochAsync(); // epoch 1 (full stake now active)
|
||||||
// reward for epoch 0
|
// reward for epoch 0
|
||||||
await rewardPoolMembersAsync({ poolId, membersStake: rewardStake });
|
await rewardPoolAsync({ poolId, membersStake: rewardStake });
|
||||||
// unstake some
|
// unstake some
|
||||||
const unstake = new BigNumber(stake).dividedToIntegerBy(2);
|
const unstake = new BigNumber(stake).dividedToIntegerBy(2);
|
||||||
stakeResults.push(await undelegateStakeAsync(poolId, delegator, unstake));
|
stakeResults.push(await undelegateStakeAsync(poolId, delegator, unstake));
|
||||||
await advanceEpochAsync(); // epoch 2 (half active stake)
|
await advanceEpochAsync(); // epoch 2 (half active stake)
|
||||||
// reward for epoch 1
|
// reward for epoch 1
|
||||||
const { membersReward: reward1 } = await rewardPoolMembersAsync({ poolId, membersStake: rewardStake });
|
const { membersReward: reward1 } = await rewardPoolAsync({ poolId, membersStake: rewardStake });
|
||||||
// re-stake
|
// re-stake
|
||||||
stakeResults.push(await delegateStakeAsync(poolId, { delegator, stake: unstake }));
|
stakeResults.push(await delegateStakeAsync(poolId, { delegator, stake: unstake }));
|
||||||
await advanceEpochAsync(); // epoch 3 (full stake now active)
|
await advanceEpochAsync(); // epoch 3 (full stake now active)
|
||||||
// reward for epoch 2
|
// reward for epoch 2
|
||||||
const { membersReward: reward2 } = await rewardPoolMembersAsync({ poolId, membersStake: rewardStake });
|
const { membersReward: reward2 } = await rewardPoolAsync({ poolId, membersStake: rewardStake });
|
||||||
// touch the stake to claim rewards
|
// touch the stake to claim rewards
|
||||||
stakeResults.push(await touchStakeAsync(poolId, delegator));
|
stakeResults.push(await touchStakeAsync(poolId, delegator));
|
||||||
const allDeposits = stakeResults.map(r => r.ethVaultDeposit);
|
const allDeposits = stakeResults.map(r => r.ethVaultDeposit);
|
||||||
@ -670,7 +746,7 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
await advanceEpochAsync(); // epoch 1 (stakes now active)
|
await advanceEpochAsync(); // epoch 1 (stakes now active)
|
||||||
await advanceEpochAsync(); // epoch 2
|
await advanceEpochAsync(); // epoch 2
|
||||||
// rewards paid for stake in epoch 1
|
// rewards paid for stake in epoch 1
|
||||||
const { membersReward: reward } = await rewardPoolMembersAsync({ poolId, membersStake: totalStake });
|
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: totalStake });
|
||||||
// delegator A will finalize and collect rewards by touching stake.
|
// delegator A will finalize and collect rewards by touching stake.
|
||||||
const { ethVaultDeposit: depositA } = await touchStakeAsync(poolId, delegatorA);
|
const { ethVaultDeposit: depositA } = await touchStakeAsync(poolId, delegatorA);
|
||||||
assertRoughlyEquals(depositA, computeDelegatorRewards(reward, stakeA, totalStake));
|
assertRoughlyEquals(depositA, computeDelegatorRewards(reward, stakeA, totalStake));
|
||||||
@ -687,7 +763,7 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
await advanceEpochAsync(); // epoch 1 (stakes now active)
|
await advanceEpochAsync(); // epoch 1 (stakes now active)
|
||||||
await advanceEpochAsync(); // epoch 2
|
await advanceEpochAsync(); // epoch 2
|
||||||
// rewards paid for stake in epoch 1
|
// rewards paid for stake in epoch 1
|
||||||
const { membersReward: prevReward } = await rewardPoolMembersAsync({ poolId, membersStake: totalStake });
|
const { membersReward: prevReward } = await rewardPoolAsync({ poolId, membersStake: totalStake });
|
||||||
await advanceEpochAsync(); // epoch 3
|
await advanceEpochAsync(); // epoch 3
|
||||||
// unfinalized rewards for stake in epoch 2
|
// unfinalized rewards for stake in epoch 2
|
||||||
const { membersReward: unfinalizedReward } = await setUnfinalizedPoolRewardAsync({
|
const { membersReward: unfinalizedReward } = await setUnfinalizedPoolRewardAsync({
|
||||||
@ -711,7 +787,7 @@ blockchainTests.resets('delegator unit rewards', env => {
|
|||||||
await advanceEpochAsync(); // epoch 1 (stakes now active)
|
await advanceEpochAsync(); // epoch 1 (stakes now active)
|
||||||
await advanceEpochAsync(); // epoch 2
|
await advanceEpochAsync(); // epoch 2
|
||||||
// rewards paid for stake in epoch 1
|
// rewards paid for stake in epoch 1
|
||||||
const { membersReward: prevReward } = await rewardPoolMembersAsync({ poolId, membersStake: totalStake });
|
const { membersReward: prevReward } = await rewardPoolAsync({ poolId, membersStake: totalStake });
|
||||||
await advanceEpochAsync(); // epoch 3
|
await advanceEpochAsync(); // epoch 3
|
||||||
// unfinalized rewards for stake in epoch 2
|
// unfinalized rewards for stake in epoch 2
|
||||||
const { membersReward: unfinalizedReward } = await setUnfinalizedPoolRewardAsync({
|
const { membersReward: unfinalizedReward } = await setUnfinalizedPoolRewardAsync({
|
||||||
|
Loading…
x
Reference in New Issue
Block a user