/* 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 experimental ABIEncoderV2; pragma solidity ^0.5.5; contract AbiGenDummy { uint256 constant internal SOME_CONSTANT = 1234; string constant internal REVERT_REASON = "REVERT_WITH_CONSTANT"; string constant internal REQUIRE_REASON = "REQUIRE_WITH_CONSTANT"; function simplePureFunction () public pure returns (uint256 result) { return 1; } function simplePureFunctionWithInput (uint256 x) public pure returns (uint256 sum) { return 1 + x; } function pureFunctionWithConstant () public pure returns (uint256 someConstant) { return SOME_CONSTANT; } function simpleRevert () public pure { revert("SIMPLE_REVERT"); } function revertWithConstant () public pure { revert(REVERT_REASON); } function simpleRequire () public pure { require(0 > 1, "SIMPLE_REQUIRE"); } function requireWithConstant () public pure { require(0 > 1, REQUIRE_REASON); } /// @dev test that devdocs will be generated and /// that multiline devdocs will look okay /// @param hash description of some hash. Let's make this line super long to demonstrate hanging indents for method params. It has to be more than one hundred twenty columns. /// @param v some v, recovery id /// @param r ECDSA r output /// @param s ECDSA s output /// @return the signerAddress that created this signature. this line too is super long in order to demonstrate the proper hanging indentation in generated code. function ecrecoverFn(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public pure returns (address signerAddress) { bytes memory prefix = "\x19Ethereum Signed Message:\n32"; bytes32 prefixedHash = keccak256(abi.encodePacked(prefix, hash)); return ecrecover(prefixedHash, v, r, s); } // test: generated code should normalize address inputs to lowercase // add extra inputs to make sure it works with address in any position function withAddressInput(address x, uint256 a, uint256 b, address y, uint256 c) public pure returns (address z) { return x; } function acceptsBytes(bytes memory a) public pure {} /// @dev a method that accepts an array of bytes /// @param a the array of bytes being accepted function acceptsAnArrayOfBytes(bytes[] memory a) public pure {} struct Struct { bytes someBytes; uint32 anInteger; bytes[] aDynamicArrayOfBytes; string aString; } function structInput(Struct memory s) public pure {} /// @dev a method that returns a struct /// @return a Struct struct function structOutput() public pure returns(Struct memory s) { bytes[] memory byteArray = new bytes[](2); byteArray[0] = "0x123"; byteArray[1] = "0x321"; return Struct({ someBytes: "0x123", anInteger: 5, aDynamicArrayOfBytes: byteArray, aString: "abc" }); } function methodReturningArrayOfStructs() public pure returns(Struct[] memory) {} function methodAcceptingArrayOfStructs(Struct[] memory) public pure {} function methodAcceptingArrayOfArrayOfStructs(Struct[][] memory) public pure {} struct NestedStruct { Struct innerStruct; string description; } function nestedStructInput(NestedStruct memory n) public pure {} function nestedStructOutput() public pure returns(NestedStruct memory) {} struct StructNotDirectlyUsedAnywhere { uint256 aField; } struct NestedStructWithInnerStructNotUsedElsewhere { StructNotDirectlyUsedAnywhere innerStruct; } function methodUsingNestedStructWithInnerStructNotUsedElsewhere() public pure returns(NestedStructWithInnerStructNotUsedElsewhere memory) {} uint someState; function nonPureMethod() public returns(uint) { return someState += 1; } function nonPureMethodThatReturnsNothing() public { someState += 1; } function methodReturningMultipleValues() public pure returns (uint256, string memory) { return (1, "hello"); } function overloadedMethod(int a) public pure {} function overloadedMethod(string memory a) public pure {} event Withdrawal(address indexed _owner, uint _value); function withdraw(uint wad) public { emit Withdrawal(msg.sender, wad); } event SimpleEvent(bytes someBytes, string someString); function emitSimpleEvent() public { emit SimpleEvent( hex'12345678', "lorem" ); } // begin tests for `decodeTransactionData`, `decodeReturnData` /// @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; } /// @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" ); } // end tests for `decodeTransactionData`, `decodeReturnData` }