Fix tests to no longer utilize active stake

This commit is contained in:
Amir Bandeali
2019-10-05 17:29:05 -07:00
parent 2e36c7ef83
commit aa0a1bb54d
6 changed files with 156 additions and 245 deletions

View File

@@ -148,7 +148,7 @@ export class StakerActor extends BaseActor {
public async stakeWithPoolAsync(poolId: string, amount: BigNumber): Promise<void> {
await this.stakeAsync(amount);
await this.moveStakeAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolId),
amount,
);
@@ -182,10 +182,8 @@ export class StakerActor extends BaseActor {
private _getNextEpochBalances(balances: StakeBalances): StakeBalances {
const nextBalances = _.cloneDeep(balances);
for (const balance of [
nextBalances.activeStakeBalance,
nextBalances.inactiveStakeBalance,
nextBalances.delegatedStakeBalance,
nextBalances.globalActiveStakeBalance,
nextBalances.globalInactiveStakeBalance,
nextBalances.globalDelegatedStakeBalance,
...this._poolIds.map(poolId => nextBalances.delegatedStakeByPool[poolId]),
@@ -202,10 +200,6 @@ export class StakerActor extends BaseActor {
zrxBalance: await this._stakingApiWrapper.zrxTokenContract.balanceOf.callAsync(this._owner),
stakeBalance: await this._stakingApiWrapper.stakingContract.getTotalStake.callAsync(this._owner),
stakeBalanceInVault: await this._stakingApiWrapper.zrxVaultContract.balanceOf.callAsync(this._owner),
activeStakeBalance: await this._stakingApiWrapper.stakingContract.getOwnerStakeByStatus.callAsync(
this._owner,
StakeStatus.Active,
),
inactiveStakeBalance: await this._stakingApiWrapper.stakingContract.getOwnerStakeByStatus.callAsync(
this._owner,
StakeStatus.Inactive,
@@ -214,9 +208,6 @@ export class StakerActor extends BaseActor {
this._owner,
StakeStatus.Delegated,
),
globalActiveStakeBalance: await this._stakingApiWrapper.stakingContract.getGlobalStakeByStatus.callAsync(
StakeStatus.Active,
),
globalInactiveStakeBalance: await this._stakingApiWrapper.stakingContract.getGlobalStakeByStatus.callAsync(
StakeStatus.Inactive,
),
@@ -246,12 +237,6 @@ export class StakerActor extends BaseActor {
expect(balances.stakeBalanceInVault, 'stake balance, recorded in vault').to.be.bignumber.equal(
expectedBalances.stakeBalanceInVault,
);
expect(balances.activeStakeBalance.currentEpochBalance, 'active stake balance (current)').to.be.bignumber.equal(
expectedBalances.activeStakeBalance.currentEpochBalance,
);
expect(balances.activeStakeBalance.nextEpochBalance, 'active stake balance (next)').to.be.bignumber.equal(
expectedBalances.activeStakeBalance.nextEpochBalance,
);
expect(
balances.inactiveStakeBalance.currentEpochBalance,
'inactive stake balance (current)',
@@ -266,10 +251,6 @@ export class StakerActor extends BaseActor {
expect(balances.delegatedStakeBalance.nextEpochBalance, 'delegated stake balance (next)').to.be.bignumber.equal(
expectedBalances.delegatedStakeBalance.nextEpochBalance,
);
expect(
balances.globalActiveStakeBalance.currentEpochBalance,
'global active stake (current)',
).to.bignumber.equal(expectedBalances.globalActiveStakeBalance.currentEpochBalance);
expect(
balances.globalInactiveStakeBalance.currentEpochBalance,
'global inactive stake (current)',
@@ -278,9 +259,6 @@ export class StakerActor extends BaseActor {
balances.globalDelegatedStakeBalance.currentEpochBalance,
'global delegated stake (current)',
).to.bignumber.equal(expectedBalances.globalDelegatedStakeBalance.currentEpochBalance);
expect(balances.globalActiveStakeBalance.nextEpochBalance, 'global active stake (next)').to.bignumber.equal(
expectedBalances.globalActiveStakeBalance.nextEpochBalance,
);
expect(balances.globalInactiveStakeBalance.nextEpochBalance, 'global inactive stake (next)').to.bignumber.equal(
expectedBalances.globalInactiveStakeBalance.nextEpochBalance,
);
@@ -311,10 +289,7 @@ export class StakerActor extends BaseActor {
// @TODO check receipt logs and return value via eth_call
// check balances
// from
if (from.status === StakeStatus.Active) {
StakerActor._decrementNextBalance(expectedBalances.activeStakeBalance, amount);
StakerActor._decrementNextBalance(expectedBalances.globalActiveStakeBalance, amount);
} else if (from.status === StakeStatus.Inactive) {
if (from.status === StakeStatus.Inactive) {
StakerActor._decrementNextBalance(expectedBalances.inactiveStakeBalance, amount);
StakerActor._decrementNextBalance(expectedBalances.globalInactiveStakeBalance, amount);
} else if (from.status === StakeStatus.Delegated && from.poolId !== undefined) {
@@ -324,10 +299,7 @@ export class StakerActor extends BaseActor {
StakerActor._decrementNextBalance(expectedBalances.totalDelegatedStakeByPool[from.poolId], amount);
}
// to
if (to.status === StakeStatus.Active) {
StakerActor._incrementNextBalance(expectedBalances.activeStakeBalance, amount);
StakerActor._incrementNextBalance(expectedBalances.globalActiveStakeBalance, amount);
} else if (to.status === StakeStatus.Inactive) {
if (to.status === StakeStatus.Inactive) {
StakerActor._incrementNextBalance(expectedBalances.inactiveStakeBalance, amount);
StakerActor._incrementNextBalance(expectedBalances.globalInactiveStakeBalance, amount);
} else if (to.status === StakeStatus.Delegated && to.poolId !== undefined) {
@@ -347,8 +319,8 @@ export class StakerActor extends BaseActor {
// check balances
expectedBalances.zrxBalance = expectedBalances.zrxBalance.minus(amount);
expectedBalances.stakeBalanceInVault = expectedBalances.stakeBalanceInVault.plus(amount);
StakerActor._incrementCurrentAndNextBalance(expectedBalances.activeStakeBalance, amount);
StakerActor._incrementCurrentAndNextBalance(expectedBalances.globalActiveStakeBalance, amount);
StakerActor._incrementCurrentAndNextBalance(expectedBalances.inactiveStakeBalance, amount);
StakerActor._incrementCurrentAndNextBalance(expectedBalances.globalInactiveStakeBalance, amount);
return expectedBalances;
}
}

View File

@@ -40,11 +40,11 @@ blockchainTests.resets('Catastrophe Tests', env => {
await stakingApiWrapper.stakingContract.stake.awaitTransactionSuccessAsync(amountToStake, {
from: actors[0],
});
const activeStakeBalance = await stakingApiWrapper.stakingContract.getOwnerStakeByStatus.callAsync(
const inactiveStakeBalance = await stakingApiWrapper.stakingContract.getOwnerStakeByStatus.callAsync(
actors[0],
StakeStatus.Active,
StakeStatus.Inactive,
);
expect(activeStakeBalance.currentEpochBalance).to.be.bignumber.equal(amountToStake);
expect(inactiveStakeBalance.currentEpochBalance).to.be.bignumber.equal(amountToStake);
});
it('should not change state when in read-only mode', async () => {
// set to read-only mode
@@ -54,11 +54,11 @@ blockchainTests.resets('Catastrophe Tests', env => {
await stakingApiWrapper.stakingContract.stake.awaitTransactionSuccessAsync(amountToStake, {
from: actors[0],
});
const activeStakeBalance = await stakingApiWrapper.stakingContract.getOwnerStakeByStatus.callAsync(
const inactiveStakeBalance = await stakingApiWrapper.stakingContract.getOwnerStakeByStatus.callAsync(
actors[0],
StakeStatus.Active,
StakeStatus.Inactive,
);
expect(activeStakeBalance.currentEpochBalance).to.be.bignumber.equal(ZERO);
expect(inactiveStakeBalance.currentEpochBalance).to.be.bignumber.equal(ZERO);
});
it('should read values correctly when in read-only mode', async () => {
// stake some zrx
@@ -69,11 +69,11 @@ blockchainTests.resets('Catastrophe Tests', env => {
// set to read-only mode
await stakingApiWrapper.stakingProxyContract.setReadOnlyMode.awaitTransactionSuccessAsync(true);
// read stake balance in read-only mode
const activeStakeBalanceReadOnly = await stakingApiWrapper.stakingContract.getOwnerStakeByStatus.callAsync(
const inactiveStakeBalanceReadOnly = await stakingApiWrapper.stakingContract.getOwnerStakeByStatus.callAsync(
actors[0],
StakeStatus.Active,
StakeStatus.Inactive,
);
expect(activeStakeBalanceReadOnly.currentEpochBalance).to.be.bignumber.equal(amountToStake);
expect(inactiveStakeBalanceReadOnly.currentEpochBalance).to.be.bignumber.equal(amountToStake);
});
it('should exit read-only mode', async () => {
// set to read-only mode
@@ -84,11 +84,11 @@ blockchainTests.resets('Catastrophe Tests', env => {
await stakingApiWrapper.stakingContract.stake.awaitTransactionSuccessAsync(amountToStake, {
from: actors[0],
});
const activeStakeBalance = await stakingApiWrapper.stakingContract.getOwnerStakeByStatus.callAsync(
const inactiveStakeBalance = await stakingApiWrapper.stakingContract.getOwnerStakeByStatus.callAsync(
actors[0],
StakeStatus.Active,
StakeStatus.Inactive,
);
expect(activeStakeBalance.currentEpochBalance).to.be.bignumber.equal(amountToStake);
expect(inactiveStakeBalance.currentEpochBalance).to.be.bignumber.equal(amountToStake);
});
it('should emit event when setting read-only mode', async () => {
// set to read-only mode

View File

@@ -176,7 +176,7 @@ blockchainTests.resets('Testing Rewards', env => {
const amount = toBaseUnitAmount(4);
await stakers[0].stakeAsync(amount);
await stakers[0].moveStakeAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolId),
amount,
);
@@ -248,7 +248,7 @@ blockchainTests.resets('Testing Rewards', env => {
const totalStakeAmount = toBaseUnitAmount(10);
await stakers[0].stakeAsync(stakeAmounts[0]);
await stakers[0].moveStakeAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolId),
stakeAmounts[0],
);
@@ -259,7 +259,7 @@ blockchainTests.resets('Testing Rewards', env => {
// second staker delegates (epoch 1)
await stakers[1].stakeAsync(stakeAmounts[1]);
await stakers[1].moveStakeAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolId),
stakeAmounts[1],
);
@@ -355,7 +355,7 @@ blockchainTests.resets('Testing Rewards', env => {
// undelegate (withdraws delegator's rewards)
await stakers[0].moveStakeAsync(
new StakeInfo(StakeStatus.Delegated, poolId),
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
stakeAmount,
);
// sanity check final balances
@@ -436,7 +436,7 @@ blockchainTests.resets('Testing Rewards', env => {
// undelegate stake and finalize epoch
await stakers[0].moveStakeAsync(
new StakeInfo(StakeStatus.Delegated, poolId),
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
stakeAmount,
);
@@ -472,7 +472,7 @@ blockchainTests.resets('Testing Rewards', env => {
// undelegate stake and finalize epoch
await stakers[0].moveStakeAsync(
new StakeInfo(StakeStatus.Delegated, poolId),
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
stakeAmount,
);
await payProtocolFeeAndFinalize();
@@ -499,7 +499,7 @@ blockchainTests.resets('Testing Rewards', env => {
// undelegate stake and finalize epoch
await stakers[0].moveStakeAsync(
new StakeInfo(StakeStatus.Delegated, poolId),
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
stakeAmount,
);
await payProtocolFeeAndFinalize();
@@ -507,7 +507,7 @@ blockchainTests.resets('Testing Rewards', env => {
await payProtocolFeeAndFinalize(rewardNotForDelegator);
// delegate stake and go to next epoch
await stakers[0].moveStakeAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolId),
stakeAmount,
);
@@ -530,7 +530,7 @@ blockchainTests.resets('Testing Rewards', env => {
const stakeAmount = toBaseUnitAmount(4);
await stakers[0].stakeAsync(stakeAmount);
await stakers[0].moveStakeAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolId),
stakeAmount,
);
@@ -539,7 +539,7 @@ blockchainTests.resets('Testing Rewards', env => {
// undelegate stake and finalize epoch
await stakers[0].moveStakeAsync(
new StakeInfo(StakeStatus.Delegated, poolId),
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
stakeAmount,
);
// this should go to the delegator
@@ -547,7 +547,7 @@ blockchainTests.resets('Testing Rewards', env => {
// delegate stake ~ this will result in a payout where rewards are computed on
// the balance's `currentEpochBalance` field but not the `nextEpochBalance` field.
await stakers[0].moveStakeAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolId),
stakeAmount,
);
@@ -565,7 +565,7 @@ blockchainTests.resets('Testing Rewards', env => {
const stakeAmount = toBaseUnitAmount(4);
await stakers[0].stakeAsync(stakeAmount);
await stakers[0].moveStakeAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolId),
stakeAmount,
);
@@ -595,7 +595,7 @@ blockchainTests.resets('Testing Rewards', env => {
const undelegateAmount = toBaseUnitAmount(2.5);
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Delegated, poolId),
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
undelegateAmount,
);
// finalize

View File

@@ -76,42 +76,47 @@ blockchainTests.resets('Stake Statuses', env => {
// epoch 1
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
await staker.moveStakeAsync(new StakeInfo(StakeStatus.Active), new StakeInfo(StakeStatus.Inactive), amount);
// still epoch 1 ~ should be able to move stake again
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
amount,
);
// still epoch 1 ~ should be able to move stake again
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
new StakeInfo(StakeStatus.Inactive),
amount,
);
});
it("should be able to reassign next epoch's stake", async () => {
// epoch 1
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
amount,
);
// still epoch 1 ~ should be able to move stake again
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
new StakeInfo(StakeStatus.Delegated, poolIds[1]),
amount,
);
});
it('should fail to move the same stake more than once', async () => {
// epoch 1
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
await staker.moveStakeAsync(new StakeInfo(StakeStatus.Active), new StakeInfo(StakeStatus.Inactive), amount);
// stake is now inactive, should not be able to move it out of active status again
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
amount,
new StakingRevertErrors.InsufficientBalanceError(amount, ZERO),
);
});
it('should fail to reassign stake', async () => {
// epoch 1
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
await staker.moveStakeAsync(new StakeInfo(StakeStatus.Active), new StakeInfo(StakeStatus.Inactive), amount);
// still epoch 1 ~ should be able to move stake again
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
amount,
);
// stake is now delegated; should fail to re-assign it from inactive back to active
// stake is now inactive, should not be able to move it out of active status again
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Delegated, poolIds[1]),
amount,
new StakingRevertErrors.InsufficientBalanceError(amount, ZERO),
);
@@ -122,14 +127,14 @@ blockchainTests.resets('Stake Statuses', env => {
// epoch 1
const amount = toBaseUnitAmount(10);
await staker.stakeAndMoveAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
amount,
);
// still epoch 1 ~ should be able to move stake again
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
new StakeInfo(StakeStatus.Inactive),
amount,
);
});
@@ -137,58 +142,20 @@ blockchainTests.resets('Stake Statuses', env => {
// epoch 1
const amount = toBaseUnitAmount(10);
await staker.stakeAndMoveAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
amount,
);
// stake is now inactive, should not be able to move it out of active status again
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
amount,
new StakingRevertErrors.InsufficientBalanceError(amount, ZERO),
);
});
it('should fail to reassign stake', async () => {
// epoch 1
const amount = toBaseUnitAmount(10);
await staker.stakeAndMoveAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
amount,
);
// still epoch 1 ~ should be able to move stake again
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
amount,
);
// stake is now delegated; should fail to re-assign it from inactive back to active
// stake is now inactive, should not be able to move it out of active status again
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Delegated, poolIds[1]),
amount,
new StakingRevertErrors.InsufficientBalanceError(amount, ZERO),
);
});
});
describe('Move Zero Stake', () => {
it('active -> active', async () => {
await staker.moveStakeAsync(new StakeInfo(StakeStatus.Active), new StakeInfo(StakeStatus.Active), ZERO);
});
it('active -> inactive', async () => {
await staker.moveStakeAsync(new StakeInfo(StakeStatus.Active), new StakeInfo(StakeStatus.Inactive), ZERO);
});
it('active -> delegated', async () => {
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
ZERO,
);
});
it('inactive -> active', async () => {
await staker.moveStakeAsync(new StakeInfo(StakeStatus.Inactive), new StakeInfo(StakeStatus.Active), ZERO);
});
it('inactive -> inactive', async () => {
await staker.moveStakeAsync(new StakeInfo(StakeStatus.Inactive), new StakeInfo(StakeStatus.Inactive), ZERO);
});
@@ -199,13 +166,6 @@ blockchainTests.resets('Stake Statuses', env => {
ZERO,
);
});
it('delegated -> active', async () => {
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
new StakeInfo(StakeStatus.Active),
ZERO,
);
});
it('delegated -> inactive', async () => {
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
@@ -233,8 +193,8 @@ blockchainTests.resets('Stake Statuses', env => {
// setup
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
if (from.status !== StakeStatus.Active) {
await staker.moveStakeAsync(new StakeInfo(StakeStatus.Active), from, amount);
if (from.status !== StakeStatus.Inactive) {
await staker.moveStakeAsync(new StakeInfo(StakeStatus.Inactive), from, amount);
}
// run test, checking balances in epochs [n .. n + 2]
// in epoch `n` - `next` is set
@@ -242,21 +202,6 @@ blockchainTests.resets('Stake Statuses', env => {
await staker.moveStakeAsync(from, to, amount.div(2));
await staker.goToNextEpochAsync();
};
it('active -> active', async () => {
await testMovePartialStake(new StakeInfo(StakeStatus.Active), new StakeInfo(StakeStatus.Active));
});
it('active -> inactive', async () => {
await testMovePartialStake(new StakeInfo(StakeStatus.Active), new StakeInfo(StakeStatus.Inactive));
});
it('active -> delegated', async () => {
await testMovePartialStake(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
);
});
it('inactive -> active', async () => {
await testMovePartialStake(new StakeInfo(StakeStatus.Inactive), new StakeInfo(StakeStatus.Active));
});
it('inactive -> inactive', async () => {
await testMovePartialStake(new StakeInfo(StakeStatus.Inactive), new StakeInfo(StakeStatus.Inactive));
});
@@ -266,12 +211,6 @@ blockchainTests.resets('Stake Statuses', env => {
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
);
});
it('delegated -> active', async () => {
await testMovePartialStake(
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
new StakeInfo(StakeStatus.Active),
);
});
it('delegated -> inactive', async () => {
await testMovePartialStake(
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
@@ -290,20 +229,9 @@ blockchainTests.resets('Stake Statuses', env => {
new StakeInfo(StakeStatus.Delegated, poolIds[1]),
);
});
it('active -> delegated (non-existent pool)', async () => {
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Delegated, unusedPoolId),
amount,
new StakingRevertErrors.PoolExistenceError(unusedPoolId, false),
);
});
it('inactive -> delegated (non-existent pool)', async () => {
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
await staker.moveStakeAsync(new StakeInfo(StakeStatus.Active), new StakeInfo(StakeStatus.Inactive), amount);
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, unusedPoolId),
@@ -315,7 +243,7 @@ blockchainTests.resets('Stake Statuses', env => {
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
amount,
);
@@ -326,16 +254,6 @@ blockchainTests.resets('Stake Statuses', env => {
new StakingRevertErrors.PoolExistenceError(unusedPoolId, false),
);
});
it('delegated (non-existent pool) -> active', async () => {
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Delegated, unusedPoolId),
new StakeInfo(StakeStatus.Active),
amount,
new StakingRevertErrors.PoolExistenceError(unusedPoolId, false),
);
});
});
describe('Unstake', () => {
it('should successfully unstake zero ZRX', async () => {
@@ -345,102 +263,126 @@ blockchainTests.resets('Stake Statuses', env => {
it('should successfully unstake after becoming inactive', async () => {
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
await staker.moveStakeAsync(new StakeInfo(StakeStatus.Active), new StakeInfo(StakeStatus.Inactive), amount);
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
amount,
);
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
new StakeInfo(StakeStatus.Inactive),
amount,
);
await staker.goToNextEpochAsync(); // stake is now inactive
await staker.unstakeAsync(amount);
});
it('should fail to unstake with insufficient balance', async () => {
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
await staker.unstakeAsync(amount, new StakingRevertErrors.InsufficientBalanceError(amount, ZERO));
});
it('should fail to unstake in the same epoch as stake was set to inactive', async () => {
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
await staker.moveStakeAsync(new StakeInfo(StakeStatus.Active), new StakeInfo(StakeStatus.Inactive), amount);
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
amount,
);
await staker.goToNextEpochAsync(); // stake is now delegated
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
new StakeInfo(StakeStatus.Inactive),
amount,
);
await staker.unstakeAsync(amount, new StakingRevertErrors.InsufficientBalanceError(amount, ZERO));
});
it('should fail to unstake in same epoch that inactive stake has been reactivated', async () => {
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
await staker.moveStakeAsync(new StakeInfo(StakeStatus.Active), new StakeInfo(StakeStatus.Inactive), amount);
await staker.goToNextEpochAsync(); // stake is now inactive
await staker.moveStakeAsync(new StakeInfo(StakeStatus.Inactive), new StakeInfo(StakeStatus.Active), amount);
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
amount,
);
await staker.unstakeAsync(amount, new StakingRevertErrors.InsufficientBalanceError(amount, ZERO));
});
it('should fail to unstake one epoch after inactive stake has been reactivated', async () => {
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
await staker.moveStakeAsync(new StakeInfo(StakeStatus.Active), new StakeInfo(StakeStatus.Inactive), amount);
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
amount,
);
await staker.goToNextEpochAsync(); // stake is now inactive
await staker.moveStakeAsync(new StakeInfo(StakeStatus.Inactive), new StakeInfo(StakeStatus.Active), amount);
await staker.goToNextEpochAsync(); // stake is active
await staker.unstakeAsync(amount, new StakingRevertErrors.InsufficientBalanceError(amount, ZERO));
});
it('should fail to unstake >1 epoch after inactive/withdrawable stake has been reactivated', async () => {
it('should fail to unstake >1 epoch after inactive stake has been reactivated', async () => {
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
await staker.moveStakeAsync(new StakeInfo(StakeStatus.Active), new StakeInfo(StakeStatus.Inactive), amount);
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
amount,
);
await staker.goToNextEpochAsync(); // stake is now inactive
await staker.goToNextEpochAsync(); // stake is now withdrawable
await staker.moveStakeAsync(new StakeInfo(StakeStatus.Inactive), new StakeInfo(StakeStatus.Active), amount);
await staker.goToNextEpochAsync(); // stake is active and not withdrawable
await staker.goToNextEpochAsync(); // stake is active and not withdrawable
await staker.unstakeAsync(amount, new StakingRevertErrors.InsufficientBalanceError(amount, ZERO));
});
it('should successfuly unstake freshly deposited stake', async () => {
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
await staker.unstakeAsync(amount);
});
});
describe('Simulations', () => {
it('Simulation from Staking Spec', async () => {
// Epoch 1: Stake some ZRX
await staker.stakeAsync(toBaseUnitAmount(4));
// Later in Epoch 1: User delegates and deactivates some stake
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
toBaseUnitAmount(1),
);
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
toBaseUnitAmount(2),
);
// Epoch 2: Status updates (no user intervention required)
await staker.goToNextEpochAsync();
// Epoch 3: Stake that has been inactive for an epoch can be withdrawn (no user intervention required)
await staker.goToNextEpochAsync();
// Later in Epoch 3: User reactivates half of their inactive stake; this becomes Active next epoch
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Active),
toBaseUnitAmount(0.5),
);
// Later in Epoch 3: User re-delegates half of their stake from Pool 1 to Pool 2
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
new StakeInfo(StakeStatus.Delegated, poolIds[1]),
toBaseUnitAmount(1),
);
// Epoch 4: Status updates (no user intervention required)
await staker.goToNextEpochAsync();
// Later in Epoch 4: User deactivates all active stake
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
toBaseUnitAmount(1.5),
);
// Later in Epoch 4: User withdraws all available inactive stake
await staker.unstakeAsync(toBaseUnitAmount(0.5));
// Epoch 5: Status updates (no user intervention required)
await staker.goToNextEpochAsync();
// Later in Epoch 5: User reactivates a portion of their stake
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Active),
toBaseUnitAmount(1),
);
// Epoch 6: Status updates (no user intervention required)
await staker.goToNextEpochAsync();
});
// it('Simulation from Staking Spec', async () => {
// // Epoch 1: Stake some ZRX
// await staker.stakeAsync(toBaseUnitAmount(4));
// // Later in Epoch 1: User delegates and deactivates some stake
// await staker.moveStakeAsync(
// new StakeInfo(StakeStatus.Active),
// new StakeInfo(StakeStatus.Inactive),
// toBaseUnitAmount(1),
// );
// await staker.moveStakeAsync(
// new StakeInfo(StakeStatus.Active),
// new StakeInfo(StakeStatus.Delegated, poolIds[0]),
// toBaseUnitAmount(2),
// );
// // Epoch 2: Status updates (no user intervention required)
// await staker.goToNextEpochAsync();
// // Epoch 3: Stake that has been inactive for an epoch can be withdrawn (no user intervention required)
// await staker.goToNextEpochAsync();
// // Later in Epoch 3: User reactivates half of their inactive stake; this becomes Active next epoch
// await staker.moveStakeAsync(
// new StakeInfo(StakeStatus.Inactive),
// new StakeInfo(StakeStatus.Active),
// toBaseUnitAmount(0.5),
// );
// // Later in Epoch 3: User re-delegates half of their stake from Pool 1 to Pool 2
// await staker.moveStakeAsync(
// new StakeInfo(StakeStatus.Delegated, poolIds[0]),
// new StakeInfo(StakeStatus.Delegated, poolIds[1]),
// toBaseUnitAmount(1),
// );
// // Epoch 4: Status updates (no user intervention required)
// await staker.goToNextEpochAsync();
// // Later in Epoch 4: User deactivates all active stake
// await staker.moveStakeAsync(
// new StakeInfo(StakeStatus.Active),
// new StakeInfo(StakeStatus.Inactive),
// toBaseUnitAmount(1.5),
// );
// // Later in Epoch 4: User withdraws all available inactive stake
// await staker.unstakeAsync(toBaseUnitAmount(0.5));
// // Epoch 5: Status updates (no user intervention required)
// await staker.goToNextEpochAsync();
// // Later in Epoch 5: User reactivates a portion of their stake
// await staker.moveStakeAsync(
// new StakeInfo(StakeStatus.Inactive),
// new StakeInfo(StakeStatus.Active),
// toBaseUnitAmount(1),
// );
// // Epoch 6: Status updates (no user intervention required)
// await staker.goToNextEpochAsync();
// });
});
});
// tslint:enable:no-unnecessary-type-assertion

View File

@@ -120,7 +120,7 @@ export class CumulativeRewardTrackingSimulation {
from: this._staker,
});
receipt = await this._stakingApiWrapper.stakingContract.moveStake.awaitTransactionSuccessAsync(
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
new StakeInfo(StakeStatus.Delegated, this._poolId),
this._amountToStake,
{ from: this._staker },
@@ -130,7 +130,7 @@ export class CumulativeRewardTrackingSimulation {
case TestAction.Undelegate:
receipt = await this._stakingApiWrapper.stakingContract.moveStake.awaitTransactionSuccessAsync(
new StakeInfo(StakeStatus.Delegated, this._poolId),
new StakeInfo(StakeStatus.Active),
new StakeInfo(StakeStatus.Inactive),
this._amountToStake,
{ from: this._staker },
);

View File

@@ -68,7 +68,6 @@ export interface StakeBalanceByPool {
}
export enum StakeStatus {
Active,
Inactive,
Delegated,
}
@@ -88,10 +87,8 @@ export interface StakeBalances {
zrxBalance: BigNumber;
stakeBalance: BigNumber;
stakeBalanceInVault: BigNumber;
activeStakeBalance: StoredBalance;
inactiveStakeBalance: StoredBalance;
delegatedStakeBalance: StoredBalance;
globalActiveStakeBalance: StoredBalance;
globalInactiveStakeBalance: StoredBalance;
globalDelegatedStakeBalance: StoredBalance;
delegatedStakeByPool: StakeBalanceByPool;