diff options
author | Amir Bandeali <abandeali1@gmail.com> | 2018-07-23 07:14:09 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-23 07:14:09 +0800 |
commit | 195d11f9d0bef49494b05198c259c7314cc9097d (patch) | |
tree | 7ff0ad80b4d5b84c365b4a8a12c321098ca4860c /packages/contracts/src | |
parent | 06f61949f93eb83ea7d6456f6bbf18cb6f6dab7a (diff) | |
parent | 9aa49e59d0b4a29fb9943fe2dcc04fd2630041b9 (diff) | |
download | dexon-0x-contracts-195d11f9d0bef49494b05198c259c7314cc9097d.tar dexon-0x-contracts-195d11f9d0bef49494b05198c259c7314cc9097d.tar.gz dexon-0x-contracts-195d11f9d0bef49494b05198c259c7314cc9097d.tar.bz2 dexon-0x-contracts-195d11f9d0bef49494b05198c259c7314cc9097d.tar.lz dexon-0x-contracts-195d11f9d0bef49494b05198c259c7314cc9097d.tar.xz dexon-0x-contracts-195d11f9d0bef49494b05198c259c7314cc9097d.tar.zst dexon-0x-contracts-195d11f9d0bef49494b05198c259c7314cc9097d.zip |
Merge pull request #877 from 0xProject/feature/contracts/removeERC721Callback
Removed receiverData and `onReceive` callback from ERC721 proxy.
Diffstat (limited to 'packages/contracts/src')
3 files changed, 25 insertions, 79 deletions
diff --git a/packages/contracts/src/2.0.0/forwarder/MixinForwarderCore.sol b/packages/contracts/src/2.0.0/forwarder/MixinForwarderCore.sol index eadeaf5ba..cb0ed5422 100644 --- a/packages/contracts/src/2.0.0/forwarder/MixinForwarderCore.sol +++ b/packages/contracts/src/2.0.0/forwarder/MixinForwarderCore.sol @@ -40,7 +40,7 @@ contract MixinForwarderCore is MForwarderCore { bytes4 constant internal ERC20_DATA_ID = bytes4(keccak256("ERC20Token(address)")); - bytes4 constant internal ERC721_DATA_ID = bytes4(keccak256("ERC721Token(address,uint256,bytes)")); + bytes4 constant internal ERC721_DATA_ID = bytes4(keccak256("ERC721Token(address,uint256)")); uint256 constant internal MAX_UINT = 2**256 - 1; constructor () diff --git a/packages/contracts/src/2.0.0/forwarder/MixinTransfer.sol b/packages/contracts/src/2.0.0/forwarder/MixinTransfer.sol index 6c49330f2..bebfc976b 100644 --- a/packages/contracts/src/2.0.0/forwarder/MixinTransfer.sol +++ b/packages/contracts/src/2.0.0/forwarder/MixinTransfer.sol @@ -109,12 +109,10 @@ contract MixinTransfer is // Decode asset data. address token = assetData.readAddress(16); uint256 tokenId = assetData.readUint256(36); - bytes memory receiverData = assetData.readBytesWithLength(100); - IERC721Token(token).safeTransferFrom( + IERC721Token(token).transferFrom( address(this), to, - tokenId, - receiverData + tokenId ); } } diff --git a/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC721Proxy.sol b/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC721Proxy.sol index 1f9958b43..53f5a14e0 100644 --- a/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC721Proxy.sol +++ b/packages/contracts/src/2.0.0/protocol/AssetProxy/ERC721Proxy.sol @@ -26,7 +26,7 @@ contract ERC721Proxy is MixinAuthorizable { // Id of this proxy. - bytes4 constant internal PROXY_ID = bytes4(keccak256("ERC721Token(address,uint256,bytes)")); + bytes4 constant internal PROXY_ID = bytes4(keccak256("ERC721Token(address,uint256)")); // solhint-disable-next-line payable-fallback function () @@ -83,19 +83,15 @@ contract ERC721Proxy is // WARNING: The ABIv2 specification allows additional padding between // the Params and Data section. This will result in a larger // offset to assetData. - + // Asset data itself is encoded as follows: // // | Area | Offset | Length | Contents | // |----------|--------|---------|-------------------------------------| // | Header | 0 | 4 | function selector | - // | Params | | 3 * 32 | function parameters: | + // | Params | | 2 * 32 | function parameters: | // | | 4 | 12 + 20 | 1. token address | // | | 36 | | 2. tokenId | - // | | 68 | | 3. offset to receiverData (*) | - // | Data | | | receiverData: | - // | | 100 | 32 | receiverData Length | - // | | 132 | ** | receiverData Contents | // We construct calldata for the `token.safeTransferFrom` ABI. // The layout of this calldata is in the table below. @@ -103,14 +99,10 @@ contract ERC721Proxy is // | Area | Offset | Length | Contents | // |----------|--------|---------|-------------------------------------| // | Header | 0 | 4 | function selector | - // | Params | | 4 * 32 | function parameters: | + // | Params | | 3 * 32 | function parameters: | // | | 4 | | 1. from | // | | 36 | | 2. to | // | | 68 | | 3. tokenId | - // | | 100 | | 4. offset to receiverData (*) | - // | Data | | | receiverData: | - // | | 132 | 32 | receiverData Length | - // | | 164 | ** | receiverData Contents | // There exists only 1 of each token. // require(amount == 1, "INVALID_AMOUNT") @@ -122,76 +114,32 @@ contract ERC721Proxy is mstore(96, 0) revert(0, 100) } - - // Require assetData to be at least 132 bytes - let offset := calldataload(4) - if lt(calldataload(add(offset, 4)), 132) { - // Revert with `Error("LENGTH_GREATER_THAN_131_REQUIRED")` - mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) - mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000) - mstore(64, 0x000000204c454e4754485f475245415445525f5448414e5f3133315f52455155) - mstore(96, 0x4952454400000000000000000000000000000000000000000000000000000000) - revert(0, 100) - } - - /////// Setup State /////// - // `cdStart` is the start of the calldata for - // `token.safeTransferFrom` (equal to free memory ptr). - let cdStart := mload(64) - // `dataAreaLength` is the total number of words - // needed to store `receiverData` - // As-per the ABI spec, this value is padded up to - // the nearest multiple of 32, - // and includes 32-bytes for length. - // It's calculated as folows: - // - Unpadded length in bytes = `mload(receiverData) + 32` - // - Add 31 to convert rounding down to rounding up. - // Combined with the previous and this is `63`. - // - Round down to nearest multiple of 32 by clearing - // bits 0x1F. This is done with `and` and a mask. /////// Setup Header Area /////// // This area holds the 4-byte `transferFromSelector`. // Any trailing data in transferFromSelector will be // overwritten in the next `mstore` call. - mstore(cdStart, 0xb88d4fde00000000000000000000000000000000000000000000000000000000) + mstore(0, 0x23b872dd00000000000000000000000000000000000000000000000000000000) /////// Setup Params Area /////// - // Each parameter is padded to 32-bytes. - // The entire Params Area is 128 bytes. - // Notes: - // 1. A 20-byte mask is applied to addresses - // to zero-out the unused bytes. - // 2. The offset to `receiverData` is the length - // of the Params Area (128 bytes). - - let length := calldataload(add(offset, 136)) - let token := calldataload(add(offset, 40)) - - // Round length up to multiple of 32 - length := and(add(length, 31), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0) - - // Copy `from` and `to` - calldatacopy(add(cdStart, 4), 36, 64) - - // TokenId - mstore(add(cdStart, 68), calldataload(add(offset, 72))) - - // Offset to receiverData - mstore(add(cdStart, 100), 128) - - // receiverData (including length) - calldatacopy(add(cdStart, 132), add(offset, 136), add(length, 32)) - - /////// Call `token.safeTransferFrom` using the calldata /////// + // We copy the fields `from` and `to` in bulk + // from our own calldata to the new calldata. + calldatacopy(4, 36, 64) + + // Copy `tokenId` field from our own calldata to the new calldata. + let assetDataOffset := calldataload(4) + calldatacopy(68, add(assetDataOffset, 72), 32) + + /////// Call `token.transferFrom` using the calldata /////// + let token := calldataload(add(assetDataOffset, 40)) let success := call( - gas, // forward all gas - token, // call address of token contract - 0, // don't send any ETH - cdStart, // pointer to start of input - add(length, 164), // length of input - 0, // write output to null - 0 // output size is 0 bytes + gas, // forward all gas + token, // call address of token contract + 0, // don't send any ETH + 0, // pointer to start of input + 100, // length of input + 0, // write output to null + 0 // output size is 0 bytes ) if success { return(0, 0) |