@0x/contracts-asset-proxy: Use IWallet from exchange-libs.

`@0x/contracts-asset-proxy`: Fix some comment typos in `UniswapBridge`.
`@0x/contracts-asset-proxy`: Add more allowance tests to the `UniswapBridge` tests.
This commit is contained in:
Lawrence Forman
2019-10-03 10:16:49 -07:00
parent cf2053ec77
commit 035dc607db
3 changed files with 88 additions and 58 deletions

View File

@@ -21,9 +21,9 @@ pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol";
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
import "../interfaces/IUniswapExchangeFactory.sol";
import "../interfaces/IUniswapExchange.sol";
import "../interfaces/IWallet.sol";
import "../interfaces/IERC20Bridge.sol";
@@ -110,7 +110,7 @@ contract UniswapBridge is
// Convert from a token to WETH.
} else if (toTokenAddress == address(state.weth)) {
// Buy as much ETH with `toTokenAddress` token as possible.
// Buy as much ETH with `fromTokenAddress` token as possible.
uint256 ethBought = state.exchange.tokenToEthSwapInput(
// Sell all tokens we hold.
state.fromTokenBalance,

View File

@@ -1,38 +0,0 @@
/*
Copyright 2019 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.5.9;
pragma experimental ABIEncoderV2;
contract IWallet {
bytes4 internal constant LEGACY_WALLET_MAGIC_VALUE = 0xb0671381;
/// @dev Validates a hash with the `Wallet` signature type.
/// @param hash Message hash that is signed.
/// @param signature Proof of signing.
/// @return magicValue `bytes4(0xb0671381)` if the signature check succeeds.
function isValidSignature(
bytes32 hash,
bytes calldata signature
)
external
view
returns (bytes4 magicValue);
}

View File

@@ -47,7 +47,10 @@ blockchainTests.resets('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('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('UniswapBridge unit tests', env => {
return {
opts: _opts,
result,
logs: (receipt.logs as any) as DecodedLogs,
logs: receipt.logs as any as DecodedLogs,
blockTime: await env.web3Wrapper.getBlockTimestampAsync(receipt.blockNumber),
};
}
@@ -157,7 +161,10 @@ blockchainTests.resets('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,11 +192,27 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
it('sets allowance for "from" token', async () => {
const { opts, logs } = await withdrawToAsync();
const transfers = filterLogsToArguments<TokenApproveArgs>(logs, ContractEvents.TokenApprove);
const approvals = 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);
expect(approvals.length).to.eq(1);
expect(approvals[0].spender).to.eq(exchangeAddress);
expect(approvals[0].allowance).to.bignumber.eq(constants.MAX_UINT256);
});
it('sets allowance for "from" token on subsequent calls', async () => {
const { opts } = await withdrawToAsync();
const { logs } = await withdrawToAsync(opts);
const approvals = filterLogsToArguments<TokenApproveArgs>(
logs,
ContractEvents.TokenApprove,
);
const exchangeAddress = await getExchangeForTokenAsync(opts.fromTokenAddress);
expect(approvals.length).to.eq(1);
expect(approvals[0].spender).to.eq(exchangeAddress);
expect(approvals[0].allowance).to.bignumber.eq(constants.MAX_UINT256);
});
it('fails if "from" token does not exist', async () => {
@@ -218,7 +241,10 @@ blockchainTests.resets('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);
@@ -245,7 +271,10 @@ blockchainTests.resets('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);
@@ -258,13 +287,31 @@ blockchainTests.resets('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 on subsequent calls', async () => {
const { opts } = await withdrawToAsync({
toTokenAddress: wethTokenAddress,
});
const { logs } = await withdrawToAsync(opts);
const approvals = filterLogsToArguments<TokenApproveArgs>(
logs,
ContractEvents.TokenApprove,
);
const exchangeAddress = await getExchangeForTokenAsync(opts.fromTokenAddress);
expect(approvals.length).to.eq(1);
expect(approvals[0].spender).to.eq(exchangeAddress);
expect(approvals[0].allowance).to.bignumber.eq(constants.MAX_UINT256);
});
it('fails if "from" token does not exist', async () => {
const tx = testContract.withdrawTo.awaitTransactionSuccessAsync(
randomAddress(),
@@ -301,7 +348,10 @@ blockchainTests.resets('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>(
@@ -319,11 +369,29 @@ blockchainTests.resets('UniswapBridge unit tests', env => {
const { opts, logs } = await withdrawToAsync({
fromTokenAddress: wethTokenAddress,
});
const transfers = filterLogsToArguments<TokenApproveArgs>(logs, ContractEvents.TokenApprove);
const approvals = 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);
expect(approvals.length).to.eq(1);
expect(approvals[0].spender).to.eq(exchangeAddress);
expect(approvals[0].allowance).to.bignumber.eq(constants.MAX_UINT256);
});
it('sets allowance for "to" token on subsequent calls', async () => {
const { opts } = await withdrawToAsync({
fromTokenAddress: wethTokenAddress,
});
const { logs } = await withdrawToAsync(opts);
const approvals = filterLogsToArguments<TokenApproveArgs>(
logs,
ContractEvents.TokenApprove,
);
const exchangeAddress = await getExchangeForTokenAsync(opts.toTokenAddress);
expect(approvals.length).to.eq(1);
expect(approvals[0].spender).to.eq(exchangeAddress);
expect(approvals[0].allowance).to.bignumber.eq(constants.MAX_UINT256);
});
it('fails if "to" token does not exist', async () => {