Contract wrappers: Catch empty reverts on live networks (#2433)

* `@0x/utils`: Allow strict decoding of return values.

* `@0x/base-contract`: Catch empty call reverts on live networks.
`@0x/abi-gen`: Catch empty call reverts on live networks.

* `@0x/contracts-integrations`: Add mainnet contract wrapper `callAsync()` revert behavior tests.

* `@0x/contract-wrappers`: Regenerate wrappers to catch empty reverts on live networks.

* Update CHANGELOGs

* `@0x/contracts-integrations`: Fix solidity linter errors.

* `@0x/abi-gen`: Regenerate test outputs.

* `@0x/base-contract`: Update CHANGELOG.

Co-authored-by: Lawrence Forman <me@merklejerk.com>
This commit is contained in:
Lawrence Forman
2020-01-13 15:33:45 -05:00
committed by GitHub
parent 71731d223b
commit ebd08d9c63
33 changed files with 467 additions and 39 deletions

View File

@@ -5,6 +5,7 @@
*/
import { ContractArtifact } from 'ethereum-types';
import * as TestContractWrapper from '../test/generated-artifacts/TestContractWrapper.json';
import * as TestDydxUser from '../test/generated-artifacts/TestDydxUser.json';
import * as TestEth2Dai from '../test/generated-artifacts/TestEth2Dai.json';
import * as TestEth2DaiBridge from '../test/generated-artifacts/TestEth2DaiBridge.json';
@@ -15,6 +16,7 @@ import * as TestUniswapBridge from '../test/generated-artifacts/TestUniswapBridg
import * as TestUniswapExchange from '../test/generated-artifacts/TestUniswapExchange.json';
import * as TestUniswapExchangeFactory from '../test/generated-artifacts/TestUniswapExchangeFactory.json';
export const artifacts = {
TestContractWrapper: TestContractWrapper as ContractArtifact,
TestDydxUser: TestDydxUser as ContractArtifact,
TestEth2Dai: TestEth2Dai as ContractArtifact,
TestEth2DaiBridge: TestEth2DaiBridge as ContractArtifact,

View File

@@ -0,0 +1,53 @@
import { blockchainTests, expect } from '@0x/contracts-test-utils';
import { BigNumber } from '@0x/utils';
import { TestContractWrapperContract } from './wrappers';
blockchainTests.live('Contract wrapper mainnet callAsync revert behavior tests', env => {
// Mainnet address of the `TestContractWrapper` contract.
const TEST_CONTRACT_ADDRESS = '0x3C120F51aa2360E6C7078dbc849591dd14F21405';
const REVERT_STRING = 'ERROR';
const VALID_RESULT = new BigNumber('0xf984f922a56ea9a20a32a32f0f60f2d216ff0c0a0d16c986a97a7f1897a6613b');
let testContract: TestContractWrapperContract;
before(async () => {
testContract = new TestContractWrapperContract(TEST_CONTRACT_ADDRESS, env.provider, env.txDefaults);
});
describe('callAsync()', () => {
it('can decode valid result', async () => {
const result = await testContract.returnValid().callAsync();
expect(result).to.bignumber.eq(VALID_RESULT);
});
it('can decode an empty result', async () => {
const result = await testContract.returnEmpty().callAsync();
expect(result).to.eq(undefined);
});
it('catches a string revert', async () => {
const tx = testContract.throwStringRevert().callAsync();
return expect(tx).to.revertWith(REVERT_STRING);
});
it('catches an empty revert', async () => {
const tx = testContract.throwEmptyRevert().callAsync();
return expect(tx).to.be.rejectedWith('reverted with no data');
});
it('catches invalid opcode', async () => {
const tx = testContract.throwInvalidOpcode().callAsync();
return expect(tx).to.be.rejectedWith('reverted with no data');
});
it('catches a forced empty result', async () => {
const tx = testContract.returnForcedEmpty().callAsync();
return expect(tx).to.be.rejectedWith('reverted with no data');
});
it('catches a truncated result', async () => {
const tx = testContract.returnTruncated().callAsync();
return expect(tx).to.be.rejectedWith('decode beyond the end of calldata');
});
});
});

View File

@@ -3,6 +3,7 @@
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
* -----------------------------------------------------------------------------
*/
export * from '../test/generated-wrappers/test_contract_wrapper';
export * from '../test/generated-wrappers/test_dydx_user';
export * from '../test/generated-wrappers/test_eth2_dai';
export * from '../test/generated-wrappers/test_eth2_dai_bridge';