From 0d4dd5ff0d50feb26f107928ec70f55707c90d2a Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Tue, 30 Jul 2019 20:55:43 +0200 Subject: [PATCH] Appeased the linter --- contracts/utils/CHANGELOG.json | 2 +- contracts/utils/contracts/test/TestAbi.sol | 143 ++++++++++-------- contracts/utils/test/abi.ts | 7 +- packages/utils/CHANGELOG.json | 6 +- .../test/abi_encoder/evm_data_types_test.ts | 3 +- .../utils/test/abi_encoder/methods_test.ts | 25 ++- 6 files changed, 108 insertions(+), 78 deletions(-) diff --git a/contracts/utils/CHANGELOG.json b/contracts/utils/CHANGELOG.json index 91beaeb0d8..f399d3967a 100644 --- a/contracts/utils/CHANGELOG.json +++ b/contracts/utils/CHANGELOG.json @@ -10,7 +10,7 @@ "note": "Added tests for decoding log arguments when artifact dependencies are included/excluded.", "pr": 1995 }, - + { "note": "Added tests for`getABIDecodedTransactionData` and `getABIDecodedReturnData` in contract wrappers.", "pr": 2018 diff --git a/contracts/utils/contracts/test/TestAbi.sol b/contracts/utils/contracts/test/TestAbi.sol index e64b17b2db..54a7f742a7 100644 --- a/contracts/utils/contracts/test/TestAbi.sol +++ b/contracts/utils/contracts/test/TestAbi.sol @@ -22,86 +22,28 @@ pragma experimental ABIEncoderV2; contract TestAbi { + /// @dev complex input is dynamic and more difficult to decode than simple input. struct ComplexInput { uint256 foo; bytes bar; string car; } + /// @dev complex input is dynamic and more difficult to decode than simple input. struct ComplexOutput { ComplexInput input; bytes lorem; bytes ipsum; string dolor; } - - function noInputNoOutput() - public - pure - { - // NOP - require(true == true); - } - - function noInputSimpleOutput() - public - pure - returns (uint256) - { - return 1991; - } - - function simpleInputNoOutput(uint256) - public - pure - { - // NOP - require(true == true); - } - - function simpleInputSimpleOutput(uint256) - public - pure - returns (uint256) - { - return 1991; - } - - function complexInputComplexOutput(ComplexInput memory complexInput) - public - pure - returns (ComplexOutput memory) - { - return ComplexOutput({ - input: complexInput, - lorem: hex'12345678', - ipsum: hex'87654321', - dolor: "amet" - }); - } - - function multiInputMultiOutput( - uint256, - bytes memory, - string memory - ) - public - pure - returns ( - bytes memory, - bytes memory, - string memory - ) - { - return ( - hex'12345678', - hex'87654321', - "amet" - ); - } + /// @dev The fallback function calls into this contract and executes one of the above functions. + /// This allows us to test `getABIDecodedTransactionData` and `getABIDecodedReturnData` that is + /// include in contract wrappers. + // solhint-disable no-complex-fallback function () external + payable { address addr = address(this); assembly { @@ -138,4 +80,75 @@ contract TestAbi { return(0, returndatasize()) } } + + /// @dev Tests decoding when both input and output are empty. + function noInputNoOutput() + public + pure + { + // NOP + require(true == true); + } + + /// @dev Tests decoding when input is empty and output is non-empty. + function noInputSimpleOutput() + public + pure + returns (uint256) + { + return 1991; + } + + /// @dev Tests decoding when input is not empty but output is empty. + function simpleInputNoOutput(uint256) + public + pure + { + // NOP + require(true == true); + } + + /// @dev Tests decoding when both input and output are non-empty. + function simpleInputSimpleOutput(uint256) + public + pure + returns (uint256) + { + return 1991; + } + + /// @dev Tests decoding when the input and output are complex. + function complexInputComplexOutput(ComplexInput memory complexInput) + public + pure + returns (ComplexOutput memory) + { + return ComplexOutput({ + input: complexInput, + lorem: hex'12345678', + ipsum: hex'87654321', + dolor: "amet" + }); + } + + /// @dev Tests decoding when the input and output are complex and have more than one argument. + function multiInputMultiOutput( + uint256, + bytes memory, + string memory + ) + public + pure + returns ( + bytes memory, + bytes memory, + string memory + ) + { + return ( + hex'12345678', + hex'87654321', + "amet" + ); + } } diff --git a/contracts/utils/test/abi.ts b/contracts/utils/test/abi.ts index fcabea04ba..28709a3914 100644 --- a/contracts/utils/test/abi.ts +++ b/contracts/utils/test/abi.ts @@ -2,7 +2,6 @@ import { chaiSetup, provider, txDefaults, web3Wrapper } from '@0x/contracts-test import { BlockchainLifecycle } from '@0x/dev-utils'; import { BigNumber } from '@0x/utils'; import * as chai from 'chai'; -import { DecodedLogArgs, LogWithDecodedArgs } from 'ethereum-types'; import { artifacts, TestAbiContract } from '../src'; @@ -11,7 +10,7 @@ const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); -describe.only('TestAbi', () => { +describe('TestAbi', () => { let testAbi: TestAbiContract; const runTestAsync = async (contractMethod: any, input: any, output: any) => { const transaction = contractMethod.getABIEncodedTransactionData(input); @@ -64,14 +63,14 @@ describe.only('TestAbi', () => { car: 'zoom zoom', }; const output = { - input: input, + input, lorem: '0x12345678', ipsum: '0x87654321', dolor: 'amet', }; await runTestAsync(testAbi.complexInputComplexOutput, input, output); }); - it('should successfully encode/decode (complex input / complex output)', async () => { + it('should successfully encode/decode (multi-input / multi-output)', async () => { const input = [new BigNumber(1991), '0x1234', 'zoom zoom']; const output = ['0x12345678', '0x87654321', 'amet']; const transaction = testAbi.multiInputMultiOutput.getABIEncodedTransactionData( diff --git a/packages/utils/CHANGELOG.json b/packages/utils/CHANGELOG.json index de642ffb26..74af4d2f58 100644 --- a/packages/utils/CHANGELOG.json +++ b/packages/utils/CHANGELOG.json @@ -3,7 +3,11 @@ "version": "4.5.0", "changes": [ { - "note": "updated to include `strictDecode` for decoding method arguments", + "note": "Updated to include `strictDecode` for decoding method arguments", + "pr": 2018 + }, + { + "note": "Throw exception when trying to decode beyond boundaries of calldata", "pr": 2018 } ] diff --git a/packages/utils/test/abi_encoder/evm_data_types_test.ts b/packages/utils/test/abi_encoder/evm_data_types_test.ts index 41e3acf06f..9271abb263 100644 --- a/packages/utils/test/abi_encoder/evm_data_types_test.ts +++ b/packages/utils/test/abi_encoder/evm_data_types_test.ts @@ -806,7 +806,8 @@ describe('ABI Encoder: EVM Data Type Encoding/Decoding', () => { const dataType = new AbiEncoder.Int(testDataItem); const args = new BigNumber(0); const encodedArgs = dataType.encode(args, encodingRules); - const encodedArgsTruncated = encodedArgs.substr(0, 60); + const truncatedCalldataLength = 60; + const encodedArgsTruncated = encodedArgs.substr(0, truncatedCalldataLength); // Encode Args and validate result expect(() => { dataType.decode(encodedArgsTruncated); diff --git a/packages/utils/test/abi_encoder/methods_test.ts b/packages/utils/test/abi_encoder/methods_test.ts index b4e8919f2a..c167db4726 100644 --- a/packages/utils/test/abi_encoder/methods_test.ts +++ b/packages/utils/test/abi_encoder/methods_test.ts @@ -1,9 +1,9 @@ import * as chai from 'chai'; +import * as _ from 'lodash'; import 'mocha'; import { AbiEncoder, BigNumber } from '../../src/'; import { chaiSetup } from '../utils/chai_setup'; -import * as _ from 'lodash'; import * as AbiSamples from './abi_samples/method_abis'; @@ -13,7 +13,13 @@ const expect = chai.expect; describe('ABI Encoder: Method Encoding / Decoding', () => { const defaultEncodingRules: AbiEncoder.EncodingRules = { shouldOptimize: false }; // optimizer is tested separately. const defaultDecodingRules: AbiEncoder.DecodingRules = { shouldConvertStructsToObjects: false }; - const runTest = (encoder: AbiEncoder.Method, methodArgs: any, expectedEncoding: string, encodingRules: AbiEncoder.EncodingRules = defaultEncodingRules, decodingRules: AbiEncoder.DecodingRules = defaultDecodingRules) => { + const runTest = ( + encoder: AbiEncoder.Method, + methodArgs: any, + expectedEncoding: string, + encodingRules: AbiEncoder.EncodingRules = defaultEncodingRules, + decodingRules: AbiEncoder.DecodingRules = defaultDecodingRules, + ) => { // Validate encoding // note - the encoder takes an array of parameters as input; // if there is only 1 parameter then we wrap it in an array (`methodArgsAsAray`) to save code. @@ -25,12 +31,19 @@ describe('ABI Encoder: Method Encoding / Decoding', () => { const decodedValueAsArray = _.isArray(decodedValue) ? decodedValue : _.toArray(decodedValue); expect(decodedValueAsArray, 'testing `.decode`').to.be.deep.equal(methodArgsAsArray); // Validate strict decoding - const strictDecodedValue = encoder.strictDecode(encoding, decodingRules); + const strictDecodedValue = encoder.strictDecode(encoding, decodingRules); expect(strictDecodedValue, 'testing `.strictDecode`').to.be.deep.equal(methodArgs); }; it('Types with default widths', async () => { const method = new AbiEncoder.Method(AbiSamples.typesWithDefaultWidthsAbi); - const methodArgs = [new BigNumber(1), new BigNumber(-1), '0x56', [new BigNumber(1)], [new BigNumber(-1)], ['0x56']]; + const methodArgs = [ + new BigNumber(1), + new BigNumber(-1), + '0x56', + [new BigNumber(1)], + [new BigNumber(-1)], + ['0x56'], + ]; const expectedEncoding = '0x09f2b0c30000000000000000000000000000000000000000000000000000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff560000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000015600000000000000000000000000000000000000000000000000000000000000'; runTest(method, methodArgs, expectedEncoding); @@ -177,7 +190,7 @@ describe('ABI Encoder: Method Encoding / Decoding', () => { const expectedEncoding = '0x5b998f3500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000046669766500000000000000000000000000000000000000000000000000000000'; runTest(method, methodArgs, expectedEncoding); - }); + }); it('Dynamic Tuple (Object input)', async () => { const method = new AbiEncoder.Method(AbiSamples.dynamicTupleAbi); const methodArgs = [new BigNumber(5), 'five']; @@ -266,7 +279,7 @@ describe('ABI Encoder: Method Encoding / Decoding', () => { ]; const expectedEncoding = '0x4b49031c000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000000000000000000000000000000000000088000000000000000000000000000000000000000000000000000000000000009800000000000000000000000000000000000000000000000000000000000000ae0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000034746865206c6974746c6520706970696e67207069706572207069706564206120706970696e6720706970706572207061707065720000000000000000000000000000000000000000000000000000000000000000000000000000000000000081746865206b6964206b6e6f777320686f7720746f20777269746520706f656d732c20776861742063616e204920736179202d2d2049206775657373207468657265732061206c6f74204920636f756c642073617920746f2074727920746f2066696c6c2074686973206c696e6520776974682061206c6f74206f6620746578742e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000163874563783498732482743928742389723894723984700000000000000000000000000000000000000000000000000000000000000000000000000000000006e72834723982374239847239847298472489274987489742847289472394874987498478743294237434923473298472398423748923748923748923472389472894789474893742894728947389427498237432987423894723894732894723894372498237498237428934723980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027283473298473248923749238742398742398472894729843278942374982374892374892743982000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000b736f6d6520737472696e670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013736f6d6520616e6f7468657220737472696e67000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024746865726520617265206a75737420746f6f206d616e7920737472696e6773757020696e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046865726500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002079616c6c2067686f6e6e61206d616b65206d65206c6f7365206d79206d696e640000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000034746865206c6974746c6520706970696e67207069706572207069706564206120706970696e6720706970706572207061707065720000000000000000000000000000000000000000000000000000000000000000000000000000000000000081746865206b6964206b6e6f777320686f7720746f20777269746520706f656d732c20776861742063616e204920736179202d2d2049206775657373207468657265732061206c6f74204920636f756c642073617920746f2074727920746f2066696c6c2074686973206c696e6520776974682061206c6f74206f6620746578742e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f0ac511500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000081746865206b6964206b6e6f777320686f7720746f20777269746520706f656d732c20776861742063616e204920736179202d2d2049206775657373207468657265732061206c6f74204920636f756c642073617920746f2074727920746f2066696c6c2074686973206c696e6520776974682061206c6f74206f6620746578742e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d69d500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f498000000000000000000000000000000000000000000000000000000000000004e616b64686a61736a6b646861736a6b6c647368646a6168646b6a73616864616a6b73646873616a6b646873616a6b646861646a6b617368646a6b73616468616a6b646873616a6b64687361646a6b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002829384723894723843743289742389472398473289472348927489274894738427428947389facdea0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000089b51500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000746dafa5ebde1f4699f4981d3221892e41d24895000000000000000000000000000000000000000000000000000000000000004e6b73646873616a6b646873616a6b646861646a6b617368646a6b73616468616a6b646873616a6b64687361646a6b616b64686a61736a6b646861736a6b6c647368646a6168646b6a73616864616a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002829384723894398473289472348927489272384374328974238947274894738427428947389facde100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fa3150000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000089571d322189e415ebde1f4699f498d24246dafa000000000000000000000000000000000000000000000000000000000000004e73646873616a6b646873616a6b646861646a6b617368646a616b64686a61736a6b646861736a6b6c647368646a6168646b6a73616864616a6b6b73616468616a6b646873616a6b64687361646a6b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002838947238437432829384729742389472398473289472348927489274894738427428947389facdef000000000000000000000000000000000000000000000000'; - const customDecodingRules = {shouldConvertStructsToObjects: true}; // custom to improve readability + const customDecodingRules = { shouldConvertStructsToObjects: true }; // custom to improve readability runTest(method, methodArgs, expectedEncoding, defaultEncodingRules, customDecodingRules); }); });