98 lines
4.3 KiB
TypeScript
98 lines
4.3 KiB
TypeScript
import { WETH9Events, WETH9TransferEventArgs } from '@0x/contracts-erc20';
|
|
import { loadCurrentBalance, StakingRevertErrors, StoredBalance } from '@0x/contracts-staking';
|
|
import { expect, filterLogsToArguments } from '@0x/contracts-test-utils';
|
|
import { BigNumber } from '@0x/utils';
|
|
import { TxData } from 'ethereum-types';
|
|
|
|
import { DeploymentManager } from '../deployment_manager';
|
|
import { SimulationEnvironment } from '../simulation';
|
|
|
|
import { FunctionAssertion, FunctionResult } from './function_assertion';
|
|
|
|
interface WithdrawDelegatorRewardsBeforeInfo {
|
|
delegatorStake: StoredBalance;
|
|
poolRewards: BigNumber;
|
|
wethReservedForPoolRewards: BigNumber;
|
|
}
|
|
|
|
/**
|
|
* Returns a FunctionAssertion for `withdrawDelegatorRewards` which assumes valid input is provided.
|
|
* It checks that the delegator's stake gets synced and pool rewards are updated to reflect the
|
|
* amount withdrawn.
|
|
*/
|
|
/* tslint:disable:no-unnecessary-type-assertion */
|
|
export function validWithdrawDelegatorRewardsAssertion(
|
|
deployment: DeploymentManager,
|
|
simulationEnvironment: SimulationEnvironment,
|
|
): FunctionAssertion<[string], WithdrawDelegatorRewardsBeforeInfo, void> {
|
|
const { stakingWrapper } = deployment.staking;
|
|
|
|
return new FunctionAssertion(stakingWrapper, 'withdrawDelegatorRewards', {
|
|
before: async (args: [string], txData: Partial<TxData>) => {
|
|
const [poolId] = args;
|
|
|
|
const delegatorStake = await stakingWrapper
|
|
.getStakeDelegatedToPoolByOwner(txData.from as string, poolId)
|
|
.callAsync();
|
|
const poolRewards = await stakingWrapper.rewardsByPoolId(poolId).callAsync();
|
|
const wethReservedForPoolRewards = await stakingWrapper.wethReservedForPoolRewards().callAsync();
|
|
return { delegatorStake, poolRewards, wethReservedForPoolRewards };
|
|
},
|
|
after: async (
|
|
beforeInfo: WithdrawDelegatorRewardsBeforeInfo,
|
|
result: FunctionResult,
|
|
args: [string],
|
|
txData: Partial<TxData>,
|
|
) => {
|
|
// Ensure that the tx succeeded.
|
|
expect(result.success, `Error: ${result.data}`).to.be.true();
|
|
|
|
const [poolId] = args;
|
|
const { currentEpoch } = simulationEnvironment;
|
|
|
|
// Check that delegator stake has been synced
|
|
const expectedDelegatorStake = loadCurrentBalance(beforeInfo.delegatorStake, currentEpoch);
|
|
const delegatorStake = await stakingWrapper
|
|
.getStakeDelegatedToPoolByOwner(txData.from as string, poolId)
|
|
.callAsync();
|
|
expect(delegatorStake).to.deep.equal(expectedDelegatorStake);
|
|
|
|
// Check that pool rewards have been updated to reflect the amount withdrawn.
|
|
const transferEvents = filterLogsToArguments<WETH9TransferEventArgs>(
|
|
result.receipt!.logs, // tslint:disable-line:no-non-null-assertion
|
|
WETH9Events.Transfer,
|
|
);
|
|
const expectedPoolRewards =
|
|
transferEvents.length > 0
|
|
? beforeInfo.poolRewards.minus(transferEvents[0]._value)
|
|
: beforeInfo.poolRewards;
|
|
const poolRewards = await stakingWrapper.rewardsByPoolId(poolId).callAsync();
|
|
expect(poolRewards).to.bignumber.equal(expectedPoolRewards);
|
|
|
|
// TODO: Check CR
|
|
},
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Returns a FunctionAssertion for `withdrawDelegatorRewards` which assumes the given pool hasn't
|
|
* been finalized for the previous epoch. It checks that the call reverts with a PoolNotFinalizedError.
|
|
*/
|
|
export function invalidWithdrawDelegatorRewardsAssertion(
|
|
deployment: DeploymentManager,
|
|
simulationEnvironment: SimulationEnvironment,
|
|
): FunctionAssertion<[string], void, void> {
|
|
return new FunctionAssertion(deployment.staking.stakingWrapper, 'withdrawDelegatorRewards', {
|
|
after: async (_beforeInfo: void, result: FunctionResult, args: [string]) => {
|
|
// Ensure that the tx reverted.
|
|
expect(result.success).to.be.false();
|
|
|
|
// Check revert error
|
|
const [poolId] = args;
|
|
const { currentEpoch } = simulationEnvironment;
|
|
expect(result.data).to.equal(new StakingRevertErrors.PoolNotFinalizedError(poolId, currentEpoch.minus(1)));
|
|
},
|
|
});
|
|
}
|
|
/* tslint:enable:no-unnecessary-type-assertion */
|