Delegator Actor
This commit is contained in:
		@@ -23,8 +23,11 @@ export class DelegatorActor extends StakerActor {
 | 
			
		||||
    constructor(owner: string, stakingWrapper: StakingWrapper) {
 | 
			
		||||
        super(owner, stakingWrapper);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public async depositAndDelegateAsync(poolId: string, amount: BigNumber, revertReason?: RevertReason): Promise<void> {
 | 
			
		||||
        // query init balances
 | 
			
		||||
        const initZrxBalanceOfVault = await this._stakingWrapper.getZrxTokenBalanceOfZrxVault();
 | 
			
		||||
        const initDelegatorBalances = await this.getBalancesAsync([poolId]);
 | 
			
		||||
        // deposit stake
 | 
			
		||||
        const txReceiptPromise = this._stakingWrapper.depositAndDelegateAsync(this._owner, poolId, amount);
 | 
			
		||||
        if (revertReason !== undefined) {
 | 
			
		||||
            await expectTransactionFailedAsync(
 | 
			
		||||
@@ -34,8 +37,25 @@ export class DelegatorActor extends StakerActor {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        const txReceipt = await txReceiptPromise;
 | 
			
		||||
        // @TODO check receipt logs and return value via eth_call
 | 
			
		||||
        // check balances
 | 
			
		||||
        let expectedDelegatorBalances = initDelegatorBalances;
 | 
			
		||||
        expectedDelegatorBalances.zrxBalance = initDelegatorBalances.zrxBalance.minus(amount);
 | 
			
		||||
        expectedDelegatorBalances.stakeBalance = initDelegatorBalances.stakeBalance.plus(amount);
 | 
			
		||||
        expectedDelegatorBalances.stakeBalanceInVault = initDelegatorBalances.stakeBalanceInVault.plus(amount);
 | 
			
		||||
        expectedDelegatorBalances.activatedStakeBalance = initDelegatorBalances.activatedStakeBalance.plus(amount);
 | 
			
		||||
        expectedDelegatorBalances.delegatedStakeBalance = initDelegatorBalances.delegatedStakeBalance.plus(amount);
 | 
			
		||||
        expectedDelegatorBalances.stakeDelegatedToPoolByOwner[0] = initDelegatorBalances.stakeDelegatedToPoolByOwner[0].plus(amount);
 | 
			
		||||
        expectedDelegatorBalances.stakeDelegatedToPool[0] = initDelegatorBalances.stakeDelegatedToPool[0].plus(amount);
 | 
			
		||||
        await this.assertBalancesAsync(expectedDelegatorBalances, [poolId]);
 | 
			
		||||
        // check zrx balance of vault
 | 
			
		||||
        const finalZrxBalanceOfVault = await this._stakingWrapper.getZrxTokenBalanceOfZrxVault();
 | 
			
		||||
        expect(finalZrxBalanceOfVault).to.be.bignumber.equal(initZrxBalanceOfVault.plus(amount));
 | 
			
		||||
    }
 | 
			
		||||
    public async activateAndDelegateStakeAsync(poolId: string, amount: BigNumber, revertReason?: RevertReason): Promise<void> {
 | 
			
		||||
        // query init balances
 | 
			
		||||
        const initDelegatorBalances = await this.getBalancesAsync([poolId]);
 | 
			
		||||
        // activate and delegate
 | 
			
		||||
        const txReceiptPromise = this._stakingWrapper.activateAndDelegateStakeAsync(this._owner, poolId, amount);
 | 
			
		||||
        if (revertReason !== undefined) {
 | 
			
		||||
            await expectTransactionFailedAsync(
 | 
			
		||||
@@ -45,8 +65,23 @@ export class DelegatorActor extends StakerActor {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        const txReceipt = await txReceiptPromise;
 | 
			
		||||
        // @TODO check receipt logs and return value via eth_call
 | 
			
		||||
        // check balances
 | 
			
		||||
        // check balances
 | 
			
		||||
        let expectedDelegatorBalances = initDelegatorBalances;
 | 
			
		||||
        expectedDelegatorBalances.activatedStakeBalance = initDelegatorBalances.activatedStakeBalance.plus(amount);
 | 
			
		||||
        expectedDelegatorBalances.withdrawableStakeBalance = expectedDelegatorBalances.withdrawableStakeBalance.minus(amount);
 | 
			
		||||
        expectedDelegatorBalances.activatableStakeBalance = expectedDelegatorBalances.activatableStakeBalance.minus(amount);
 | 
			
		||||
        expectedDelegatorBalances.deactivatedStakeBalance = expectedDelegatorBalances.deactivatedStakeBalance.minus(amount);
 | 
			
		||||
        expectedDelegatorBalances.delegatedStakeBalance = initDelegatorBalances.delegatedStakeBalance.plus(amount);
 | 
			
		||||
        expectedDelegatorBalances.stakeDelegatedToPoolByOwner[0] = initDelegatorBalances.stakeDelegatedToPoolByOwner[0].plus(amount);
 | 
			
		||||
        expectedDelegatorBalances.stakeDelegatedToPool[0] = initDelegatorBalances.stakeDelegatedToPool[0].plus(amount);
 | 
			
		||||
        await this.assertBalancesAsync(expectedDelegatorBalances, [poolId]);
 | 
			
		||||
    }
 | 
			
		||||
    public async deactivateAndTimelockDelegatedStakeAsync(poolId: string, amount: BigNumber, revertReason?: RevertReason): Promise<void> {
 | 
			
		||||
        // query init balances
 | 
			
		||||
        const initDelegatorBalances = await this.getBalancesAsync([poolId]);
 | 
			
		||||
        // deactivate and timelock
 | 
			
		||||
        const txReceiptPromise = this._stakingWrapper.deactivateAndTimelockDelegatedStakeAsync(this._owner, poolId, amount);
 | 
			
		||||
        if (revertReason !== undefined) {
 | 
			
		||||
            await expectTransactionFailedAsync(
 | 
			
		||||
@@ -56,6 +91,16 @@ export class DelegatorActor extends StakerActor {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        const txReceipt = await txReceiptPromise;
 | 
			
		||||
        // @TODO check receipt logs and return value via eth_call
 | 
			
		||||
        // check balances
 | 
			
		||||
        let expectedDelegatorBalances = initDelegatorBalances;
 | 
			
		||||
        expectedDelegatorBalances.activatedStakeBalance = initDelegatorBalances.activatedStakeBalance.minus(amount);
 | 
			
		||||
        expectedDelegatorBalances.timelockedStakeBalance = expectedDelegatorBalances.timelockedStakeBalance.plus(amount);
 | 
			
		||||
        expectedDelegatorBalances.deactivatedStakeBalance = expectedDelegatorBalances.deactivatedStakeBalance.plus(amount);
 | 
			
		||||
        expectedDelegatorBalances.delegatedStakeBalance = initDelegatorBalances.delegatedStakeBalance.minus(amount);
 | 
			
		||||
        expectedDelegatorBalances.stakeDelegatedToPoolByOwner[0] = initDelegatorBalances.stakeDelegatedToPoolByOwner[0].minus(amount);
 | 
			
		||||
        expectedDelegatorBalances.stakeDelegatedToPool[0] = initDelegatorBalances.stakeDelegatedToPool[0].minus(amount);
 | 
			
		||||
        await this.assertBalancesAsync(expectedDelegatorBalances, [poolId]);
 | 
			
		||||
    }
 | 
			
		||||
    public async getBalancesAsync(maybePoolIds?: string[]): Promise<DelegatorBalances> {
 | 
			
		||||
        const stakerBalances = await super.getBalancesAsync();
 | 
			
		||||
@@ -76,10 +121,10 @@ export class DelegatorActor extends StakerActor {
 | 
			
		||||
    }
 | 
			
		||||
    public async assertBalancesAsync(expectedBalances: DelegatorBalances, maybePoolIds?: string[]): Promise<void> {
 | 
			
		||||
        await super.assertBalancesAsync(expectedBalances);
 | 
			
		||||
        const balances = await this.getBalancesAsync();
 | 
			
		||||
        const balances = await this.getBalancesAsync(maybePoolIds);
 | 
			
		||||
        expect(balances.delegatedStakeBalance, 'delegated stake balance').to.be.bignumber.equal(expectedBalances.delegatedStakeBalance);
 | 
			
		||||
        const poolIds = maybePoolIds !== undefined ? maybePoolIds : [];
 | 
			
		||||
        for (const i in poolIds) {
 | 
			
		||||
        for (let i = 0; i < poolIds.length; i++) {
 | 
			
		||||
            expect(balances.stakeDelegatedToPoolByOwner[i], `stake delegated to pool ${poolIds[i]} by owner`).to.be.bignumber.equal(expectedBalances.stakeDelegatedToPoolByOwner[i]);
 | 
			
		||||
            expect(balances.stakeDelegatedToPool[i], `total stake delegated to pool ${poolIds[i]}`).to.be.bignumber.equal(expectedBalances.stakeDelegatedToPool[i]);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -17,15 +17,14 @@ import { StakerBalances } from '../utils/types';
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
 | 
			
		||||
export class StakerActor {
 | 
			
		||||
    private readonly _owner: string;
 | 
			
		||||
    private readonly _stakingWrapper: StakingWrapper;
 | 
			
		||||
    protected readonly _owner: string;
 | 
			
		||||
    protected readonly _stakingWrapper: StakingWrapper;
 | 
			
		||||
 | 
			
		||||
    constructor(owner: string, stakingWrapper: StakingWrapper) {
 | 
			
		||||
        this._owner = owner;
 | 
			
		||||
        this._stakingWrapper = stakingWrapper;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public async depositAsync(amount: BigNumber, revertReason?: RevertReason) {
 | 
			
		||||
    public async depositAsync(amount: BigNumber, revertReason?: RevertReason): Promise<void> {
 | 
			
		||||
        // query init balances
 | 
			
		||||
        const initZrxBalanceOfVault = await this._stakingWrapper.getZrxTokenBalanceOfZrxVault();
 | 
			
		||||
        const initStakerBalances = await this.getBalancesAsync();
 | 
			
		||||
@@ -53,11 +52,11 @@ export class StakerActor {
 | 
			
		||||
        const finalZrxBalanceOfVault = await this._stakingWrapper.getZrxTokenBalanceOfZrxVault();
 | 
			
		||||
        expect(finalZrxBalanceOfVault).to.be.bignumber.equal(initZrxBalanceOfVault.minus(amount));
 | 
			
		||||
    }
 | 
			
		||||
    public async depositAndStakeAsync(amount: BigNumber, revertReason?: RevertReason) {
 | 
			
		||||
    public async depositAndStakeAsync(amount: BigNumber, revertReason?: RevertReason): Promise<void> {
 | 
			
		||||
        // @TODO - Implement
 | 
			
		||||
        const txReceipt = this._stakingWrapper.depositAndStakeAsync(this._owner, amount);
 | 
			
		||||
    }
 | 
			
		||||
    public async activateStakeAsync(amount: BigNumber, revertReason?: RevertReason) {
 | 
			
		||||
    public async activateStakeAsync(amount: BigNumber, revertReason?: RevertReason): Promise<void> {
 | 
			
		||||
        // query init balances
 | 
			
		||||
        const initStakerBalances = await this.getBalancesAsync();
 | 
			
		||||
        // activate stake
 | 
			
		||||
@@ -79,7 +78,7 @@ export class StakerActor {
 | 
			
		||||
        expectedStakerBalances.deactivatedStakeBalance = initStakerBalances.deactivatedStakeBalance.minus(amount);
 | 
			
		||||
        await this.assertBalancesAsync(expectedStakerBalances);
 | 
			
		||||
    }
 | 
			
		||||
    public async deactivateAndTimelockStakeAsync(amount: BigNumber, revertReason?: RevertReason) {
 | 
			
		||||
    public async deactivateAndTimelockStakeAsync(amount: BigNumber, revertReason?: RevertReason): Promise<void> {
 | 
			
		||||
        // query init balances
 | 
			
		||||
        const initStakerBalances = await this.getBalancesAsync();
 | 
			
		||||
        // deactivate and timelock stake
 | 
			
		||||
@@ -100,7 +99,7 @@ export class StakerActor {
 | 
			
		||||
        expectedStakerBalances.deactivatedStakeBalance = initStakerBalances.deactivatedStakeBalance.plus(amount);
 | 
			
		||||
        await this.assertBalancesAsync(expectedStakerBalances);
 | 
			
		||||
    }
 | 
			
		||||
    public async withdrawAsync(amount: BigNumber, revertReason?: RevertReason) {
 | 
			
		||||
    public async withdrawAsync(amount: BigNumber, revertReason?: RevertReason): Promise<void> {
 | 
			
		||||
        // query init balances
 | 
			
		||||
        const initZrxBalanceOfVault = await this._stakingWrapper.getZrxTokenBalanceOfZrxVault();
 | 
			
		||||
        const initStakerBalances = await this.getBalancesAsync();
 | 
			
		||||
@@ -128,7 +127,6 @@ export class StakerActor {
 | 
			
		||||
        const finalZrxBalanceOfVault = await this._stakingWrapper.getZrxTokenBalanceOfZrxVault();
 | 
			
		||||
        expect(finalZrxBalanceOfVault).to.be.bignumber.equal(initZrxBalanceOfVault.minus(amount));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public async getBalancesAsync(): Promise<StakerBalances> {
 | 
			
		||||
        const stakerBalances = {
 | 
			
		||||
            zrxBalance: await this._stakingWrapper.getZrxTokenBalance(this._owner),
 | 
			
		||||
@@ -142,7 +140,6 @@ export class StakerActor {
 | 
			
		||||
        }
 | 
			
		||||
        return stakerBalances;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public async assertBalancesAsync(expectedBalances: StakerBalances): Promise<void> {
 | 
			
		||||
        const balances = await this.getBalancesAsync();
 | 
			
		||||
        expect(balances.zrxBalance, 'zrx balance').to.be.bignumber.equal(expectedBalances.zrxBalance);
 | 
			
		||||
@@ -154,14 +151,12 @@ export class StakerActor {
 | 
			
		||||
        expect(balances.timelockedStakeBalance, 'timelocked stake balance').to.be.bignumber.equal(expectedBalances.timelockedStakeBalance);
 | 
			
		||||
        expect(balances.deactivatedStakeBalance, 'deactivated stake balance').to.be.bignumber.equal(expectedBalances.deactivatedStakeBalance);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public async forceTimelockSyncAsync() {
 | 
			
		||||
    public async forceTimelockSyncAsync(): Promise<void> {
 | 
			
		||||
        const initBalances = await this.getBalancesAsync();
 | 
			
		||||
        await this._stakingWrapper.forceTimelockSyncAsync(this._owner);
 | 
			
		||||
        await this.assertBalancesAsync(initBalances);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public async skipToNextTimelockPeriodAsync() {
 | 
			
		||||
    public async skipToNextTimelockPeriodAsync(): Promise<void> {
 | 
			
		||||
        // query some initial values
 | 
			
		||||
        const initBalances = await this.getBalancesAsync();
 | 
			
		||||
        const timelockStart = await this._stakingWrapper.getTimelockStartAsync(this._owner);
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@ import { StakingContract } from '../src';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import { StakerActor } from './actors/StakerActor';
 | 
			
		||||
import { DelegatorActor } from './actors/DelegatorActor';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
@@ -107,7 +108,7 @@ describe('Staking Core', () => {
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('staking/unstaking', async () => {
 | 
			
		||||
        it.only('staking/unstaking', async () => {
 | 
			
		||||
            // setup test parameters
 | 
			
		||||
            const amountToStake = stakingWrapper.toBaseUnitAmount(10);
 | 
			
		||||
            const amountToDeactivate = stakingWrapper.toBaseUnitAmount(4);
 | 
			
		||||
@@ -131,256 +132,31 @@ describe('Staking Core', () => {
 | 
			
		||||
            await staker.withdrawAsync(amountToWithdraw);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('delegating/undelegating', async () => {
 | 
			
		||||
            ///// 1 SETUP TEST PARAMETERS /////
 | 
			
		||||
        it.only('delegating/undelegating', async () => {
 | 
			
		||||
            // setup test parameters
 | 
			
		||||
            const amountToDelegate = stakingWrapper.toBaseUnitAmount(10);
 | 
			
		||||
            const amountToDeactivate = stakingWrapper.toBaseUnitAmount(4);
 | 
			
		||||
            const amountToReactivate = stakingWrapper.toBaseUnitAmount(1);
 | 
			
		||||
            const amountToWithdraw = stakingWrapper.toBaseUnitAmount(1.5);
 | 
			
		||||
            const owner = stakers[0];
 | 
			
		||||
            const poolOperator = stakers[1];
 | 
			
		||||
            const operatorShare = 39;
 | 
			
		||||
            const poolId = await stakingWrapper.createPoolAsync(poolOperator, operatorShare);
 | 
			
		||||
            // check zrx token balances before minting stake
 | 
			
		||||
            const zrxTokenBalanceOfVaultBeforeStaking = await stakingWrapper.getZrxTokenBalanceOfZrxVault();
 | 
			
		||||
            expect(zrxTokenBalanceOfVaultBeforeStaking).to.be.bignumber.equal(new BigNumber(0));
 | 
			
		||||
            const zrxTokenBalanceOfStakerBeforeStaking = await stakingWrapper.getZrxTokenBalance(owner);
 | 
			
		||||
            expect(zrxTokenBalanceOfStakerBeforeStaking).to.be.bignumber.gte(amountToDelegate);
 | 
			
		||||
            ///// 2 DELEGATE ZRX /////
 | 
			
		||||
            // mint stake
 | 
			
		||||
            await stakingWrapper.depositAndDelegateAsync(owner, poolId, amountToDelegate);
 | 
			
		||||
            {
 | 
			
		||||
                // check zrx vault balance
 | 
			
		||||
                const vaultBalance = await stakingWrapper.getZrxVaultBalance(owner);
 | 
			
		||||
                expect(vaultBalance).to.be.bignumber.equal(amountToDelegate);
 | 
			
		||||
                // check zrx token balances
 | 
			
		||||
                const zrxTokenBalanceOfVaultAfterStaking = await stakingWrapper.getZrxTokenBalanceOfZrxVault();
 | 
			
		||||
                expect(zrxTokenBalanceOfVaultAfterStaking).to.be.bignumber.equal(amountToDelegate);
 | 
			
		||||
                const zrxTokenBalanceOfStakerAfterStaking = await stakingWrapper.getZrxTokenBalance(owner);
 | 
			
		||||
                expect(zrxTokenBalanceOfStakerAfterStaking).to.be.bignumber.equal(zrxTokenBalanceOfStakerBeforeStaking.minus(amountToDelegate));
 | 
			
		||||
                // check stake balance after minting
 | 
			
		||||
                const stakeBalance = await stakingWrapper.getTotalStakeAsync(owner);
 | 
			
		||||
                expect(stakeBalance).to.be.bignumber.equal(amountToDelegate);
 | 
			
		||||
                // check delegated stake balance for owner
 | 
			
		||||
                const stakeDelegatedByOwner = await stakingWrapper.getStakeDelegatedByOwnerAsync(owner);
 | 
			
		||||
                expect(stakeDelegatedByOwner).to.be.bignumber.equal(amountToDelegate);
 | 
			
		||||
                // check delegated balance to pool by owner
 | 
			
		||||
                const stakeDelegatedToPoolByOwner = await stakingWrapper.getStakeDelegatedToPoolByOwnerAsync(poolId, owner);
 | 
			
		||||
                expect(stakeDelegatedToPoolByOwner).to.be.bignumber.equal(amountToDelegate);
 | 
			
		||||
                // checktotal amount delegated to pool
 | 
			
		||||
                const stakeDelegatedToPool = await stakingWrapper.getStakeDelegatedToPoolAsync(poolId);
 | 
			
		||||
                expect(stakeDelegatedToPool).to.be.bignumber.equal(amountToDelegate);
 | 
			
		||||
                // check timelocked stake is no longer activated
 | 
			
		||||
                const activatedStakeBalance = await stakingWrapper.getActivatedStakeAsync(owner);
 | 
			
		||||
                expect(activatedStakeBalance).to.be.bignumber.equal(amountToDelegate); 
 | 
			
		||||
                // check that timelocked stake is deactivated
 | 
			
		||||
                const deactivatedStakeBalance = await stakingWrapper.getDeactivatedStakeAsync(owner);
 | 
			
		||||
                expect(deactivatedStakeBalance).to.be.bignumber.equal(0); 
 | 
			
		||||
                // check amount that is timelocked
 | 
			
		||||
                const timelockedStakeBalance = await stakingWrapper.getTimelockedStakeAsync(owner);
 | 
			
		||||
                expect(timelockedStakeBalance).to.be.bignumber.equal(0);
 | 
			
		||||
                // check that timelocked stake cannot be withdrawn
 | 
			
		||||
                const withdrawableStakeBalance = await stakingWrapper.getWithdrawableStakeAsync(owner);
 | 
			
		||||
                expect(withdrawableStakeBalance).to.be.bignumber.equal(0);
 | 
			
		||||
                // check that timelocked stake cannot be reactivated
 | 
			
		||||
                const activatableStakeBalance = await stakingWrapper.getActivatableStakeAsync(owner);
 | 
			
		||||
                expect(activatableStakeBalance).to.be.bignumber.equal(0);
 | 
			
		||||
            }
 | 
			
		||||
            ///// 3 DEACTIVATE AND TIMELOCK DELEGATED STAKE /////
 | 
			
		||||
            // unstake
 | 
			
		||||
            await stakingWrapper.deactivateAndTimelockDelegatedStakeAsync(owner, poolId, amountToDeactivate);
 | 
			
		||||
           {
 | 
			
		||||
                // check total stake balance didn't change
 | 
			
		||||
                const totalStake = await stakingWrapper.getTotalStakeAsync(owner);
 | 
			
		||||
                expect(totalStake).to.be.bignumber.equal(amountToDelegate); 
 | 
			
		||||
                // check delegated stake balance for owner
 | 
			
		||||
                const stakeDelegatedByOwner = await stakingWrapper.getStakeDelegatedByOwnerAsync(owner);
 | 
			
		||||
                expect(stakeDelegatedByOwner).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate));
 | 
			
		||||
                // check delegated balance to pool by owner
 | 
			
		||||
                const stakeDelegatedToPoolByOwner = await stakingWrapper.getStakeDelegatedToPoolByOwnerAsync(poolId, owner);
 | 
			
		||||
                expect(stakeDelegatedToPoolByOwner).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate));
 | 
			
		||||
                // checktotal amount delegated to pool
 | 
			
		||||
                const stakeDelegatedToPool = await stakingWrapper.getStakeDelegatedToPoolAsync(poolId);
 | 
			
		||||
                expect(stakeDelegatedToPool).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate));
 | 
			
		||||
                // check timelocked stake is no longer activated
 | 
			
		||||
                const activatedStakeBalance = await stakingWrapper.getActivatedStakeAsync(owner);
 | 
			
		||||
                expect(activatedStakeBalance).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate)); 
 | 
			
		||||
                // check that timelocked stake is deactivated
 | 
			
		||||
                const deactivatedStakeBalance = await stakingWrapper.getDeactivatedStakeAsync(owner);
 | 
			
		||||
                expect(deactivatedStakeBalance).to.be.bignumber.equal(amountToDeactivate); 
 | 
			
		||||
                // check amount that is timelocked
 | 
			
		||||
                const timelockedStakeBalance = await stakingWrapper.getTimelockedStakeAsync(owner);
 | 
			
		||||
                expect(timelockedStakeBalance).to.be.bignumber.equal(amountToDeactivate);
 | 
			
		||||
                // check that timelocked stake cannot be withdrawn
 | 
			
		||||
                const withdrawableStakeBalance = await stakingWrapper.getWithdrawableStakeAsync(owner);
 | 
			
		||||
                expect(withdrawableStakeBalance).to.be.bignumber.equal(0);
 | 
			
		||||
                // check that timelocked stake cannot be reactivated
 | 
			
		||||
                const activatableStakeBalance = await stakingWrapper.getActivatableStakeAsync(owner);
 | 
			
		||||
                expect(activatableStakeBalance).to.be.bignumber.equal(0);
 | 
			
		||||
            }
 | 
			
		||||
            ///// 4 SKIP TO NEXT TIMELOCK PERIOD - NOTHING SHOULD HAVE CHANGED /////
 | 
			
		||||
            await stakingWrapper.skipToNextTimelockPeriodAsync();
 | 
			
		||||
            {
 | 
			
		||||
                // check total stake balance didn't change
 | 
			
		||||
                const totalStake = await stakingWrapper.getTotalStakeAsync(owner);
 | 
			
		||||
                expect(totalStake).to.be.bignumber.equal(amountToDelegate); 
 | 
			
		||||
                // check delegated stake balance for owner
 | 
			
		||||
                const stakeDelegatedByOwner = await stakingWrapper.getStakeDelegatedByOwnerAsync(owner);
 | 
			
		||||
                expect(stakeDelegatedByOwner).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate));
 | 
			
		||||
                // check delegated balance to pool by owner
 | 
			
		||||
                const stakeDelegatedToPoolByOwner = await stakingWrapper.getStakeDelegatedToPoolByOwnerAsync(poolId, owner);
 | 
			
		||||
                expect(stakeDelegatedToPoolByOwner).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate));
 | 
			
		||||
                // checktotal amount delegated to pool
 | 
			
		||||
                const stakeDelegatedToPool = await stakingWrapper.getStakeDelegatedToPoolAsync(poolId);
 | 
			
		||||
                expect(stakeDelegatedToPool).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate));
 | 
			
		||||
                // check timelocked stake is no longer activated
 | 
			
		||||
                const activatedStakeBalance = await stakingWrapper.getActivatedStakeAsync(owner);
 | 
			
		||||
                expect(activatedStakeBalance).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate)); 
 | 
			
		||||
                // check that timelocked stake is deactivated
 | 
			
		||||
                const deactivatedStakeBalance = await stakingWrapper.getDeactivatedStakeAsync(owner);
 | 
			
		||||
                expect(deactivatedStakeBalance).to.be.bignumber.equal(amountToDeactivate); 
 | 
			
		||||
                // check amount that is timelocked
 | 
			
		||||
                const timelockedStakeBalance = await stakingWrapper.getTimelockedStakeAsync(owner);
 | 
			
		||||
                expect(timelockedStakeBalance).to.be.bignumber.equal(amountToDeactivate);
 | 
			
		||||
                // check that timelocked stake cannot be withdrawn
 | 
			
		||||
                const withdrawableStakeBalance = await stakingWrapper.getWithdrawableStakeAsync(owner);
 | 
			
		||||
                expect(withdrawableStakeBalance).to.be.bignumber.equal(0);
 | 
			
		||||
                // check that timelocked stake cannot be reactivated
 | 
			
		||||
                const activatableStakeBalance = await stakingWrapper.getActivatableStakeAsync(owner);
 | 
			
		||||
                expect(activatableStakeBalance).to.be.bignumber.equal(0);
 | 
			
		||||
            }
 | 
			
		||||
            ///// 5 SKIP TO NEXT TIMELOCK PEIOD - SHOULD BE ABLE TO REACTIVATE/WITHDRAW TIMELOCKED STAKE /////
 | 
			
		||||
            await stakingWrapper.skipToNextTimelockPeriodAsync();
 | 
			
		||||
            {
 | 
			
		||||
                // check total stake balance didn't change
 | 
			
		||||
                const totalStake = await stakingWrapper.getTotalStakeAsync(owner);
 | 
			
		||||
                expect(totalStake).to.be.bignumber.equal(amountToDelegate); 
 | 
			
		||||
                // check delegated stake balance for owner
 | 
			
		||||
                const stakeDelegatedByOwner = await stakingWrapper.getStakeDelegatedByOwnerAsync(owner);
 | 
			
		||||
                expect(stakeDelegatedByOwner).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate));
 | 
			
		||||
                // check delegated balance to pool by owner
 | 
			
		||||
                const stakeDelegatedToPoolByOwner = await stakingWrapper.getStakeDelegatedToPoolByOwnerAsync(poolId, owner);
 | 
			
		||||
                expect(stakeDelegatedToPoolByOwner).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate));
 | 
			
		||||
                // checktotal amount delegated to pool
 | 
			
		||||
                const stakeDelegatedToPool = await stakingWrapper.getStakeDelegatedToPoolAsync(poolId);
 | 
			
		||||
                expect(stakeDelegatedToPool).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate));
 | 
			
		||||
                // check timelocked stake is no longer activated
 | 
			
		||||
                const activatedStakeBalance = await stakingWrapper.getActivatedStakeAsync(owner);
 | 
			
		||||
                expect(activatedStakeBalance).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate)); 
 | 
			
		||||
                // check that timelocked stake is deactivated
 | 
			
		||||
                const deactivatedStakeBalance = await stakingWrapper.getDeactivatedStakeAsync(owner);
 | 
			
		||||
                expect(deactivatedStakeBalance).to.be.bignumber.equal(amountToDeactivate); 
 | 
			
		||||
                // check amount that is timelocked
 | 
			
		||||
                const timelockedStakeBalance = await stakingWrapper.getTimelockedStakeAsync(owner);
 | 
			
		||||
                expect(timelockedStakeBalance).to.be.bignumber.equal(0);
 | 
			
		||||
                // check that timelocked stake cannot be withdrawn
 | 
			
		||||
                const withdrawableStakeBalance = await stakingWrapper.getWithdrawableStakeAsync(owner);
 | 
			
		||||
                expect(withdrawableStakeBalance).to.be.bignumber.equal(amountToDeactivate);
 | 
			
		||||
                // check that timelocked stake cannot be reactivated
 | 
			
		||||
                const activatableStakeBalance = await stakingWrapper.getActivatableStakeAsync(owner);
 | 
			
		||||
                expect(activatableStakeBalance).to.be.bignumber.equal(amountToDeactivate);
 | 
			
		||||
            }
 | 
			
		||||
            ///// 6 FORCE A SYNC - BALANCES SHOULD NOT CHANGE
 | 
			
		||||
            await stakingWrapper.forceTimelockSyncAsync(owner);
 | 
			
		||||
            {
 | 
			
		||||
                // check total stake balance didn't change
 | 
			
		||||
                const totalStake = await stakingWrapper.getTotalStakeAsync(owner);
 | 
			
		||||
                expect(totalStake).to.be.bignumber.equal(amountToDelegate); 
 | 
			
		||||
                // check delegated stake balance for owner
 | 
			
		||||
                const stakeDelegatedByOwner = await stakingWrapper.getStakeDelegatedByOwnerAsync(owner);
 | 
			
		||||
                expect(stakeDelegatedByOwner).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate));
 | 
			
		||||
                // check delegated balance to pool by owner
 | 
			
		||||
                const stakeDelegatedToPoolByOwner = await stakingWrapper.getStakeDelegatedToPoolByOwnerAsync(poolId, owner);
 | 
			
		||||
                expect(stakeDelegatedToPoolByOwner).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate));
 | 
			
		||||
                // checktotal amount delegated to pool
 | 
			
		||||
                const stakeDelegatedToPool = await stakingWrapper.getStakeDelegatedToPoolAsync(poolId);
 | 
			
		||||
                expect(stakeDelegatedToPool).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate));
 | 
			
		||||
                // check timelocked stake is no longer activated
 | 
			
		||||
                const activatedStakeBalance = await stakingWrapper.getActivatedStakeAsync(owner);
 | 
			
		||||
                expect(activatedStakeBalance).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate)); 
 | 
			
		||||
                // check that timelocked stake is deactivated
 | 
			
		||||
                const deactivatedStakeBalance = await stakingWrapper.getDeactivatedStakeAsync(owner);
 | 
			
		||||
                expect(deactivatedStakeBalance).to.be.bignumber.equal(amountToDeactivate); 
 | 
			
		||||
                // check amount that is timelocked
 | 
			
		||||
                const timelockedStakeBalance = await stakingWrapper.getTimelockedStakeAsync(owner);
 | 
			
		||||
                expect(timelockedStakeBalance).to.be.bignumber.equal(0);
 | 
			
		||||
                // check that timelocked stake cannot be withdrawn
 | 
			
		||||
                const withdrawableStakeBalance = await stakingWrapper.getWithdrawableStakeAsync(owner);
 | 
			
		||||
                expect(withdrawableStakeBalance).to.be.bignumber.equal(amountToDeactivate);
 | 
			
		||||
                // check that timelocked stake cannot be reactivated
 | 
			
		||||
                const activatableStakeBalance = await stakingWrapper.getActivatableStakeAsync(owner);
 | 
			
		||||
                expect(activatableStakeBalance).to.be.bignumber.equal(amountToDeactivate);
 | 
			
		||||
            }
 | 
			
		||||
            ///// 7 REACTIVATE SOME STAKE /////
 | 
			
		||||
            await stakingWrapper.activateAndDelegateStakeAsync(owner, poolId, amountToReactivate);
 | 
			
		||||
            {
 | 
			
		||||
                // check total stake balance didn't change
 | 
			
		||||
                const totalStake = await stakingWrapper.getTotalStakeAsync(owner);
 | 
			
		||||
                expect(totalStake).to.be.bignumber.equal(amountToDelegate); 
 | 
			
		||||
                // check delegated stake balance for owner
 | 
			
		||||
                const stakeDelegatedByOwner = await stakingWrapper.getStakeDelegatedByOwnerAsync(owner);
 | 
			
		||||
                expect(stakeDelegatedByOwner).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate).plus(amountToReactivate));
 | 
			
		||||
                // check delegated balance to pool by owner
 | 
			
		||||
                const stakeDelegatedToPoolByOwner = await stakingWrapper.getStakeDelegatedToPoolByOwnerAsync(poolId, owner);
 | 
			
		||||
                expect(stakeDelegatedToPoolByOwner).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate).plus(amountToReactivate));
 | 
			
		||||
                // checktotal amount delegated to pool
 | 
			
		||||
                const stakeDelegatedToPool = await stakingWrapper.getStakeDelegatedToPoolAsync(poolId);
 | 
			
		||||
                expect(stakeDelegatedToPool).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate).plus(amountToReactivate));
 | 
			
		||||
                // check timelocked stake is no longer activated
 | 
			
		||||
                const activatedStakeBalance = await stakingWrapper.getActivatedStakeAsync(owner);
 | 
			
		||||
                expect(activatedStakeBalance).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate).plus(amountToReactivate)); 
 | 
			
		||||
                // check that timelocked stake is deactivated
 | 
			
		||||
                const deactivatedStakeBalance = await stakingWrapper.getDeactivatedStakeAsync(owner);
 | 
			
		||||
                expect(deactivatedStakeBalance).to.be.bignumber.equal(amountToDeactivate.minus(amountToReactivate)); 
 | 
			
		||||
                // check amount that is timelocked
 | 
			
		||||
                const timelockedStakeBalance = await stakingWrapper.getTimelockedStakeAsync(owner);
 | 
			
		||||
                expect(timelockedStakeBalance).to.be.bignumber.equal(0);
 | 
			
		||||
                // check that timelocked stake cannot be withdrawn
 | 
			
		||||
                const withdrawableStakeBalance = await stakingWrapper.getWithdrawableStakeAsync(owner);
 | 
			
		||||
                expect(withdrawableStakeBalance).to.be.bignumber.equal(amountToDeactivate.minus(amountToReactivate));
 | 
			
		||||
                // check that timelocked stake cannot be reactivated
 | 
			
		||||
                const activatableStakeBalance = await stakingWrapper.getActivatableStakeAsync(owner);
 | 
			
		||||
                expect(activatableStakeBalance).to.be.bignumber.equal(amountToDeactivate.minus(amountToReactivate));
 | 
			
		||||
            }
 | 
			
		||||
            ///// 8 WITHDRAW SOME STAKE /////
 | 
			
		||||
            await stakingWrapper.withdrawAsync(owner, amountToWithdraw);
 | 
			
		||||
            {
 | 
			
		||||
                // check total stake balance didn't change
 | 
			
		||||
                const totalStake = await stakingWrapper.getTotalStakeAsync(owner);
 | 
			
		||||
                expect(totalStake).to.be.bignumber.equal(amountToDelegate.minus(amountToWithdraw)); 
 | 
			
		||||
                // check delegated stake balance for owner
 | 
			
		||||
                const stakeDelegatedByOwner = await stakingWrapper.getStakeDelegatedByOwnerAsync(owner);
 | 
			
		||||
                expect(stakeDelegatedByOwner).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate).plus(amountToReactivate));
 | 
			
		||||
                // check delegated balance to pool by owner
 | 
			
		||||
                const stakeDelegatedToPoolByOwner = await stakingWrapper.getStakeDelegatedToPoolByOwnerAsync(poolId, owner);
 | 
			
		||||
                expect(stakeDelegatedToPoolByOwner).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate).plus(amountToReactivate));
 | 
			
		||||
                // checktotal amount delegated to pool
 | 
			
		||||
                const stakeDelegatedToPool = await stakingWrapper.getStakeDelegatedToPoolAsync(poolId);
 | 
			
		||||
                expect(stakeDelegatedToPool).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate).plus(amountToReactivate));
 | 
			
		||||
                // check timelocked stake is no longer activated
 | 
			
		||||
                const activatedStakeBalance = await stakingWrapper.getActivatedStakeAsync(owner);
 | 
			
		||||
                expect(activatedStakeBalance).to.be.bignumber.equal(amountToDelegate.minus(amountToDeactivate).plus(amountToReactivate)); 
 | 
			
		||||
                // check that timelocked stake is deactivated
 | 
			
		||||
                const deactivatedStakeBalance = await stakingWrapper.getDeactivatedStakeAsync(owner);
 | 
			
		||||
                expect(deactivatedStakeBalance).to.be.bignumber.equal(amountToDeactivate.minus(amountToReactivate).minus(amountToWithdraw)); 
 | 
			
		||||
                // check amount that is timelocked
 | 
			
		||||
                const timelockedStakeBalance = await stakingWrapper.getTimelockedStakeAsync(owner);
 | 
			
		||||
                expect(timelockedStakeBalance).to.be.bignumber.equal(0);
 | 
			
		||||
                // check that timelocked stake cannot be withdrawn
 | 
			
		||||
                const withdrawableStakeBalance = await stakingWrapper.getWithdrawableStakeAsync(owner);
 | 
			
		||||
                expect(withdrawableStakeBalance).to.be.bignumber.equal(amountToDeactivate.minus(amountToReactivate).minus(amountToWithdraw));
 | 
			
		||||
                // check that timelocked stake cannot be reactivated
 | 
			
		||||
                const activatableStakeBalance = await stakingWrapper.getActivatableStakeAsync(owner);
 | 
			
		||||
                expect(activatableStakeBalance).to.be.bignumber.equal(amountToDeactivate.minus(amountToReactivate).minus(amountToWithdraw));
 | 
			
		||||
                // check zrx vault balance
 | 
			
		||||
                const vaultBalance = await stakingWrapper.getZrxVaultBalance(owner);
 | 
			
		||||
                expect(vaultBalance).to.be.bignumber.equal(amountToDelegate.minus(amountToWithdraw));
 | 
			
		||||
                // check zrx token balances
 | 
			
		||||
                const zrxTokenBalanceOfVaultAfterStaking = await stakingWrapper.getZrxTokenBalanceOfZrxVault();
 | 
			
		||||
                expect(zrxTokenBalanceOfVaultAfterStaking).to.be.bignumber.equal(amountToDelegate.minus(amountToWithdraw));
 | 
			
		||||
                const zrxTokenBalanceOfStakerAfterStaking = await stakingWrapper.getZrxTokenBalance(owner);
 | 
			
		||||
                expect(zrxTokenBalanceOfStakerAfterStaking).to.be.bignumber.equal(zrxTokenBalanceOfStakerBeforeStaking.minus(amountToDelegate).plus(amountToWithdraw));
 | 
			
		||||
            }
 | 
			
		||||
            // run test
 | 
			
		||||
            const delegator = new DelegatorActor(stakers[0], stakingWrapper);
 | 
			
		||||
            await delegator.depositAndDelegateAsync(poolId, amountToDelegate);
 | 
			
		||||
            await delegator.deactivateAndTimelockDelegatedStakeAsync(poolId, amountToDeactivate);
 | 
			
		||||
            // note - we cannot re-activate this timelocked stake until at least one full timelock period has passed.
 | 
			
		||||
            //        attempting to do so should revert.
 | 
			
		||||
            await delegator.activateStakeAsync(amountToReactivate, RevertReason.InsufficientBalance);
 | 
			
		||||
            await delegator.skipToNextTimelockPeriodAsync();
 | 
			
		||||
            await delegator.activateStakeAsync(amountToReactivate, RevertReason.InsufficientBalance);
 | 
			
		||||
            await delegator.skipToNextTimelockPeriodAsync();
 | 
			
		||||
            // this forces the internal state to update; it is not necessary to activate stake, but
 | 
			
		||||
            // allows us to check that state is updated correctly after a timelock period rolls over.
 | 
			
		||||
            await delegator.forceTimelockSyncAsync();
 | 
			
		||||
            // now we can activate stake
 | 
			
		||||
            await delegator.activateAndDelegateStakeAsync(poolId, amountToReactivate);
 | 
			
		||||
            await delegator.withdrawAsync(amountToWithdraw);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('Exchange Tracking', async () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -21,3 +21,9 @@ export interface StakerBalances {
 | 
			
		||||
    deactivatedStakeBalance: BigNumber;
 | 
			
		||||
    timelockedStakeBalance: BigNumber;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface DelegatorBalances extends StakerBalances {
 | 
			
		||||
    delegatedStakeBalance: BigNumber;
 | 
			
		||||
    stakeDelegatedToPoolByOwner: BigNumber[];
 | 
			
		||||
    stakeDelegatedToPool: BigNumber[];
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user