diff options
Diffstat (limited to 'packages/contracts')
-rw-r--r-- | packages/contracts/compiler.json | 2 | ||||
-rw-r--r-- | packages/contracts/package.json | 2 | ||||
-rw-r--r-- | packages/contracts/src/utils/artifacts.ts | 2 | ||||
-rw-r--r-- | packages/contracts/src/utils/types.ts | 1 | ||||
-rw-r--r-- | packages/contracts/test/asset_proxy/decoder.ts | 2 | ||||
-rw-r--r-- | packages/contracts/test/asset_proxy/proxies.ts | 122 |
6 files changed, 126 insertions, 5 deletions
diff --git a/packages/contracts/compiler.json b/packages/contracts/compiler.json index 639849cd7..464137d9b 100644 --- a/packages/contracts/compiler.json +++ b/packages/contracts/compiler.json @@ -21,8 +21,8 @@ "contracts": [ "AssetProxyOwner", "DummyERC20Token", - "DummyERC721Token", "DummyERC721Receiver", + "DummyERC721Token", "ERC20Proxy", "ERC721Proxy", "Exchange", diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 43c33e7d3..658f5ed60 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -30,7 +30,7 @@ "test:circleci": "yarn test" }, "config": { - "abis": "../migrations/artifacts/2.0.0/@(AssetProxyOwner|DummyERC20Token|DummyERC721Token|ERC20Proxy|ERC721Proxy|Exchange|MixinAuthorizable|MultiSigWallet|MultiSigWalletWithTimeLock|TestAssetProxyDispatcher|TestLibAssetProxyDecoder|TestLibBytes|TestLibMem|TestLibs|TestSignatureValidator|TokenRegistry|Whitelist|WETH9|ZRXToken).json" + "abis": "../migrations/artifacts/2.0.0/@(AssetProxyOwner|DummyERC20Token|DummyERC721Token|DummyERC721Receiver|ERC20Proxy|ERC721Proxy|Exchange|MixinAuthorizable|MultiSigWallet|MultiSigWalletWithTimeLock|TestAssetProxyDispatcher|TestLibAssetProxyDecoder|TestLibBytes|TestLibMem|TestLibs|TestSignatureValidator|TokenRegistry|Whitelist|WETH9|ZRXToken).json" }, "repository": { "type": "git", diff --git a/packages/contracts/src/utils/artifacts.ts b/packages/contracts/src/utils/artifacts.ts index 44de43a95..a1c8483d8 100644 --- a/packages/contracts/src/utils/artifacts.ts +++ b/packages/contracts/src/utils/artifacts.ts @@ -2,6 +2,7 @@ import { ContractArtifact } from '@0xproject/sol-compiler'; import * as AssetProxyOwner from '../artifacts/AssetProxyOwner.json'; import * as DummyERC20Token from '../artifacts/DummyERC20Token.json'; +import * as DummyERC721Receiver from '../artifacts/DummyERC721Receiver.json'; import * as DummyERC721Token from '../artifacts/DummyERC721Token.json'; import * as ERC20Proxy from '../artifacts/ERC20Proxy.json'; import * as ERC721Proxy from '../artifacts/ERC721Proxy.json'; @@ -23,6 +24,7 @@ import * as ZRX from '../artifacts/ZRXToken.json'; export const artifacts = { AssetProxyOwner: (AssetProxyOwner as any) as ContractArtifact, DummyERC20Token: (DummyERC20Token as any) as ContractArtifact, + DummyERC721Receiver: (DummyERC721Receiver as any) as ContractArtifact, DummyERC721Token: (DummyERC721Token as any) as ContractArtifact, ERC20Proxy: (ERC20Proxy as any) as ContractArtifact, ERC721Proxy: (ERC721Proxy as any) as ContractArtifact, diff --git a/packages/contracts/src/utils/types.ts b/packages/contracts/src/utils/types.ts index 70abb2643..cccca5705 100644 --- a/packages/contracts/src/utils/types.ts +++ b/packages/contracts/src/utils/types.ts @@ -97,6 +97,7 @@ export enum ContractName { TestSignatureValidator = 'TestSignatureValidator', ERC20Proxy = 'ERC20Proxy', ERC721Proxy = 'ERC721Proxy', + DummyERC721Receiver = 'DummyERC721Receiver', DummyERC721Token = 'DummyERC721Token', TestLibBytes = 'TestLibBytes', Authorizable = 'Authorizable', diff --git a/packages/contracts/test/asset_proxy/decoder.ts b/packages/contracts/test/asset_proxy/decoder.ts index b35cd0d43..4416334d1 100644 --- a/packages/contracts/test/asset_proxy/decoder.ts +++ b/packages/contracts/test/asset_proxy/decoder.ts @@ -19,7 +19,7 @@ chaiSetup.configure(); const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); -describe.only('LibAssetProxyDecoder', () => { +describe('LibAssetProxyDecoder', () => { let owner: string; let testAssetProxyDecoder: TestLibAssetProxyDecoderContract; let testAddress: string; diff --git a/packages/contracts/test/asset_proxy/proxies.ts b/packages/contracts/test/asset_proxy/proxies.ts index d14280c5f..d7f27deb4 100644 --- a/packages/contracts/test/asset_proxy/proxies.ts +++ b/packages/contracts/test/asset_proxy/proxies.ts @@ -1,25 +1,37 @@ +import { LogWithDecodedArgs, ZeroEx } from '0x.js'; import { BlockchainLifecycle } from '@0xproject/dev-utils'; import { assetProxyUtils } from '@0xproject/order-utils'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; +import ethUtil = require('ethereumjs-util'); import * as _ from 'lodash'; +import { + DummyERC721ReceiverContract, + TokenReceivedContractEventArgs, +} from '../../src/contract_wrappers/generated/dummy_e_r_c721_receiver'; import { DummyERC20TokenContract } from '../../src/generated_contract_wrappers/dummy_e_r_c20_token'; import { DummyERC721TokenContract } from '../../src/generated_contract_wrappers/dummy_e_r_c721_token'; import { ERC20ProxyContract } from '../../src/generated_contract_wrappers/e_r_c20_proxy'; import { ERC721ProxyContract } from '../../src/generated_contract_wrappers/e_r_c721_proxy'; +import { artifacts } from '../../src/utils/artifacts'; import { expectRevertOrAlwaysFailingTransactionAsync } from '../../src/utils/assertions'; +import { assetProxyUtils } from '../../src/utils/asset_proxy_utils'; import { chaiSetup } from '../../src/utils/chai_setup'; import { constants } from '../../src/utils/constants'; import { ERC20Wrapper } from '../../src/utils/erc20_wrapper'; import { ERC721Wrapper } from '../../src/utils/erc721_wrapper'; -import { provider, web3Wrapper } from '../../src/utils/web3_wrapper'; +import { LogDecoder } from '../../src/utils/log_decoder'; +import { AssetProxyId } from '../../src/utils/types'; +import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper'; chaiSetup.configure(); const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); describe('Asset Transfer Proxies', () => { + const nullDataHex = '0x'; + let owner: string; let notAuthorized: string; let exchangeAddress: string; @@ -28,6 +40,7 @@ describe('Asset Transfer Proxies', () => { let zrxToken: DummyERC20TokenContract; let erc721Token: DummyERC721TokenContract; + let erc721Receiver: DummyERC721ReceiverContract; let erc20Proxy: ERC20ProxyContract; let erc721Proxy: ERC721ProxyContract; @@ -69,6 +82,20 @@ describe('Asset Transfer Proxies', () => { }), constants.AWAIT_TRANSACTION_MINED_MS, ); + + await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(exchangeAddress, { + from: owner, + }); + + erc721Receiver = await DummyERC721ReceiverContract.deployFrom0xArtifactAsync( + artifacts.DummyERC721Receiver, + provider, + txDefaults, + ); + + zeroEx = new ZeroEx(provider, { + networkId: constants.TESTRPC_NETWORK_ID, + }); }); beforeEach(async () => { await blockchainLifecycle.startAsync(); @@ -234,7 +261,7 @@ describe('Asset Transfer Proxies', () => { }); }); - describe('Transfer Proxy - ERC721', () => { + describe.only('Transfer Proxy - ERC721', () => { describe('transferFrom', () => { it('should successfully transfer tokens', async () => { // Construct metadata for ERC721 proxy @@ -262,6 +289,97 @@ describe('Asset Transfer Proxies', () => { expect(newOwnerMakerAsset).to.be.bignumber.equal(takerAddress); }); + it.only('should call onERC721Received when transferring to a smart contract', async () => { + // Construct metadata for ERC721 proxy + const encodedProxyMetadata = assetProxyUtils.encodeERC721ProxyData( + erc721Token.address, + erc721MakerTokenId, + ); + // Verify pre-condition + const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); + expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress); + // Perform a transfer from makerAddress to takerAddress + const erc20Balances = await erc20Wrapper.getBalancesAsync(); + const amount = new BigNumber(1); + const txHash = await erc721Proxy.transferFrom.sendTransactionAsync( + encodedProxyMetadata, + makerAddress, + erc721Receiver.address, + amount, + { from: exchangeAddress }, + ); + // Parse transaction logs + const tx = await zeroEx.awaitTransactionMinedAsync(txHash); + tx.logs = _.filter(tx.logs, log => log.address === erc721Receiver.address); + const logDecoder = new LogDecoder(constants.TESTRPC_NETWORK_ID); + tx.logs = _.map(tx.logs, log => logDecoder.decodeLogOrThrow(log)); + // Validate log emitted by erc721 receiver + expect(tx.logs.length).to.be.equal(1); + const tokenReceivedLog = tx.logs[0] as LogWithDecodedArgs<TokenReceivedContractEventArgs>; + expect(tokenReceivedLog.args.from).to.be.equal(makerAddress); + expect(tokenReceivedLog.args.tokenId).to.be.bignumber.equal(erc721MakerTokenId); + expect(tokenReceivedLog.args.data).to.be.equal(nullDataHex); + // Verify transfer was successful + const newOwnerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); + expect(newOwnerMakerAsset).to.be.bignumber.equal(erc721Receiver.address); + }); + + it('should call onERC721Received when transferring to a smart contract and receive extra data', async () => { + // Construct metadata for ERC721 proxy + const encodedProxyMetadata = assetProxyUtils.encodeERC721ProxyData( + erc721Token.address, + erc721MakerTokenId, + ); + // Verify pre-condition + const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); + expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress); + // Perform a transfer from makerAddress to takerAddress + const erc20Balances = await erc20Wrapper.getBalancesAsync(); + const amount = new BigNumber(1); + const txHash = await erc721Proxy.transferFrom.sendTransactionAsync( + encodedProxyMetadata, + makerAddress, + erc721Receiver.address, + amount, + { from: exchangeAddress }, + ); + // Parse transaction logs + const tx = await zeroEx.awaitTransactionMinedAsync(txHash); + tx.logs = _.filter(tx.logs, log => log.address === erc721Receiver.address); + const logDecoder = new LogDecoder(constants.TESTRPC_NETWORK_ID); + tx.logs = _.map(tx.logs, log => logDecoder.decodeLogOrThrow(log)); + // Verify erc721 receiver log emitted + console.log(tx.logs); + // Verify transfer was successful + const newOwnerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); + expect(newOwnerMakerAsset).to.be.bignumber.equal(erc721Receiver.address); + }); + + /* + it('should throw if receiving contract does not have onERC721Received', async () => { + // Construct metadata for ERC721 proxy + const encodedProxyMetadata = assetProxyUtils.encodeERC721ProxyData( + erc721Token.address, + erc721MakerTokenId, + ); + // Verify pre-condition + const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); + expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress); + // Perform a transfer from makerAddress to takerAddress + const erc20Balances = await erc20Wrapper.getBalancesAsync(); + const amount = new BigNumber(1); + await erc721Proxy.transferFrom.sendTransactionAsync( + encodedProxyMetadata, + makerAddress, + takerAddress, + amount, + { from: exchangeAddress }, + ); + // Verify transfer was successful + const newOwnerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); + expect(newOwnerMakerAsset).to.be.bignumber.equal(takerAddress); + });*/ + it('should throw if transferring 0 amount of a token', async () => { // Construct metadata for ERC721 proxy const encodedProxyMetadata = assetProxyUtils.encodeERC721ProxyData( |