@0x/contracts-asset-proxy
: More work on UniswapBridge
tests.
This commit is contained in:
@@ -35,6 +35,9 @@ contract UniswaBridge is
|
||||
address constant public UNISWAP_EXCHANGE_FACTORY_ADDRESS = address(0);
|
||||
address constant public WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
|
||||
|
||||
/// @dev Whether we've granted an allowance to a spender for a token.
|
||||
mapping (address => mapping (address => bool)) private _hasAllowance;
|
||||
|
||||
/// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of
|
||||
/// `toTokenAddress` tokens by selling the entirety of the `fromTokenAddress`
|
||||
/// token encoded in the bridge data.
|
||||
@@ -67,6 +70,8 @@ contract UniswaBridge is
|
||||
fromTokenAddress,
|
||||
toTokenAddress
|
||||
);
|
||||
// Grant an allowance to the exchange.
|
||||
_grantAllowanceForTokens(address(exchange), [fromTokenAddress, toTokenAddress]);
|
||||
// Get our balance of `fromTokenAddress` token.
|
||||
uint256 fromTokenBalance = IERC20Token(fromToken).balanceOf(address(this));
|
||||
|
||||
@@ -157,6 +162,30 @@ contract UniswaBridge is
|
||||
return IUniswapExchangeFactory(ETH2DAI_ADDRESS);
|
||||
}
|
||||
|
||||
/// @dev Grants an unlimited allowance to `spender` for `fromTokenAddress`
|
||||
/// and `toTokenAddress` tokens, if they're not WETH and we haven't
|
||||
/// already granted `spender` an allowance.
|
||||
/// @param spender The spender being granted an aloowance.
|
||||
/// @param tokenAddresses Array of token addresses.
|
||||
function _grantAllowanceForTokens(
|
||||
address spender,
|
||||
address[2] memory tokenAddresses,
|
||||
)
|
||||
private
|
||||
{
|
||||
address wethAddress = address(_getWethContract());
|
||||
mapping (address => bool) storage doesSpenderHaveAllowance = _hasAllowance[spender];
|
||||
for (uint256 i = 0; i < tokenAddresses.length; ++i) {
|
||||
address tokenAddress = tokenAddresses[i];
|
||||
if (tokenAddress != wethAddress) {
|
||||
if (!doesSpenderHaveAllowance[tokenAddress]) {
|
||||
IERC20Token(tokenAddress).approve(spender, uint256(-1));
|
||||
doesSpenderHaveAllowance[tokenAddress] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Retrieves the uniswap exchange contract for a given token pair.
|
||||
/// @return exchange The exchange contract for the token pair.
|
||||
function _getUniswapExchangeForTokenPair(
|
||||
@@ -168,8 +197,7 @@ contract UniswaBridge is
|
||||
returns (IUniswapExchange exchange)
|
||||
{
|
||||
// Whichever isn't WETH is the exchange token.
|
||||
address wethAddress = address(_getWethContract());
|
||||
if (fromTokenAddress != wethAddress) {
|
||||
if (fromTokenAddress != address(_getWethContract())) {
|
||||
return _getUniswapExchangeForToken(fromTokenAddress);
|
||||
}
|
||||
return _getUniswapExchangeForToken(toTokenAddress);
|
||||
|
@@ -20,25 +20,34 @@ pragma solidity ^0.5.9;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
|
||||
import "../src/bridges/Eth2DaiBridge.sol";
|
||||
import "../src/interfaces/IEth2Dai.sol";
|
||||
import "../src/bridges/UniswapBridge.sol";
|
||||
import "../src/interfaces/IUniswap.sol";
|
||||
|
||||
|
||||
// solhint-disable no-simple-event-func-name
|
||||
/// @dev Interface that allows `TestToken` to call `raiseTransferEvent` on
|
||||
/// the `TestEth2DaiBridge` contract.
|
||||
interface ITestTokenCaller {
|
||||
/// @dev Interface that allows `TestToken` to call functions on the
|
||||
/// `TestUniswapBridge` contract.
|
||||
interface ITestEventRaiser {
|
||||
|
||||
function raiseTransferEvent(
|
||||
function raiseTokenTransferEvent(
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount
|
||||
)
|
||||
external;
|
||||
|
||||
function raiseTransferEvent(
|
||||
address from,
|
||||
address to,
|
||||
function raiseTokenApproveEvent(
|
||||
address spender,
|
||||
uint256 allowance
|
||||
)
|
||||
external;
|
||||
|
||||
function raiseWethDeposit(
|
||||
uint256 amount
|
||||
)
|
||||
external;
|
||||
|
||||
function raiseWethWithdraw(
|
||||
uint256 amount
|
||||
)
|
||||
external;
|
||||
@@ -50,12 +59,21 @@ contract TestToken {
|
||||
|
||||
mapping (address => uint256) public balances;
|
||||
|
||||
/// @dev Just calls `raiseTransferEvent()` on the caller.
|
||||
/// @dev Just calls `raiseTokenTransferEvent()` on the caller.
|
||||
function transfer(address to, uint256 amount)
|
||||
external
|
||||
returns (bool)
|
||||
{
|
||||
IRaiseTransferEvent(msg.sender).raiseTransferEvent(msg.sender, to, amount);
|
||||
ITestEventRaiser(msg.sender).raiseTokenTransferEvent(msg.sender, to, amount);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @dev Just calls `raiseTokenApproveEvent()` on the caller.
|
||||
function approve(address spender, uint256 allowance)
|
||||
external
|
||||
returns (bool)
|
||||
{
|
||||
ITestEventRaiser(msg.sender).raiseTokenApproveEvent(spender, allowance);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -66,13 +84,19 @@ contract TestToken {
|
||||
balances[owner] = balance;
|
||||
}
|
||||
|
||||
/// @dev Just calls `raiseApproveEvent()` on the caller.
|
||||
function approve(address spender, uint256 allowance)
|
||||
// @dev `IWETH.deposit()` that just calls `raiseWethDeposit()` on the caller.
|
||||
function deposit()
|
||||
external
|
||||
returns (bool)
|
||||
payable
|
||||
{
|
||||
allowances[msg.sender][spender] = allowance;
|
||||
return true;
|
||||
ITestEventRaiser(msg.sender).raiseWethDeposit(msg.value);
|
||||
}
|
||||
|
||||
// @dev `IWETH.withdraw()` that just calls `raiseWethWithdraw()` on the caller.
|
||||
function withdraw(uint256 amount)
|
||||
external
|
||||
{
|
||||
ITestEventRaiser(msg.sender).raiseWethWithdraw(amount);
|
||||
}
|
||||
|
||||
/// @dev Retrieve the balance for `owner`.
|
||||
@@ -86,11 +110,10 @@ contract TestToken {
|
||||
}
|
||||
|
||||
|
||||
/// @dev Eth2DaiBridge overridden to mock tokens and
|
||||
/// implement IEth2Dai.
|
||||
contract TestEth2DaiBridge is
|
||||
IEth2Dai,
|
||||
Eth2DaiBridge
|
||||
/// @dev UniswapBridge overridden to mock tokens and implement IUniswap.
|
||||
contract TestUniswapBridge is
|
||||
IUniswap,
|
||||
UniswapBridge
|
||||
{
|
||||
event SellAllAmount(
|
||||
address sellToken,
|
||||
@@ -106,6 +129,19 @@ contract TestEth2DaiBridge is
|
||||
uint256 amount
|
||||
);
|
||||
|
||||
event TokenApprove(
|
||||
address spender,
|
||||
uint256 allowance
|
||||
);
|
||||
|
||||
event WethDeposit(
|
||||
uint256 amount
|
||||
);
|
||||
|
||||
event WethWithdraw(
|
||||
uint256 amount
|
||||
);
|
||||
|
||||
TestToken public wethToken = new TestToken();
|
||||
TestToken public daiToken = new TestToken();
|
||||
string private _nextRevertReason;
|
||||
@@ -119,7 +155,7 @@ contract TestEth2DaiBridge is
|
||||
daiToken.setBalance(address(this), daiBalance);
|
||||
}
|
||||
|
||||
/// @dev Set the behavior for `IEth2Dai.sellAllAmount()`.
|
||||
/// @dev Set the behavior for `IUniswap.sellAllAmount()`.
|
||||
function setFillBehavior(string calldata revertReason, uint256 fillAmount)
|
||||
external
|
||||
{
|
||||
@@ -127,7 +163,7 @@ contract TestEth2DaiBridge is
|
||||
_nextFillAmount = fillAmount;
|
||||
}
|
||||
|
||||
/// @dev Implementation of `IEth2Dai.sellAllAmount()`
|
||||
/// @dev Implementation of `IUniswap.sellAllAmount()`
|
||||
function sellAllAmount(
|
||||
address sellTokenAddress,
|
||||
uint256 sellTokenAmount,
|
||||
@@ -149,7 +185,7 @@ contract TestEth2DaiBridge is
|
||||
return _nextFillAmount;
|
||||
}
|
||||
|
||||
function raiseTransferEvent(
|
||||
function raiseTokenTransferEvent(
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount
|
||||
@@ -164,8 +200,20 @@ contract TestEth2DaiBridge is
|
||||
);
|
||||
}
|
||||
|
||||
function raiseTokenApproveEvent(
|
||||
address spender,
|
||||
uint256 allowance
|
||||
)
|
||||
external
|
||||
{
|
||||
emit TokenApprove(
|
||||
spender,
|
||||
allowance
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Retrieves the allowances of the test tokens.
|
||||
function getEth2DaiTokenAllowances()
|
||||
function getUniswapTokenAllowances()
|
||||
external
|
||||
view
|
||||
returns (uint256 wethAllowance, uint256 daiAllowance)
|
||||
@@ -193,12 +241,12 @@ contract TestEth2DaiBridge is
|
||||
return IERC20Token(address(daiToken));
|
||||
}
|
||||
|
||||
// @dev This contract will double as the Eth2Dai contract.
|
||||
function _getEth2DaiContract()
|
||||
// @dev This contract will double as the Uniswap contract.
|
||||
function _getUniswapContract()
|
||||
internal
|
||||
view
|
||||
returns (IEth2Dai)
|
||||
returns (IUniswap)
|
||||
{
|
||||
return IEth2Dai(address(this));
|
||||
return IUniswap(address(this));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user