diff --git a/contracts/utils/CHANGELOG.json b/contracts/utils/CHANGELOG.json index a1d6cd67db..cbe11a0e09 100644 --- a/contracts/utils/CHANGELOG.json +++ b/contracts/utils/CHANGELOG.json @@ -5,6 +5,10 @@ { "note": "Updated calls to .deploy0xArtifactAsync to include artifact dependencies.", "pr": 1995 + }, + { + "note": "Added tests for decoding log arguments when artifact dependencies are included/excluded.", + "pr": 1995 } ] }, diff --git a/contracts/utils/compiler.json b/contracts/utils/compiler.json index d132a71268..01ab211056 100644 --- a/contracts/utils/compiler.json +++ b/contracts/utils/compiler.json @@ -32,6 +32,8 @@ "src/interfaces/IOwnable.sol", "test/TestConstants.sol", "test/TestLibAddressArray.sol", - "test/TestLibBytes.sol" + "test/TestLibBytes.sol", + "test/TestLogDecoding.sol", + "test/TestLogDecodingDownstream.sol" ] } diff --git a/contracts/utils/contracts/test/TestLogDecoding.sol b/contracts/utils/contracts/test/TestLogDecoding.sol new file mode 100644 index 0000000000..b79b66200b --- /dev/null +++ b/contracts/utils/contracts/test/TestLogDecoding.sol @@ -0,0 +1,46 @@ +/* + + Copyright 2018 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.5; + +import "./TestLogDecodingDownstream.sol"; + +contract TestLogDecoding { + + /// @dev arbitrary event; fields to not matter. + event TestEvent( + uint256 foo, + bytes bar, + string car + ); + + /// @dev Emits a local event + function emitEvent() + public + { + emit TestEvent(256, hex'1234', "4321"); + } + + /// @dev Emits an event in a downstream contract + function emitEventDownstream() + public + { + TestLogDecodingDownstream testLogDecodingDownstream = new TestLogDecodingDownstream(); + ITestLogDecodingDownstream(testLogDecodingDownstream).emitEvent(); + } +} \ No newline at end of file diff --git a/contracts/utils/contracts/test/TestLogDecodingDownstream.sol b/contracts/utils/contracts/test/TestLogDecodingDownstream.sol new file mode 100644 index 0000000000..e977f93c82 --- /dev/null +++ b/contracts/utils/contracts/test/TestLogDecodingDownstream.sol @@ -0,0 +1,46 @@ +/* + + Copyright 2018 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.5; + +contract ITestLogDecodingDownstream { + + /// @dev Emits a local event + function emitEvent() external; +} + +contract TestLogDecodingDownstream is + ITestLogDecodingDownstream +{ + + /// @dev event with fields different than those in `TestLogDecoding.TestEvent` + /// Note: do not include this in the interface + /// For testing, we want to emit an event that is + /// not known by the calling contract. + event TestEvent2( + uint256 lorem, + string ipsum + ); + + /// @dev Emits a local event + function emitEvent() + external + { + emit TestEvent2(256, "4321"); + } +} \ No newline at end of file diff --git a/contracts/utils/package.json b/contracts/utils/package.json index 331a0c14e9..0b11673348 100644 --- a/contracts/utils/package.json +++ b/contracts/utils/package.json @@ -34,7 +34,7 @@ "lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol" }, "config": { - "abis": "./generated-artifacts/@(Address|IOwnable|LibBytes|Ownable|ReentrancyGuard|SafeMath|TestConstants|TestLibAddressArray|TestLibBytes).json", + "abis": "./generated-artifacts/@(Address|IOwnable|LibBytes|Ownable|ReentrancyGuard|SafeMath|TestConstants|TestLibAddressArray|TestLibBytes|TestLogDecoding|TestLogDecodingDownstream).json", "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually." }, "repository": { diff --git a/contracts/utils/src/artifacts.ts b/contracts/utils/src/artifacts.ts index 04ebb5b525..e2b2104257 100644 --- a/contracts/utils/src/artifacts.ts +++ b/contracts/utils/src/artifacts.ts @@ -14,6 +14,8 @@ import * as SafeMath from '../generated-artifacts/SafeMath.json'; import * as TestConstants from '../generated-artifacts/TestConstants.json'; import * as TestLibAddressArray from '../generated-artifacts/TestLibAddressArray.json'; import * as TestLibBytes from '../generated-artifacts/TestLibBytes.json'; +import * as TestLogDecoding from '../generated-artifacts/TestLogDecoding.json'; +import * as TestLogDecodingDownstream from '../generated-artifacts/TestLogDecodingDownstream.json'; export const artifacts = { Address: Address as ContractArtifact, LibBytes: LibBytes as ContractArtifact, @@ -22,6 +24,8 @@ export const artifacts = { SafeMath: SafeMath as ContractArtifact, IOwnable: IOwnable as ContractArtifact, TestConstants: TestConstants as ContractArtifact, - TestLibBytes: TestLibBytes as ContractArtifact, TestLibAddressArray: TestLibAddressArray as ContractArtifact, + TestLibBytes: TestLibBytes as ContractArtifact, + TestLogDecoding: TestLogDecoding as ContractArtifact, + TestLogDecodingDownstream: TestLogDecodingDownstream as ContractArtifact, }; diff --git a/contracts/utils/src/wrappers.ts b/contracts/utils/src/wrappers.ts index 91a90bec6c..be616b060f 100644 --- a/contracts/utils/src/wrappers.ts +++ b/contracts/utils/src/wrappers.ts @@ -12,3 +12,5 @@ export * from '../generated-wrappers/safe_math'; export * from '../generated-wrappers/test_constants'; export * from '../generated-wrappers/test_lib_address_array'; export * from '../generated-wrappers/test_lib_bytes'; +export * from '../generated-wrappers/test_log_decoding'; +export * from '../generated-wrappers/test_log_decoding_downstream'; diff --git a/contracts/utils/test/log_decoding.ts b/contracts/utils/test/log_decoding.ts new file mode 100644 index 0000000000..f74a72a928 --- /dev/null +++ b/contracts/utils/test/log_decoding.ts @@ -0,0 +1,70 @@ +import { chaiSetup, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils'; +import { BlockchainLifecycle } from '@0x/dev-utils'; +import { BigNumber } from '@0x/utils'; +import * as chai from 'chai'; +import { DecodedLogArgs, LogWithDecodedArgs } from 'ethereum-types'; + +import { artifacts, TestLogDecodingContract } from '../src'; + +chaiSetup.configure(); +const expect = chai.expect; + +const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); + +describe.only('TestLogDecoding', () => { + let testLogDecodingWithDependencies: TestLogDecodingContract; + let testLogDecodingDeployedWithoutDependencies: TestLogDecodingContract; + const expectedEvent = { + foo: new BigNumber(256), + bar: "0x1234", + car: "4321", + }; + const expectedDownstreamEvent = { + lorem: new BigNumber(256), + ipsum: "4321", + } + const emptyDependencyList = {}; + + before(async () => { + testLogDecodingDeployedWithoutDependencies = await TestLogDecodingContract.deployFrom0xArtifactAsync( + artifacts.TestLogDecoding, + provider, + txDefaults, + emptyDependencyList + ); + testLogDecodingWithDependencies = await TestLogDecodingContract.deployFrom0xArtifactAsync( + artifacts.TestLogDecoding, + provider, + txDefaults, + artifacts + ); + }); + beforeEach(async () => { + await blockchainLifecycle.startAsync(); + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); + }); + + describe('Decoding Log Arguments', () => { + it('should decode locally emitted event args when no dependencies are passed into wrapper', async () => { + const txReceipt = await testLogDecodingDeployedWithoutDependencies.emitEvent.awaitTransactionSuccessAsync(); + expect(txReceipt.logs.length).to.be.equal(1); + expect((txReceipt.logs[0] as LogWithDecodedArgs).args).to.be.deep.equal(expectedEvent); + }); + it('should not event args when no dependencies are passed into wrapper', async () => { + const txReceipt = await testLogDecodingDeployedWithoutDependencies.emitEventDownstream.awaitTransactionSuccessAsync(); + expect((txReceipt.logs[0] as LogWithDecodedArgs).args).to.be.undefined();//(emptyArgs); + }); + it('should decode locally emitted event args when dependencies are passed into wrapper', async () => { + const txReceipt = await testLogDecodingWithDependencies.emitEvent.awaitTransactionSuccessAsync(); + expect(txReceipt.logs.length).to.be.equal(1); + expect((txReceipt.logs[0] as LogWithDecodedArgs).args).to.be.deep.equal(expectedEvent); + }); + it('should decode downstream event args when dependencies are passed into wrapper', async () => { + const txReceipt = await testLogDecodingWithDependencies.emitEventDownstream.awaitTransactionSuccessAsync(); + expect(txReceipt.logs.length).to.be.equal(1); + expect((txReceipt.logs[0] as LogWithDecodedArgs).args).to.be.deep.equal(expectedDownstreamEvent); + }); + }); +}); diff --git a/contracts/utils/tsconfig.json b/contracts/utils/tsconfig.json index dce54b101e..bb3f9566be 100644 --- a/contracts/utils/tsconfig.json +++ b/contracts/utils/tsconfig.json @@ -11,7 +11,9 @@ "generated-artifacts/SafeMath.json", "generated-artifacts/TestConstants.json", "generated-artifacts/TestLibAddressArray.json", - "generated-artifacts/TestLibBytes.json" + "generated-artifacts/TestLibBytes.json", + "generated-artifacts/TestLogDecoding.json", + "generated-artifacts/TestLogDecodingDownstream.json" ], "exclude": ["./deploy/solc/solc_bin"] }