diff --git a/contracts/asset-proxy/contracts/src/interfaces/IChai.sol b/contracts/asset-proxy/contracts/src/interfaces/IChai.sol index 3d08116894..957a59fbc8 100644 --- a/contracts/asset-proxy/contracts/src/interfaces/IChai.sol +++ b/contracts/asset-proxy/contracts/src/interfaces/IChai.sol @@ -18,6 +18,9 @@ pragma solidity ^0.5.9; +import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; + + contract PotLike { function chi() external returns (uint256); function rho() external returns (uint256); @@ -27,8 +30,9 @@ contract PotLike { } // The actual Chai contract can be found here: https://github.com/dapphub/chai -contract IChai { - +contract IChai is + IERC20Token +{ /// @dev Withdraws Dai owned by `src` /// @param src Address that owns Dai. /// @param wad Amount of Dai to withdraw. @@ -49,4 +53,13 @@ contract IChai { function pot() external returns (PotLike); + + /// @dev Deposits Dai in exchange for Chai + /// @param dst Address to receive Chai. + /// @param wad Amount of Dai to deposit. + function join( + address dst, + uint256 wad + ) + external; } diff --git a/contracts/asset-proxy/src/index.ts b/contracts/asset-proxy/src/index.ts index 8682fe2572..eb4bdf4fd0 100644 --- a/contracts/asset-proxy/src/index.ts +++ b/contracts/asset-proxy/src/index.ts @@ -15,6 +15,7 @@ export { UniswapBridgeContract, KyberBridgeContract, ChaiBridgeContract, + IChaiContract, } from './wrappers'; export { ERC20Wrapper } from './erc20_wrapper'; diff --git a/contracts/dev-utils/contracts/src/LibAssetData.sol b/contracts/dev-utils/contracts/src/LibAssetData.sol index 69f4b4d8e0..95aa3bee26 100644 --- a/contracts/dev-utils/contracts/src/LibAssetData.sol +++ b/contracts/dev-utils/contracts/src/LibAssetData.sol @@ -254,6 +254,7 @@ contract LibAssetData is // Query allowance (bool success, bytes memory returnData) = tokenAddress.staticcall(allowanceData); allowance = success && returnData.length == 32 ? returnData.readUint256(0) : 0; + } else if (assetProxyId == IAssetData(address(0)).ERC721Token.selector) { // Get ERC721 token address and id (, address tokenAddress, uint256 tokenId) = decodeERC721AssetData(assetData); @@ -279,6 +280,7 @@ contract LibAssetData is // Allowance is 2^256 - 1 if `isApprovedForAll` returned true allowance = _MAX_UINT256; } + } else if (assetProxyId == IAssetData(address(0)).ERC1155Assets.selector) { // Get ERC1155 token address (, address tokenAddress, , , ) = decodeERC1155AssetData(assetData); @@ -293,9 +295,11 @@ contract LibAssetData is // Query allowance (bool success, bytes memory returnData) = tokenAddress.staticcall(isApprovedForAllData); allowance = success && returnData.length == 32 && returnData.readUint256(0) == 1 ? _MAX_UINT256 : 0; + } else if (assetProxyId == IAssetData(address(0)).StaticCall.selector) { // The StaticCallProxy does not require any approvals allowance = _MAX_UINT256; + } else if (assetProxyId == IAssetData(address(0)).ERC20Bridge.selector) { // Get address of ERC20 token and bridge contract (, address tokenAddress, address bridgeAddress,) = decodeERC20BridgeAssetData(assetData); @@ -307,7 +311,8 @@ contract LibAssetData is ); (bool success, bytes memory returnData) = _getChaiAddress().staticcall(allowanceData); uint256 chaiAllowance = success && returnData.length == 32 ? returnData.readUint256(0) : 0; - allowance = _convertChaiToDaiAmount(chaiAllowance); + // Dai allowance is unlimited if Chai allowance is unlimited + allowance = chaiAllowance == _MAX_UINT256 ? _MAX_UINT256 : _convertChaiToDaiAmount(chaiAllowance); } // Allowance will be 0 if bridge is not supported } @@ -662,6 +667,8 @@ contract LibAssetData is ); } + /// @dev Reverts if assetData is not of a valid format for its given proxy id. + /// @param assetData AssetProxy compliant asset data. function revertIfInvalidAssetData(bytes memory assetData) public pure