MixinVaultCore unit tests

This commit is contained in:
Michael Zhu
2019-09-16 10:25:41 -07:00
parent 314d1b9873
commit 49d223f344
7 changed files with 156 additions and 9 deletions

View File

@@ -0,0 +1,44 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
import "../src/vaults/MixinVaultCore.sol";
// solhint-disable no-empty-blocks
contract TestMixinVaultCore is
MixinVaultCore
{
function assertStakingProxy()
external
view
onlyStakingProxy
{}
function assertInCatastrophicFailure()
external
view
onlyInCatastrophicFailure
{}
function assertNotInCatastrophicFailure()
external
view
onlyNotInCatastrophicFailure
{}
}

View File

@@ -37,7 +37,7 @@
},
"config": {
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
"abis": "./generated-artifacts/@(EthVault|IEthVault|IStaking|IStakingEvents|IStakingPoolRewardVault|IStakingProxy|IStorage|IStorageInit|IStructs|IVaultCore|IZrxVault|LibCobbDouglas|LibFixedMath|LibFixedMathRichErrors|LibProxy|LibSafeDowncast|LibStakingRichErrors|MixinConstants|MixinCumulativeRewards|MixinDeploymentConstants|MixinExchangeFees|MixinExchangeManager|MixinParams|MixinScheduler|MixinStake|MixinStakeBalances|MixinStakeStorage|MixinStakingPool|MixinStakingPoolMakers|MixinStakingPoolModifiers|MixinStakingPoolRewards|MixinStorage|MixinVaultCore|ReadOnlyProxy|Staking|StakingPoolRewardVault|StakingProxy|TestCobbDouglas|TestCumulativeRewardTracking|TestInitTarget|TestLibFixedMath|TestLibProxy|TestLibProxyReceiver|TestLibSafeDowncast|TestProtocolFees|TestProtocolFeesERC20Proxy|TestStaking|TestStakingProxy|TestStorageLayout|ZrxVault).json"
"abis": "./generated-artifacts/@(EthVault|IEthVault|IStaking|IStakingEvents|IStakingPoolRewardVault|IStakingProxy|IStorage|IStorageInit|IStructs|IVaultCore|IZrxVault|LibCobbDouglas|LibFixedMath|LibFixedMathRichErrors|LibProxy|LibSafeDowncast|LibStakingRichErrors|MixinConstants|MixinCumulativeRewards|MixinDeploymentConstants|MixinExchangeFees|MixinExchangeManager|MixinParams|MixinScheduler|MixinStake|MixinStakeBalances|MixinStakeStorage|MixinStakingPool|MixinStakingPoolMakers|MixinStakingPoolModifiers|MixinStakingPoolRewards|MixinStorage|MixinVaultCore|ReadOnlyProxy|Staking|StakingPoolRewardVault|StakingProxy|TestCobbDouglas|TestCumulativeRewardTracking|TestInitTarget|TestLibFixedMath|TestLibProxy|TestLibProxyReceiver|TestLibSafeDowncast|TestMixinVaultCore|TestProtocolFees|TestProtocolFeesERC20Proxy|TestStaking|TestStakingProxy|TestStorageLayout|ZrxVault).json"
},
"repository": {
"type": "git",

View File

@@ -49,6 +49,7 @@ import * as TestLibFixedMath from '../generated-artifacts/TestLibFixedMath.json'
import * as TestLibProxy from '../generated-artifacts/TestLibProxy.json';
import * as TestLibProxyReceiver from '../generated-artifacts/TestLibProxyReceiver.json';
import * as TestLibSafeDowncast from '../generated-artifacts/TestLibSafeDowncast.json';
import * as TestMixinVaultCore from '../generated-artifacts/TestMixinVaultCore.json';
import * as TestProtocolFees from '../generated-artifacts/TestProtocolFees.json';
import * as TestProtocolFeesERC20Proxy from '../generated-artifacts/TestProtocolFeesERC20Proxy.json';
import * as TestStaking from '../generated-artifacts/TestStaking.json';
@@ -101,6 +102,7 @@ export const artifacts = {
TestLibProxy: TestLibProxy as ContractArtifact,
TestLibProxyReceiver: TestLibProxyReceiver as ContractArtifact,
TestLibSafeDowncast: TestLibSafeDowncast as ContractArtifact,
TestMixinVaultCore: TestMixinVaultCore as ContractArtifact,
TestProtocolFees: TestProtocolFees as ContractArtifact,
TestProtocolFeesERC20Proxy: TestProtocolFeesERC20Proxy as ContractArtifact,
TestStaking: TestStaking as ContractArtifact,

View File

@@ -47,6 +47,7 @@ export * from '../generated-wrappers/test_lib_fixed_math';
export * from '../generated-wrappers/test_lib_proxy';
export * from '../generated-wrappers/test_lib_proxy_receiver';
export * from '../generated-wrappers/test_lib_safe_downcast';
export * from '../generated-wrappers/test_mixin_vault_core';
export * from '../generated-wrappers/test_protocol_fees';
export * from '../generated-wrappers/test_protocol_fees_erc20_proxy';
export * from '../generated-wrappers/test_staking';

View File

@@ -0,0 +1,99 @@
import { blockchainTests, expect, filterLogsToArguments } from '@0x/contracts-test-utils';
import { StakingRevertErrors } from '@0x/order-utils';
import { OwnableRevertErrors } from '@0x/utils';
import { constants } from '../utils/constants';
import {
artifacts,
TestMixinVaultCoreContract,
TestMixinVaultCoreInCatastrophicFailureModeEventArgs,
TestMixinVaultCoreStakingProxySetEventArgs,
} from '../../src';
blockchainTests.resets('MixinVaultCore', env => {
let owner: string;
let nonOwnerAddresses: string[];
let testContract: TestMixinVaultCoreContract;
before(async () => {
[owner, ...nonOwnerAddresses] = await env.getAccountAddressesAsync();
testContract = await TestMixinVaultCoreContract.deployFrom0xArtifactAsync(
artifacts.TestMixinVaultCore,
env.provider,
env.txDefaults,
artifacts,
);
});
describe('Set staking proxy', () => {
async function testAssertStakingProxyAsync(callerAddress: string): Promise<void> {
const tx = testContract.assertStakingProxy.callAsync({ from: callerAddress });
const expectedError = new StakingRevertErrors.OnlyCallableByStakingContractError(callerAddress);
expect(tx).to.revertWith(expectedError);
}
it('Owner can set staking proxy', async () => {
const newAddress = nonOwnerAddresses[0];
const receipt = await testContract.setStakingProxy.awaitTransactionSuccessAsync(newAddress, {
from: owner,
});
const eventArgs = filterLogsToArguments<TestMixinVaultCoreStakingProxySetEventArgs>(
receipt.logs,
'StakingProxySet',
);
expect(eventArgs.length).to.equal(1);
expect(eventArgs[0].stakingProxyAddress).to.equal(newAddress);
expect(await testContract.stakingProxyAddress.callAsync()).to.equal(newAddress);
// The new staking proxy address should be able to pass the modifier check
await testContract.assertStakingProxy.callAsync({ from: newAddress });
return testAssertStakingProxyAsync(owner);
});
it('Non-owner address cannot set staking proxy', async () => {
const notOwner = nonOwnerAddresses[0];
const newAddress = nonOwnerAddresses[1];
const tx = testContract.setStakingProxy.awaitTransactionSuccessAsync(newAddress, {
from: notOwner,
});
const expectedError = new OwnableRevertErrors.OnlyOwnerError(notOwner);
expect(tx).to.revertWith(expectedError);
expect(await testContract.stakingProxyAddress.callAsync()).to.equal(constants.NIL_ADDRESS);
return testAssertStakingProxyAsync(newAddress);
});
});
describe('Catastrophic failure mode', () => {
async function testCatastrophicFailureModeAsync(isInCatastrophicFailure: boolean): Promise<void> {
const [expectToSucceed, expectToRevert] = isInCatastrophicFailure
? [testContract.assertInCatastrophicFailure, testContract.assertNotInCatastrophicFailure]
: [testContract.assertNotInCatastrophicFailure, testContract.assertInCatastrophicFailure];
const expectedError = isInCatastrophicFailure
? new StakingRevertErrors.OnlyCallableIfNotInCatastrophicFailureError()
: new StakingRevertErrors.OnlyCallableIfInCatastrophicFailureError();
await expectToSucceed.callAsync();
expect(expectToRevert.callAsync()).to.revertWith(expectedError);
expect(await testContract.isInCatastrophicFailure.callAsync()).to.equal(isInCatastrophicFailure);
}
it('Owner can turn on catastrophic failure mode', async () => {
await testCatastrophicFailureModeAsync(false);
const receipt = await testContract.enterCatastrophicFailure.awaitTransactionSuccessAsync({ from: owner });
const eventArgs = filterLogsToArguments<TestMixinVaultCoreInCatastrophicFailureModeEventArgs>(
receipt.logs,
'InCatastrophicFailureMode',
);
expect(eventArgs.length).to.equal(1);
expect(eventArgs[0].sender).to.equal(owner);
return testCatastrophicFailureModeAsync(true);
});
it('Non-owner cannot turn on catastrophic failure mode', async () => {
await testCatastrophicFailureModeAsync(false);
const tx = testContract.enterCatastrophicFailure.awaitTransactionSuccessAsync({
from: nonOwnerAddresses[0],
});
expect(tx).to.revertWith(new OwnableRevertErrors.OnlyOwnerError());
return testCatastrophicFailureModeAsync(false);
});
});
});

View File

@@ -1,6 +1,6 @@
import { ERC20Wrapper } from '@0x/contracts-asset-proxy';
import { artifacts as erc20Artifacts, DummyERC20TokenContract } from '@0x/contracts-erc20';
import { BlockchainTestsEnvironment, constants, txDefaults } from '@0x/contracts-test-utils';
import { BlockchainTestsEnvironment, constants } from '@0x/contracts-test-utils';
import { BigNumber, logUtils } from '@0x/utils';
import { Web3Wrapper } from '@0x/web3-wrapper';
import { ContractArtifact, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
@@ -131,7 +131,7 @@ export class StakingApiWrapper {
stakingProxyContract.address,
env.provider,
{
...txDefaults,
...env.txDefaults,
from: ownerAddress,
to: stakingProxyContract.address,
gas: 3e6,
@@ -162,35 +162,35 @@ export async function deployAndConfigureContractsAsync(
const stakingContract = await StakingContract.deployFrom0xArtifactAsync(
customStakingArtifact !== undefined ? customStakingArtifact : artifacts.Staking,
env.provider,
txDefaults,
env.txDefaults,
artifacts,
);
// deploy read-only proxy
const readOnlyProxyContract = await ReadOnlyProxyContract.deployFrom0xArtifactAsync(
artifacts.ReadOnlyProxy,
env.provider,
txDefaults,
env.txDefaults,
artifacts,
);
// deploy eth vault
const ethVaultContract = await EthVaultContract.deployFrom0xArtifactAsync(
artifacts.EthVault,
env.provider,
txDefaults,
env.txDefaults,
artifacts,
);
// deploy reward vault
const rewardVaultContract = await StakingPoolRewardVaultContract.deployFrom0xArtifactAsync(
artifacts.StakingPoolRewardVault,
env.provider,
txDefaults,
env.txDefaults,
artifacts,
);
// deploy zrx vault
const zrxVaultContract = await ZrxVaultContract.deployFrom0xArtifactAsync(
artifacts.ZrxVault,
env.provider,
txDefaults,
env.txDefaults,
artifacts,
erc20ProxyContract.address,
zrxTokenContract.address,
@@ -199,7 +199,7 @@ export async function deployAndConfigureContractsAsync(
const stakingProxyContract = await StakingProxyContract.deployFrom0xArtifactAsync(
artifacts.StakingProxy,
env.provider,
txDefaults,
env.txDefaults,
artifacts,
stakingContract.address,
readOnlyProxyContract.address,

View File

@@ -47,6 +47,7 @@
"generated-artifacts/TestLibProxy.json",
"generated-artifacts/TestLibProxyReceiver.json",
"generated-artifacts/TestLibSafeDowncast.json",
"generated-artifacts/TestMixinVaultCore.json",
"generated-artifacts/TestProtocolFees.json",
"generated-artifacts/TestProtocolFeesERC20Proxy.json",
"generated-artifacts/TestStaking.json",