@0x/contracts-asset-proxy: Always set allowance.

This commit is contained in:
Lawrence Forman
2019-10-01 18:32:41 -07:00
parent 2593f1ff30
commit 95e461072f
2 changed files with 39 additions and 45 deletions

View File

@@ -52,9 +52,6 @@ contract UniswapBridge is
payable
{}
/// @dev Whether we've granted an allowance to the exchange for a token.
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.
@@ -184,16 +181,13 @@ contract UniswapBridge is
}
/// @dev Grants an unlimited allowance to the exchange for its token
/// on behalf of this contract, if we haven't already done so.
/// on behalf of this contract.
/// @param exchange The Uniswap token exchange.
function _grantExchangeAllowance(IUniswapExchange exchange)
private
{
address tokenAddress = exchange.toTokenAddress();
if (!_hasAllowance[tokenAddress]) {
IERC20Token(tokenAddress).approve(address(exchange), uint256(-1));
_hasAllowance[tokenAddress] = true;
}
IERC20Token(tokenAddress).approve(address(exchange), uint256(-1));
}
/// @dev Retrieves the uniswap exchange contract for a given token pair.

View File

@@ -47,7 +47,10 @@ blockchainTests.resets.only('UniswapBridge unit tests', env => {
describe('isValidSignature()', () => {
it('returns success bytes', async () => {
const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381';
const result = await testContract.isValidSignature.callAsync(hexRandom(), hexRandom(_.random(0, 32)));
const result = await testContract.isValidSignature.callAsync(
hexRandom(),
hexRandom(_.random(0, 32)),
);
expect(result).to.eq(LEGACY_WALLET_MAGIC_VALUE);
});
});
@@ -112,9 +115,10 @@ blockchainTests.resets.only('UniswapBridge unit tests', env => {
_opts.fromTokenRevertReason,
);
// Set the token balance for the token we're converting from.
await testContract.setTokenBalance.awaitTransactionSuccessAsync(_opts.fromTokenAddress, {
value: new BigNumber(_opts.fromTokenBalance),
});
await testContract.setTokenBalance.awaitTransactionSuccessAsync(
_opts.fromTokenAddress,
{ value: new BigNumber(_opts.fromTokenBalance) },
);
// Call withdrawTo().
const [result, receipt] = await txHelper.getResultAndReceiptAsync(
testContract.withdrawTo,
@@ -132,7 +136,7 @@ blockchainTests.resets.only('UniswapBridge unit tests', env => {
return {
opts: _opts,
result,
logs: receipt.logs,
logs: receipt.logs as any as DecodedLogs,
blockTime: await env.web3Wrapper.getBlockTimestampAsync(receipt.blockNumber),
};
}
@@ -157,7 +161,10 @@ blockchainTests.resets.only('UniswapBridge unit tests', env => {
toTokenAddress: tokenAddress,
});
expect(result).to.eq(AssetProxyId.ERC20Bridge);
const transfers = filterLogsToArguments<TokenTransferArgs>(logs, ContractEvents.TokenTransfer);
const transfers = filterLogsToArguments<TokenTransferArgs>(
logs,
ContractEvents.TokenTransfer,
);
expect(transfers.length).to.eq(1);
expect(transfers[0].token).to.eq(tokenAddress);
expect(transfers[0].from).to.eq(testContract.address);
@@ -185,20 +192,16 @@ blockchainTests.resets.only('UniswapBridge unit tests', env => {
it('sets allowance for "from" token', async () => {
const { opts, logs } = await withdrawToAsync();
const transfers = filterLogsToArguments<TokenApproveArgs>(logs, ContractEvents.TokenApprove);
const transfers = filterLogsToArguments<TokenApproveArgs>(
logs,
ContractEvents.TokenApprove,
);
const exchangeAddress = await getExchangeForTokenAsync(opts.fromTokenAddress);
expect(transfers.length).to.eq(1);
expect(transfers[0].spender).to.eq(exchangeAddress);
expect(transfers[0].allowance).to.bignumber.eq(constants.MAX_UINT256);
});
it('sets allowance for "from" token only once', async () => {
const { opts } = await withdrawToAsync();
const { logs } = await withdrawToAsync(opts);
const transfers = filterLogsToArguments<TokenApproveArgs>(logs, ContractEvents.TokenApprove);
expect(transfers.length).to.eq(0);
});
it('fails if "from" token does not exist', async () => {
const tx = testContract.withdrawTo.awaitTransactionSuccessAsync(
randomAddress(),
@@ -225,7 +228,10 @@ blockchainTests.resets.only('UniswapBridge unit tests', env => {
toTokenAddress: wethTokenAddress,
});
const exchangeAddress = await getExchangeForTokenAsync(opts.fromTokenAddress);
let calls: any = filterLogs<TokenToEthSwapInputArgs>(logs, ContractEvents.TokenToEthSwapInput);
let calls: any = filterLogs<TokenToEthSwapInputArgs>(
logs,
ContractEvents.TokenToEthSwapInput,
);
expect(calls.length).to.eq(1);
expect(calls[0].args.exchange).to.eq(exchangeAddress);
expect(calls[0].args.tokensSold).to.bignumber.eq(opts.fromTokenBalance);
@@ -252,7 +258,10 @@ blockchainTests.resets.only('UniswapBridge unit tests', env => {
const { opts, logs, blockTime } = await withdrawToAsync({
toTokenAddress: wethTokenAddress,
});
const calls = filterLogsToArguments<TokenToEthSwapInputArgs>(logs, ContractEvents.TokenToEthSwapInput);
const calls = filterLogsToArguments<TokenToEthSwapInputArgs>(
logs,
ContractEvents.TokenToEthSwapInput,
);
const exchangeAddress = await getExchangeForTokenAsync(opts.fromTokenAddress);
expect(calls.length).to.eq(1);
expect(calls[0].exchange).to.eq(exchangeAddress);
@@ -265,22 +274,16 @@ blockchainTests.resets.only('UniswapBridge unit tests', env => {
const { opts, logs } = await withdrawToAsync({
toTokenAddress: wethTokenAddress,
});
const transfers = filterLogsToArguments<TokenApproveArgs>(logs, ContractEvents.TokenApprove);
const transfers = filterLogsToArguments<TokenApproveArgs>(
logs,
ContractEvents.TokenApprove,
);
const exchangeAddress = await getExchangeForTokenAsync(opts.fromTokenAddress);
expect(transfers.length).to.eq(1);
expect(transfers[0].spender).to.eq(exchangeAddress);
expect(transfers[0].allowance).to.bignumber.eq(constants.MAX_UINT256);
});
it('sets allowance for "from" token only once', async () => {
const { opts } = await withdrawToAsync({
toTokenAddress: wethTokenAddress,
});
const { logs } = await withdrawToAsync(opts);
const transfers = filterLogsToArguments<TokenApproveArgs>(logs, ContractEvents.TokenApprove);
expect(transfers.length).to.eq(0);
});
it('fails if "from" token does not exist', async () => {
const tx = testContract.withdrawTo.awaitTransactionSuccessAsync(
randomAddress(),
@@ -317,7 +320,10 @@ blockchainTests.resets.only('UniswapBridge unit tests', env => {
fromTokenAddress: wethTokenAddress,
});
const exchangeAddress = await getExchangeForTokenAsync(opts.toTokenAddress);
let calls: any = filterLogs<WethWithdrawArgs>(logs, ContractEvents.WethWithdraw);
let calls: any = filterLogs<WethWithdrawArgs>(
logs,
ContractEvents.WethWithdraw,
);
expect(calls.length).to.eq(1);
expect(calls[0].args.amount).to.bignumber.eq(opts.fromTokenBalance);
calls = filterLogs<EthToTokenTransferInputArgs>(
@@ -335,22 +341,16 @@ blockchainTests.resets.only('UniswapBridge unit tests', env => {
const { opts, logs } = await withdrawToAsync({
fromTokenAddress: wethTokenAddress,
});
const transfers = filterLogsToArguments<TokenApproveArgs>(logs, ContractEvents.TokenApprove);
const transfers = filterLogsToArguments<TokenApproveArgs>(
logs,
ContractEvents.TokenApprove,
);
const exchangeAddress = await getExchangeForTokenAsync(opts.toTokenAddress);
expect(transfers.length).to.eq(1);
expect(transfers[0].spender).to.eq(exchangeAddress);
expect(transfers[0].allowance).to.bignumber.eq(constants.MAX_UINT256);
});
it('sets allowance for "from" token only', async () => {
const { opts } = await withdrawToAsync({
fromTokenAddress: wethTokenAddress,
});
const { logs } = await withdrawToAsync(opts);
const transfers = filterLogsToArguments<TokenApproveArgs>(logs, ContractEvents.TokenApprove);
expect(transfers.length).to.eq(0);
});
it('fails if "to" token does not exist', async () => {
const tx = testContract.withdrawTo.awaitTransactionSuccessAsync(
wethTokenAddress,