diff --git a/contracts/staking/contracts/src/vaults/ZrxVault.sol b/contracts/staking/contracts/src/vaults/ZrxVault.sol index 660387ccf9..8adae29b00 100644 --- a/contracts/staking/contracts/src/vaults/ZrxVault.sol +++ b/contracts/staking/contracts/src/vaults/ZrxVault.sol @@ -21,6 +21,7 @@ pragma solidity ^0.5.5; import "../interfaces/IVault.sol"; import "../interfaces/IAssetProxy.sol"; import "@0x/contracts-utils/contracts/src/SafeMath.sol"; +import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; import "./MixinVaultCore.sol"; @@ -35,12 +36,19 @@ contract ZrxVault is IAssetProxy internal erc20Proxy; + IERC20Token internal zrxToken; + bytes internal zrxAssetData; - constructor(address _erc20ProxyAddress, bytes memory _zrxAssetData) + constructor( + address _erc20ProxyAddress, + address _zrxTokenAddress, + bytes memory _zrxAssetData + ) public { erc20Proxy = IAssetProxy(_erc20ProxyAddress); + zrxToken = IERC20Token(_zrxTokenAddress); zrxAssetData = _zrxAssetData; } @@ -98,9 +106,7 @@ contract ZrxVault is internal { // withdraw ZRX to owner - erc20Proxy.transferFrom( - zrxAssetData, - address(this), + zrxToken.transfer( owner, amount ); diff --git a/contracts/staking/test/core_test.ts b/contracts/staking/test/core_test.ts index 21ab3b3954..fad98a2ea8 100644 --- a/contracts/staking/test/core_test.ts +++ b/contracts/staking/test/core_test.ts @@ -14,12 +14,6 @@ import * as chai from 'chai'; import { LogWithDecodedArgs } from 'ethereum-types'; import * as _ from 'lodash'; -import { - artifacts, - StakingContract, - ZrxVaultContract -} from '../src'; - import { StakingWrapper } from './utils/staking_wrapper'; import { ERC20Wrapper, ERC20ProxyContract } from '@0x/contracts-asset-proxy'; @@ -70,28 +64,49 @@ describe('Staking Core', () => { await blockchainLifecycle.revertAsync(); }); describe('end-to-end tests', () => { - it('staking', async () => { - // setup tets parameters - const amount = stakingWrapper.toBaseUnitAmount(10); + it('staking/unstaking', async () => { + ///// 1/3 SETUP TEST PARAMETERS ///// + const amountToStake = stakingWrapper.toBaseUnitAmount(10); + const amountToUnstake = stakingWrapper.toBaseUnitAmount(5); // 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(stakers[0]); - expect(zrxTokenBalanceOfStakerBeforeStaking).to.be.bignumber.gte(amount); - // mint stake - const stakeMinted = await stakingWrapper.stake(stakers[0], amount); - expect(stakeMinted).to.be.bignumber.equal(amount); - // check stake balance after minting - const stakeBalance = await stakingWrapper.getStakeBalance(stakers[0]); - expect(stakeBalance).to.be.bignumber.equal(amount); - // check zrx vault balance - const vaultBalance = await stakingWrapper.getZrxVaultBalance(stakers[0]); - expect(vaultBalance).to.be.bignumber.equal(amount); - // check zrx token balances - const zrxTokenBalanceOfVaultAfterStaking = await stakingWrapper.getZrxTokenBalanceOfZrxVault(); - expect(zrxTokenBalanceOfVaultAfterStaking).to.be.bignumber.equal(amount); - const zrxTokenBalanceOfStakerAfterStaking = await stakingWrapper.getZrxTokenBalance(stakers[0]); - expect(zrxTokenBalanceOfStakerAfterStaking).to.be.bignumber.equal(zrxTokenBalanceOfStakerBeforeStaking.minus(amount)); + expect(zrxTokenBalanceOfStakerBeforeStaking).to.be.bignumber.gte(amountToStake); + ///// 2/3 STAKE ZRX ///// + { + // mint stake + const stakeMinted = await stakingWrapper.stake(stakers[0], amountToStake); + expect(stakeMinted).to.be.bignumber.equal(amountToStake); + // check stake balance after minting + const stakeBalance = await stakingWrapper.getStakeBalance(stakers[0]); + expect(stakeBalance).to.be.bignumber.equal(amountToStake); + // check zrx vault balance + const vaultBalance = await stakingWrapper.getZrxVaultBalance(stakers[0]); + expect(vaultBalance).to.be.bignumber.equal(amountToStake); + // check zrx token balances + const zrxTokenBalanceOfVaultAfterStaking = await stakingWrapper.getZrxTokenBalanceOfZrxVault(); + expect(zrxTokenBalanceOfVaultAfterStaking).to.be.bignumber.equal(amountToStake); + const zrxTokenBalanceOfStakerAfterStaking = await stakingWrapper.getZrxTokenBalance(stakers[0]); + expect(zrxTokenBalanceOfStakerAfterStaking).to.be.bignumber.equal(zrxTokenBalanceOfStakerBeforeStaking.minus(amountToStake)); + } + ///// 3/3 UNSTAKE ZRX ///// + { + // unstake + const stakeBurned = await stakingWrapper.unstake(stakers[0], amountToUnstake); + expect(stakeBurned).to.be.bignumber.equal(amountToUnstake); + // check stake balance after burning + const stakeBalance = await stakingWrapper.getStakeBalance(stakers[0]); + expect(stakeBalance).to.be.bignumber.equal(amountToStake.minus(amountToUnstake)); + // check zrx vault balance + const vaultBalance = await stakingWrapper.getZrxVaultBalance(stakers[0]); + expect(vaultBalance).to.be.bignumber.equal(amountToStake.minus(amountToUnstake)); + // check zrx token balances + const zrxTokenBalanceOfVaultAfterStaking = await stakingWrapper.getZrxTokenBalanceOfZrxVault(); + expect(zrxTokenBalanceOfVaultAfterStaking).to.be.bignumber.equal(amountToStake.minus(amountToUnstake)); + const zrxTokenBalanceOfStakerAfterStaking = await stakingWrapper.getZrxTokenBalance(stakers[0]); + expect(zrxTokenBalanceOfStakerAfterStaking).to.be.bignumber.equal(zrxTokenBalanceOfStakerBeforeStaking.minus(amountToStake).plus(amountToUnstake)); + } }); }); }); diff --git a/contracts/staking/test/utils/staking_wrapper.ts b/contracts/staking/test/utils/staking_wrapper.ts index e4463da366..8c020c8215 100644 --- a/contracts/staking/test/utils/staking_wrapper.ts +++ b/contracts/staking/test/utils/staking_wrapper.ts @@ -46,6 +46,7 @@ export class StakingWrapper { this._provider, txDefaults, this._erc20ProxyContract.address, + this._zrxTokenContract.address, zrxAssetData ); // configure erc20 proxy to accept calls from zrx vault @@ -65,6 +66,11 @@ export class StakingWrapper { await this.getStakingContract().stake.awaitTransactionSuccessAsync(amount, {from: holder}); return stakeMinted; } + public async unstake(holder: string, amount: BigNumber): Promise { + const stakeBurned = await this.getStakingContract().unstake.callAsync(amount, {from: holder}); + await this.getStakingContract().unstake.awaitTransactionSuccessAsync(amount, {from: holder}); + return stakeBurned; + } public async getStakeBalance(holder: string): Promise { const balance = await this.getStakingContract().getStakeBalance.callAsync(holder); return balance;