diff options
author | Amir Bandeali <abandeali1@gmail.com> | 2018-08-15 06:39:10 +0800 |
---|---|---|
committer | Amir Bandeali <abandeali1@gmail.com> | 2018-08-22 02:47:28 +0800 |
commit | be67c25b0a3dcf2eaf91c39e4d8a8cdb1215bbe0 (patch) | |
tree | 7045a114ca79f5e572db3742015b1cb917efd598 /packages/contracts/src/2.0.0/extensions/Forwarder/MixinAssets.sol | |
parent | f53157414f144a7ea8c24126c9d75d3168228130 (diff) | |
download | dexon-sol-tools-be67c25b0a3dcf2eaf91c39e4d8a8cdb1215bbe0.tar dexon-sol-tools-be67c25b0a3dcf2eaf91c39e4d8a8cdb1215bbe0.tar.gz dexon-sol-tools-be67c25b0a3dcf2eaf91c39e4d8a8cdb1215bbe0.tar.bz2 dexon-sol-tools-be67c25b0a3dcf2eaf91c39e4d8a8cdb1215bbe0.tar.lz dexon-sol-tools-be67c25b0a3dcf2eaf91c39e4d8a8cdb1215bbe0.tar.xz dexon-sol-tools-be67c25b0a3dcf2eaf91c39e4d8a8cdb1215bbe0.tar.zst dexon-sol-tools-be67c25b0a3dcf2eaf91c39e4d8a8cdb1215bbe0.zip |
Add OrderValidator contract
Diffstat (limited to 'packages/contracts/src/2.0.0/extensions/Forwarder/MixinAssets.sol')
-rw-r--r-- | packages/contracts/src/2.0.0/extensions/Forwarder/MixinAssets.sol | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/packages/contracts/src/2.0.0/extensions/Forwarder/MixinAssets.sol b/packages/contracts/src/2.0.0/extensions/Forwarder/MixinAssets.sol new file mode 100644 index 000000000..d6a38aa6e --- /dev/null +++ b/packages/contracts/src/2.0.0/extensions/Forwarder/MixinAssets.sol @@ -0,0 +1,144 @@ +/* + + 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.4.24; + +import "../../utils/LibBytes/LibBytes.sol"; +import "../../utils/Ownable/Ownable.sol"; +import "../../tokens/ERC20Token/IERC20Token.sol"; +import "../../tokens/ERC721Token/IERC721Token.sol"; +import "./libs/LibConstants.sol"; +import "./mixins/MAssets.sol"; + + +contract MixinAssets is + Ownable, + LibConstants, + MAssets +{ + + using LibBytes for bytes; + + bytes4 constant internal ERC20_TRANSFER_SELECTOR = bytes4(keccak256("transfer(address,uint256)")); + + /// @dev Withdraws assets from this contract. The contract requires a ZRX balance in order to + /// function optimally, and this function allows the ZRX to be withdrawn by owner. It may also be + /// used to withdraw assets that were accidentally sent to this contract. + /// @param assetData Byte array encoded for the respective asset proxy. + /// @param amount Amount of ERC20 token to withdraw. + function withdrawAsset( + bytes assetData, + uint256 amount + ) + external + onlyOwner + { + transferAssetToSender(assetData, amount); + } + + /// @dev Transfers given amount of asset to sender. + /// @param assetData Byte array encoded for the respective asset proxy. + /// @param amount Amount of asset to transfer to sender. + function transferAssetToSender( + bytes memory assetData, + uint256 amount + ) + internal + { + bytes4 proxyId = assetData.readBytes4(0); + + if (proxyId == ERC20_DATA_ID) { + transferERC20Token(assetData, amount); + } else if (proxyId == ERC721_DATA_ID) { + transferERC721Token(assetData, amount); + } else { + revert("UNSUPPORTED_ASSET_PROXY"); + } + } + + /// @dev Decodes ERC20 assetData and transfers given amount to sender. + /// @param assetData Byte array encoded for the respective asset proxy. + /// @param amount Amount of asset to transfer to sender. + function transferERC20Token( + bytes memory assetData, + uint256 amount + ) + internal + { + address token = assetData.readAddress(16); + + // Transfer tokens. + // We do a raw call so we can check the success separate + // from the return data. + bool success = token.call(abi.encodeWithSelector( + ERC20_TRANSFER_SELECTOR, + msg.sender, + amount + )); + require( + success, + "TRANSFER_FAILED" + ); + + // Check return data. + // If there is no return data, we assume the token incorrectly + // does not return a bool. In this case we expect it to revert + // on failure, which was handled above. + // If the token does return data, we require that it is a single + // value that evaluates to true. + assembly { + if returndatasize { + success := 0 + if eq(returndatasize, 32) { + // First 64 bytes of memory are reserved scratch space + returndatacopy(0, 0, 32) + success := mload(0) + } + } + } + require( + success, + "TRANSFER_FAILED" + ); + } + + /// @dev Decodes ERC721 assetData and transfers given amount to sender. + /// @param assetData Byte array encoded for the respective asset proxy. + /// @param amount Amount of asset to transfer to sender. + function transferERC721Token( + bytes memory assetData, + uint256 amount + ) + internal + { + require( + amount == 1, + "INVALID_AMOUNT" + ); + // Decode asset data. + address token = assetData.readAddress(16); + uint256 tokenId = assetData.readUint256(36); + + // Perform transfer. + IERC721Token(token).transferFrom( + address(this), + msg.sender, + tokenId + ); + } +} |