Skip to content
This repository has been archived by the owner on Jul 9, 2021. It is now read-only.

Commit

Permalink
wip: tests
Browse files Browse the repository at this point in the history
  • Loading branch information
xianny committed Jun 2, 2020
1 parent 46a8c65 commit ba6f7d5
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ contract UniswapV2Bridge is

// Convert directly from fromTokenAddress to toTokenAddress
address[] memory path = new address[](2);
path = path.append(state.fromTokenAddress);
path = path.append(toTokenAddress);
path[0] = state.fromTokenAddress;
path[1] = toTokenAddress;

// Buy as much `toTokenAddress` token with `fromTokenAddress` token
// and transfer it to `to`.
Expand All @@ -107,7 +107,7 @@ contract UniswapV2Bridge is
block.timestamp
);

state.boughtAmount = amounts[1];
state.boughtAmount = amounts[0];

emit ERC20BridgeTransfer(
// input token
Expand Down
122 changes: 68 additions & 54 deletions contracts/asset-proxy/contracts/test/TestUniswapV2Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,8 @@ import "@0x/contracts-utils/contracts/src/LibAddressArray.sol";
import "../src/bridges/UniswapV2Bridge.sol";
import "../src/interfaces/IUniswapV2Router01.sol";


/// @dev A minimalist ERC20/WETH token.
contract TestToken {

using LibSafeMath for uint256;

mapping (address => uint256) public balances;
string private _nextRevertReason;

contract TestEventsRaiser {

event TokenTransfer(
address token,
address from,
Expand All @@ -46,6 +39,59 @@ contract TestToken {
uint256 allowance
);

event SwapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
address toTokenAddress,
address to,
uint deadline
);

function raiseTokenTransfer(
address from,
address to,
uint256 amount
)
external
{
emit TokenTransfer(
msg.sender,
from,
to,
amount
);
}

function raiseTokenApprove(address spender, uint256 allowance) external {
emit TokenApprove(spender, allowance);
}

function raiseSwapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
address toTokenAddress,
address to,
uint deadline
) external
{
emit SwapExactTokensForTokens(
amountIn,
amountOutMin,
toTokenAddress,
to,
deadline
);
}
}

/// @dev A minimalist ERC20 token.
contract TestToken {

using LibSafeMath for uint256;

mapping (address => uint256) public balances;
string private _nextRevertReason;

/// @dev Set the balance for `owner`.
function setBalance(address owner)
external
Expand All @@ -68,7 +114,7 @@ contract TestToken {
returns (bool)
{
_revertIfReasonExists();
emit TokenTransfer(msg.sender, msg.sender, to, amount);
TestEventsRaiser(msg.sender).raiseTokenTransfer(msg.sender, to, amount);
return true;
}

Expand All @@ -77,32 +123,10 @@ contract TestToken {
external
returns (bool)
{
emit TokenApprove(spender, allowance);
TestEventsRaiser(msg.sender).raiseTokenApprove(spender, allowance);
return true;
}

/// @dev `IWETH.deposit()` that increases balances and calls
/// `raiseWethDeposit()` on the caller.
function deposit()
external
payable
{
_revertIfReasonExists();
balances[msg.sender] += balances[msg.sender].safeAdd(msg.value);
// TestEventsRaiser(msg.sender).raiseWethDeposit(msg.value);
}

/// @dev `IWETH.withdraw()` that just reduces balances and calls
/// `raiseWethWithdraw()` on the caller.
function withdraw(uint256 amount)
external
{
_revertIfReasonExists();
balances[msg.sender] = balances[msg.sender].safeSub(amount);
msg.sender.transfer(amount);
// TestEventsRaiser(msg.sender).raiseWethWithdraw(amount);
}

function allowance(address, address) external view returns (uint256) {
return 0;
}
Expand Down Expand Up @@ -131,15 +155,6 @@ contract TestRouter is
IUniswapV2Router01
{

event TokenToTokenTransferInput(
address exchange,
uint256 tokensSold,
uint256 minTokensBought,
uint256 deadline,
address recipient,
address toTokenAddress
);

function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
Expand All @@ -148,23 +163,21 @@ contract TestRouter is
uint deadline
) external returns (uint[] memory amounts)
{
amounts = new uint[](2);
amounts[0] = amountIn;
// amounts[1] = address(this).balance;
amounts[1] = amountOutMin;

emit TokenToTokenTransferInput(
msg.sender,
amounts = new uint[](1);
amounts[0] = amountOutMin;

TestEventsRaiser(msg.sender).raiseSwapExactTokensForTokens(
// tokens sold
amountIn,
// tokens bought
amountOutMin,
// deadline
deadline,
// output token (toTokenAddress)
path[1],
// recipient
to,
// output token (toTokenAddress)
path[1]
// deadline
deadline
);
}

Expand All @@ -173,7 +186,8 @@ contract TestRouter is

/// @dev UniswapV2Bridge overridden to mock tokens and Uniswap router
contract TestUniswapV2Bridge is
UniswapV2Bridge
UniswapV2Bridge,
TestEventsRaiser
{

// Token address to TestToken instance.
Expand All @@ -192,7 +206,7 @@ contract TestUniswapV2Bridge is
payable
{
TestToken token = _testTokens[tokenAddress];
token.deposit.value(msg.value)();
token.setBalance(address(this));
}

/// @dev Sets the revert reason for an existing token.
Expand Down
73 changes: 38 additions & 35 deletions contracts/asset-proxy/test/uniswapv2_bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
expect,
filterLogsToArguments,
getRandomInteger,
getRandomPortion,
randomAddress,
} from '@0x/contracts-test-utils';
import { AssetProxyId } from '@0x/types';
Expand All @@ -16,11 +15,16 @@ import { artifacts } from './artifacts';

import {
TestUniswapV2BridgeContract,
UniswapV2BridgeERC20BridgeTransferEventArgs,
UniswapV2BridgeEvents,
TestUniswapV2BridgeEvents as ContractEvents,
TestUniswapV2BridgeSwapExactTokensForTokensEventArgs as SwapExactTokensForTokensArgs,
// TestUniswapV2BridgeTokenToEthSwapInputEventArgs as TokenToEthSwapInputArgs,
TestUniswapV2BridgeTokenApproveEventArgs as TokenApproveArgs,
TestUniswapV2BridgeTokenTransferEventArgs as TokenTransferArgs,
// TestUniswapV2BridgeWethDepositEventArgs as WethDepositArgs,
// TestUniswapV2BridgeWethWithdrawEventArgs as WethWithdrawArgs,
} from './wrappers';

blockchainTests.resets.only('UniswapV2 unit tests', env => {
blockchainTests.resets('UniswapV2 unit tests', env => {
const FROM_TOKEN_DECIMALS = 6;
const TO_TOKEN_DECIMALS = 18;
const FROM_TOKEN_BASE = new BigNumber(10).pow(FROM_TOKEN_DECIMALS);
Expand All @@ -46,15 +50,13 @@ blockchainTests.resets.only('UniswapV2 unit tests', env => {
});
});

describe('bridgeTransferFrom()', () => {
describe.only('bridgeTransferFrom()', () => {
interface TransferFromOpts {
toTokenAddress: string;
fromTokenAddress: string;
toAddress: string;
// Amount to pass into `bridgeTransferFrom()`
amount: BigNumber;
// Amount to convert in `trade()`.
fillAmount: BigNumber;
// Token balance of the bridge.
fromTokenBalance: BigNumber;
}
Expand All @@ -72,24 +74,22 @@ blockchainTests.resets.only('UniswapV2 unit tests', env => {
toTokenAddress: constants.NULL_ADDRESS,
amount,
toAddress: randomAddress(),
fillAmount: getRandomPortion(amount),
fromTokenBalance: getRandomInteger(1, FROM_TOKEN_BASE.times(100)),
...opts,
};
}

async function transferFromAsync(opts?: Partial<TransferFromOpts>): Promise<TransferFromResult> {
const _opts = createTransferFromOpts(opts);
const callData = { value: new BigNumber(_opts.fillAmount) };
// Create the "from" token.
const createFromTokenFn = testContract.createToken(_opts.fromTokenAddress);
_opts.fromTokenAddress = await createFromTokenFn.callAsync(callData);
await createFromTokenFn.awaitTransactionSuccessAsync(callData);
_opts.fromTokenAddress = await createFromTokenFn.callAsync();
await createFromTokenFn.awaitTransactionSuccessAsync();

// Create the "to" token.
const createToTokenFn = testContract.createToken(_opts.toTokenAddress);
_opts.toTokenAddress = await createToTokenFn.callAsync(callData);
await createToTokenFn.awaitTransactionSuccessAsync(callData);
_opts.toTokenAddress = await createToTokenFn.callAsync();
await createToTokenFn.awaitTransactionSuccessAsync();

// Set the token balance for the token we're converting from.
await testContract.setTokenBalance(_opts.fromTokenAddress).awaitTransactionSuccessAsync({
Expand Down Expand Up @@ -123,37 +123,40 @@ blockchainTests.resets.only('UniswapV2 unit tests', env => {
expect(result).to.eq(AssetProxyId.ERC20Bridge);
});

it('transfers from one token to another', async () => {
const { opts, result, logs } = await transferFromAsync();
it('transfers when both tokens are the same', async () => {
const createTokenFn = testContract.createToken(constants.NULL_ADDRESS);
const tokenAddress = await createTokenFn.callAsync();
await createTokenFn.awaitTransactionSuccessAsync();

const { opts, result, logs } = await transferFromAsync({
fromTokenAddress: tokenAddress,
toTokenAddress: tokenAddress,
});
expect(result).to.eq(AssetProxyId.ERC20Bridge, 'asset proxy id');
const transfers = filterLogsToArguments<UniswapV2BridgeERC20BridgeTransferEventArgs>(
logs,
UniswapV2BridgeEvents.ERC20BridgeTransfer,
);
const transfers = filterLogsToArguments<TokenTransferArgs>(logs, ContractEvents.TokenTransfer);

expect(transfers.length).to.eq(1);
expect(transfers[0].inputToken).to.eq(opts.fromTokenAddress, 'input token address');
expect(transfers[0].outputToken).to.eq(opts.toTokenAddress, 'output token address');
expect(transfers[0].token).to.eq(tokenAddress, 'input token address');
expect(transfers[0].from).to.eq(testContract.address);
expect(transfers[0].to).to.eq(opts.toAddress, 'recipient address');
expect(transfers[0].inputTokenAmount).to.bignumber.eq(opts.fromTokenBalance, 'input token amount');
expect(transfers[0].outputTokenAmount).to.bignumber.eq(opts.amount, 'output token amount');
expect(transfers[0].amount).to.bignumber.eq(opts.amount, 'amount');
});
it.skip('transfers when both tokens are the same', async () => {
const address = randomAddress();
const { opts, result, logs } = await transferFromAsync({
fromTokenAddress: address,
toTokenAddress: address,
});

it.only('calls UniswapV2Router01.swapExactTokensForTokens()', async () => {
const { opts, result, logs } = await transferFromAsync();
expect(result).to.eq(AssetProxyId.ERC20Bridge, 'asset proxy id');
const transfers = filterLogsToArguments<UniswapV2BridgeERC20BridgeTransferEventArgs>(
const transfers = filterLogsToArguments<SwapExactTokensForTokensArgs>(
logs,
UniswapV2BridgeEvents.ERC20BridgeTransfer,
ContractEvents.SwapExactTokensForTokens,
);

console.log(transfers[0].amountIn, 'amountIN');
console.log(transfers[0].amountOutMin, 'amount out');
expect(transfers.length).to.eq(1);
expect(transfers[0].inputToken).to.eq(opts.fromTokenAddress, 'input token address');
expect(transfers[0].outputToken).to.eq(opts.toTokenAddress, 'output token address');
expect(transfers[0].toTokenAddress).to.eq(opts.toTokenAddress, 'output token address');
expect(transfers[0].to).to.eq(opts.toAddress, 'recipient address');
expect(transfers[0].inputTokenAmount).to.bignumber.eq(opts.fromTokenBalance, 'input token amount');
expect(transfers[0].outputTokenAmount).to.bignumber.eq(opts.amount, 'output token amount');
expect(transfers[0].amountIn).to.bignumber.eq(opts.fromTokenBalance, 'input token amount');
expect(transfers[0].amountOutMin).to.bignumber.eq(opts.amount, 'output token amount');
});
});
});

0 comments on commit ba6f7d5

Please sign in to comment.