Add negative assertions for endEpoch
This commit is contained in:
@@ -7,7 +7,11 @@ import { filterLogsToArguments, web3Wrapper } from '@0x/contracts-test-utils';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { BlockParamLiteral, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
|
||||
import { validEndEpochAssertion } from '../assertions/endEpoch';
|
||||
import {
|
||||
endEpochTooEarlyAssertion,
|
||||
endEpochUnfinalizedPoolsAssertion,
|
||||
validEndEpochAssertion,
|
||||
} from '../assertions/endEpoch';
|
||||
import { validFinalizePoolAssertion } from '../assertions/finalizePool';
|
||||
import { AssertionResult } from '../assertions/function_assertion';
|
||||
import { Pseudorandom } from '../utils/pseudorandom';
|
||||
@@ -43,6 +47,7 @@ export function KeeperMixin<TBase extends Constructor>(Base: TBase): TBase & Con
|
||||
...this.actor.simulationActions,
|
||||
validFinalizePool: this._validFinalizePool(),
|
||||
validEndEpoch: this._validEndEpoch(),
|
||||
invalidEndEpoch: this._invalidEndEpoch(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -118,6 +123,27 @@ export function KeeperMixin<TBase extends Constructor>(Base: TBase): TBase & Con
|
||||
}
|
||||
}
|
||||
|
||||
private async *_invalidEndEpoch(): AsyncIterableIterator<AssertionResult | void> {
|
||||
const { stakingWrapper } = this.actor.deployment.staking;
|
||||
while (true) {
|
||||
const { simulationEnvironment } = this.actor;
|
||||
const aggregatedStats = AggregatedStats.fromArray(
|
||||
await stakingWrapper
|
||||
.aggregatedStatsByEpoch(simulationEnvironment!.currentEpoch.minus(1))
|
||||
.callAsync(),
|
||||
);
|
||||
const assertion = aggregatedStats.numPoolsToFinalize.isGreaterThan(0)
|
||||
? endEpochUnfinalizedPoolsAssertion(
|
||||
this.actor.deployment,
|
||||
simulationEnvironment!,
|
||||
aggregatedStats.numPoolsToFinalize,
|
||||
)
|
||||
: endEpochTooEarlyAssertion(this.actor.deployment);
|
||||
|
||||
yield assertion.executeAsync([], { from: this.actor.address });
|
||||
}
|
||||
}
|
||||
|
||||
private async _fastForwardToNextEpochAsync(): Promise<void> {
|
||||
const { stakingWrapper } = this.actor.deployment.staking;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
StakingEpochEndedEventArgs,
|
||||
StakingEpochFinalizedEventArgs,
|
||||
StakingEvents,
|
||||
StakingRevertErrors,
|
||||
} from '@0x/contracts-staking';
|
||||
import { constants, expect, verifyEventsFromLogs } from '@0x/contracts-test-utils';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
@@ -117,3 +118,49 @@ export function validEndEpochAssertion(
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a FunctionAssertion for `endEpoch` which assumes it has been called while the previous
|
||||
* epoch hasn't been fully finalized. Checks that the transaction reverts with PreviousEpochNotFinalizedError.
|
||||
*/
|
||||
export function endEpochUnfinalizedPoolsAssertion(
|
||||
deployment: DeploymentManager,
|
||||
simulationEnvironment: SimulationEnvironment,
|
||||
numPoolsToFinalizeFromPrevEpoch: BigNumber,
|
||||
): FunctionAssertion<[], void, void> {
|
||||
return new FunctionAssertion(deployment.staking.stakingWrapper, 'endEpoch', {
|
||||
after: async (_beforeInfo: void, result: FunctionResult) => {
|
||||
// Ensure that the tx reverted.
|
||||
expect(result.success).to.be.false();
|
||||
|
||||
// Check revert error
|
||||
expect(result.data).to.equal(
|
||||
new StakingRevertErrors.PreviousEpochNotFinalizedError(
|
||||
simulationEnvironment.currentEpoch.minus(1),
|
||||
numPoolsToFinalizeFromPrevEpoch,
|
||||
),
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a FunctionAssertion for `endEpoch` which assumes it has been called before the full epoch
|
||||
* duration has elapsed. Checks that the transaction reverts with BlockTimestampTooLowError.
|
||||
*/
|
||||
export function endEpochTooEarlyAssertion(deployment: DeploymentManager): FunctionAssertion<[], void, void> {
|
||||
const { stakingWrapper } = deployment.staking;
|
||||
return new FunctionAssertion(stakingWrapper, 'endEpoch', {
|
||||
after: async (_beforeInfo: void, result: FunctionResult) => {
|
||||
// Ensure that the tx reverted.
|
||||
expect(result.success).to.be.false();
|
||||
|
||||
// Check revert error
|
||||
const epochEndTime = await stakingWrapper.getCurrentEpochEarliestEndTimeInSeconds().callAsync();
|
||||
const lastBlockTime = await deployment.web3Wrapper.getBlockTimestampAsync('latest');
|
||||
expect(result.data).to.equal(
|
||||
new StakingRevertErrors.BlockTimestampTooLowError(epochEndTime, lastBlockTime),
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -38,8 +38,10 @@ export class StakingRewardsSimulation extends Simulation {
|
||||
...stakers.map(staker => [staker.simulationActions.validWithdrawDelegatorRewards, 0.1 / stakers.length]),
|
||||
// 10% chance of executing validFinalizePool for a random keeper
|
||||
...keepers.map(keeper => [keeper.simulationActions.validFinalizePool, 0.1 / keepers.length]),
|
||||
// 10% chance of executing validEndEpoch for a random keeper
|
||||
...keepers.map(keeper => [keeper.simulationActions.validEndEpoch, 0.1 / keepers.length]),
|
||||
// 7% chance of executing validEndEpoch for a random keeper
|
||||
...keepers.map(keeper => [keeper.simulationActions.validEndEpoch, 0.07 / keepers.length]),
|
||||
// 3% chance of executing invalidEndEpoch for a random keeper
|
||||
...keepers.map(keeper => [keeper.simulationActions.invalidEndEpoch, 0.03 / keepers.length]),
|
||||
// 50% chance of executing an assertion generated from the pool membership simulation
|
||||
[poolMembership.generator, 0.5],
|
||||
// 20% chance of executing an assertion generated from the stake management simulation
|
||||
|
||||
Reference in New Issue
Block a user