Add ChaiBridge allowance checks

This commit is contained in:
Amir 2020-01-06 22:00:33 -08:00
parent 410a3fef18
commit 9a97401606
2 changed files with 35 additions and 6 deletions

View File

@ -18,6 +18,13 @@
pragma solidity ^0.5.9; pragma solidity ^0.5.9;
contract PotLike {
function chi() external returns (uint256);
function rho() external returns (uint256);
function drip() external returns (uint256);
function join(uint256) external;
function exit(uint256) external;
}
// The actual Chai contract can be found here: https://github.com/dapphub/chai // The actual Chai contract can be found here: https://github.com/dapphub/chai
contract IChai { contract IChai {
@ -35,6 +42,11 @@ contract IChai {
/// @param usr Address of Chai holder. /// @param usr Address of Chai holder.
/// @return Dai balance. /// @return Dai balance.
function dai(address usr) function dai(address usr)
external external
returns (uint256); returns (uint256);
/// @dev Queries the Pot contract used by the Chai contract.
function pot()
external
returns (PotLike);
} }

View File

@ -28,6 +28,7 @@ import "@0x/contracts-erc721/contracts/src/interfaces/IERC721Token.sol";
import "@0x/contracts-erc1155/contracts/src/interfaces/IERC1155.sol"; import "@0x/contracts-erc1155/contracts/src/interfaces/IERC1155.sol";
import "@0x/contracts-asset-proxy/contracts/src/interfaces/IChai.sol"; import "@0x/contracts-asset-proxy/contracts/src/interfaces/IChai.sol";
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol";
contract LibAssetData is contract LibAssetData is
@ -152,12 +153,12 @@ contract LibAssetData is
// Get address of ERC20 token and bridge contract // Get address of ERC20 token and bridge contract
(, address tokenAddress, address bridgeAddress,) = decodeERC20BridgeAssetData(assetData); (, address tokenAddress, address bridgeAddress,) = decodeERC20BridgeAssetData(assetData);
if (tokenAddress == _getDaiAddress() && bridgeAddress == _CHAI_BRIDGE_ADDRESS) { if (tokenAddress == _getDaiAddress() && bridgeAddress == _CHAI_BRIDGE_ADDRESS) {
bytes memory chaiDaiCalldata = abi.encodeWithSelector( bytes memory chaiDaiData = abi.encodeWithSelector(
IChai(address(0)).dai.selector, IChai(address(0)).dai.selector,
ownerAddress ownerAddress
); );
// We do not make a STATICCALL because this function can potentially alter state // We do not make a STATICCALL because this function can potentially alter state
(bool success, bytes memory returnData) = _getChaiAddress().call(chaiDaiCalldata); (bool success, bytes memory returnData) = _getChaiAddress().call(chaiDaiData);
uint256 chaiBalance = success && returnData.length == 32 ? returnData.readUint256(0) : 0; uint256 chaiBalance = success && returnData.length == 32 ? returnData.readUint256(0) : 0;
} }
// Balance will be 0 if bridge is not supported // Balance will be 0 if bridge is not supported
@ -217,7 +218,6 @@ contract LibAssetData is
/// @return Number of assets (or asset baskets) that the corresponding AssetProxy is authorized to spend. /// @return Number of assets (or asset baskets) that the corresponding AssetProxy is authorized to spend.
function getAssetProxyAllowance(address ownerAddress, bytes memory assetData) function getAssetProxyAllowance(address ownerAddress, bytes memory assetData)
public public
view
returns (uint256 allowance) returns (uint256 allowance)
{ {
// Get id of AssetProxy contract // Get id of AssetProxy contract
@ -305,6 +305,24 @@ contract LibAssetData is
} else if (assetProxyId == IAssetData(address(0)).StaticCall.selector) { } else if (assetProxyId == IAssetData(address(0)).StaticCall.selector) {
// The StaticCallProxy does not require any approvals // The StaticCallProxy does not require any approvals
allowance = _MAX_UINT256; 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);
if (tokenAddress == _getDaiAddress() && bridgeAddress == _CHAI_BRIDGE_ADDRESS) {
bytes memory allowanceData = abi.encodeWithSelector(
IERC20Token(address(0)).allowance.selector,
ownerAddress,
_CHAI_BRIDGE_ADDRESS
);
(bool success, bytes memory returnData) = _getChaiAddress().staticcall(allowanceData);
uint256 chaiAllowance = success && returnData.length == 32 ? returnData.readUint256(0) : 0;
IChai chaiContract = IChai(_getChaiAddress());
uint256 chiMultiplier = (now > chaiContract.pot().rho())
? chaiContract.pot().drip()
: chaiContract.pot().chi();
allowance = LibMath.getPartialAmountFloor(chiMultiplier, 10**27, chaiAllowance);
}
// Allowance will be 0 if bridge is not supported
} }
// Allowance will be 0 if the assetProxyId is unknown // Allowance will be 0 if the assetProxyId is unknown
@ -318,7 +336,6 @@ contract LibAssetData is
/// element corresponding to the same-indexed element in the assetData input. /// element corresponding to the same-indexed element in the assetData input.
function getBatchAssetProxyAllowances(address ownerAddress, bytes[] memory assetData) function getBatchAssetProxyAllowances(address ownerAddress, bytes[] memory assetData)
public public
view
returns (uint256[] memory allowances) returns (uint256[] memory allowances)
{ {
uint256 length = assetData.length; uint256 length = assetData.length;