Update tests to use new Forwarder interface

This commit is contained in:
Amir Bandeali
2019-12-02 15:38:30 -08:00
parent 5574c368cd
commit e2e4d048ab
3 changed files with 118 additions and 75 deletions

View File

@@ -146,7 +146,7 @@ blockchainTests.resets('Forwarder <> ERC20Bridge integration tests', env => {
const tokenIds = { erc721: { [erc721Token.address]: [nftId] } };
balanceStore = new BlockchainBalanceStore(tokenOwners, tokenContracts, tokenIds);
testFactory = new ForwarderTestFactory(forwarder, deployment, balanceStore, taker, [forwarderFeeRecipient]);
testFactory = new ForwarderTestFactory(forwarder, deployment, balanceStore, taker);
});
after(async () => {
@@ -193,7 +193,10 @@ blockchainTests.resets('Forwarder <> ERC20Bridge integration tests', env => {
eth2DaiBridgeOrder,
await maker.signOrderAsync({ makerAssetData: makerTokenAssetData }), // Non-bridge order of the same ERC20
];
await testFactory.marketSellTestAsync(orders, 2.56, { forwarderFeeAmount: toBaseUnitAmount(0.1) });
await testFactory.marketSellTestAsync(orders, 2.56, {
forwarderFeeAmounts: [toBaseUnitAmount(0.1)],
forwarderFeeRecipientAddresses: [forwarderFeeRecipient.address],
});
});
it('should fully fill a single UniswapBridge order without a taker fee', async () => {
await testFactory.marketSellTestAsync([uniswapBridgeOrder], 1);
@@ -234,7 +237,7 @@ blockchainTests.resets('Forwarder <> ERC20Bridge integration tests', env => {
uniswapBridgeOrder,
await maker.signOrderAsync({ makerAssetData: makerTokenAssetData }), // Non-bridge order of the same ERC20
];
await testFactory.marketSellTestAsync(orders, 2.56, { forwarderFeeAmount: toBaseUnitAmount(0.1) });
await testFactory.marketSellTestAsync(orders, 2.56);
});
it('should fill multiple bridge orders', async () => {
await testFactory.marketSellTestAsync([eth2DaiBridgeOrder, uniswapBridgeOrder], 1.23);
@@ -292,7 +295,10 @@ blockchainTests.resets('Forwarder <> ERC20Bridge integration tests', env => {
eth2DaiBridgeOrder,
await maker.signOrderAsync({ makerAssetData: makerTokenAssetData }), // Non-bridge order of the same ERC20
];
await testFactory.marketBuyTestAsync(orders, 2.56, { forwarderFeeAmount: toBaseUnitAmount(0.1) });
await testFactory.marketBuyTestAsync(orders, 2.56, {
forwarderFeeAmounts: [toBaseUnitAmount(0.1)],
forwarderFeeRecipientAddresses: [forwarderFeeRecipient.address],
});
});
it('should revert if the amount of ETH sent is too low to fill the makerAssetAmount (Eth2Dai)', async () => {
const expectedError = new ExchangeForwarderRevertErrors.CompleteBuyFailedError(
@@ -343,7 +349,7 @@ blockchainTests.resets('Forwarder <> ERC20Bridge integration tests', env => {
uniswapBridgeOrder,
await maker.signOrderAsync({ makerAssetData: makerTokenAssetData }), // Non-bridge order of the same ERC20
];
await testFactory.marketBuyTestAsync(orders, 2.56, { forwarderFeeAmount: toBaseUnitAmount(0.1) });
await testFactory.marketBuyTestAsync(orders, 2.56);
});
it('should revert if the amount of ETH sent is too low to fill the makerAssetAmount (Uniswap)', async () => {
const expectedError = new ExchangeForwarderRevertErrors.CompleteBuyFailedError(

View File

@@ -10,7 +10,7 @@ import {
randomAddress,
toBaseUnitAmount,
} from '@0x/contracts-test-utils';
import { BigNumber, SafeMathRevertErrors } from '@0x/utils';
import { BigNumber } from '@0x/utils';
import { Actor } from '../framework/actors/base';
import { FeeRecipient } from '../framework/actors/fee_recipient';
@@ -102,7 +102,7 @@ blockchainTests('Forwarder integration tests', env => {
const tokenIds = { erc721: { [erc721Token.address]: [nftId] } };
balanceStore = new BlockchainBalanceStore(tokenOwners, tokenContracts, tokenIds);
testFactory = new ForwarderTestFactory(forwarder, deployment, balanceStore, taker, [forwarderFeeRecipient]);
testFactory = new ForwarderTestFactory(forwarder, deployment, balanceStore, taker);
});
after(async () => {
@@ -180,9 +180,7 @@ blockchainTests('Forwarder integration tests', env => {
await balanceStore.updateBalancesAsync();
// Execute test case
const tx = await forwarder
.marketSellOrdersWithEth([order], [order.signature], constants.ZERO_AMOUNT, [
forwarderFeeRecipient.address,
])
.marketSellOrdersWithEth([order], [order.signature], [], [])
.awaitTransactionSuccessAsync({
value: order.takerAssetAmount.plus(DeploymentManager.protocolFee),
from: taker.address,
@@ -221,9 +219,7 @@ blockchainTests('Forwarder integration tests', env => {
const ethValue = order.takerAssetAmount.plus(DeploymentManager.protocolFee).plus(2);
const takerEthBalanceBefore = await env.web3Wrapper.getBalanceInWeiAsync(taker.address);
const tx = await forwarder
.marketSellOrdersWithEth([order], [order.signature], constants.ZERO_AMOUNT, [
forwarderFeeRecipient.address,
])
.marketSellOrdersWithEth([order], [order.signature], [], [])
.awaitTransactionSuccessAsync({
value: ethValue,
from: taker.address,
@@ -306,44 +302,83 @@ blockchainTests('Forwarder integration tests', env => {
takerAssetAmount: toBaseUnitAmount(36),
});
await testFactory.marketSellTestAsync([order], 0.67, {
forwarderFeeAmount: toBaseUnitAmount(0.2),
forwarderFeeAmounts: [toBaseUnitAmount(0.2)],
forwarderFeeRecipientAddresses: [forwarderFeeRecipient.address],
});
});
it('should fill the order and send fees to different feeRecipient addresses', async () => {
it('should fill the order and send the same fees to different feeRecipient addresses', async () => {
const order = await maker.signOrderAsync({
makerAssetAmount: toBaseUnitAmount(157),
takerAssetAmount: toBaseUnitAmount(36),
});
await testFactory.marketSellTestAsync([order], 0.67, {
forwarderFeeAmount: toBaseUnitAmount(0.2),
forwarderFeeAmounts: [toBaseUnitAmount(0.2), toBaseUnitAmount(0.2)],
forwarderFeeRecipientAddresses: [randomAddress(), randomAddress()],
});
});
it('should fill the order and send fees to multiple instances of the same feeRecipient address', async () => {
it('should fill the order and send different fees to different feeRecipient addresses', async () => {
const order = await maker.signOrderAsync({
makerAssetAmount: toBaseUnitAmount(157),
takerAssetAmount: toBaseUnitAmount(36),
});
await testFactory.marketSellTestAsync([order], 0.67, {
forwarderFeeAmounts: [toBaseUnitAmount(0.2), toBaseUnitAmount(0.1)],
forwarderFeeRecipientAddresses: [randomAddress(), randomAddress()],
});
});
it('should fill the order and send the same fees to multiple instances of the same feeRecipient address', async () => {
const order = await maker.signOrderAsync({
makerAssetAmount: toBaseUnitAmount(157),
takerAssetAmount: toBaseUnitAmount(36),
});
const feeRecipient = randomAddress();
await testFactory.marketSellTestAsync([order], 0.67, {
forwarderFeeAmount: toBaseUnitAmount(0.2),
forwarderFeeAmounts: [toBaseUnitAmount(0.2), toBaseUnitAmount(0.2)],
forwarderFeeRecipientAddresses: [feeRecipient, feeRecipient],
});
});
it('should fail if a fee is specified with no feeRecipient', async () => {
it('should fill the order and send different fees to multiple instances of the same feeRecipient address', async () => {
const order = await maker.signOrderAsync({
makerAssetAmount: toBaseUnitAmount(157),
takerAssetAmount: toBaseUnitAmount(36),
});
const forwarderFeeAmount = toBaseUnitAmount(0.2);
const revertError = new SafeMathRevertErrors.Uint256BinOpError(
SafeMathRevertErrors.BinOpErrorCodes.DivisionByZero,
forwarderFeeAmount,
constants.ZERO_AMOUNT,
const feeRecipient = randomAddress();
await testFactory.marketSellTestAsync([order], 0.67, {
forwarderFeeAmounts: [toBaseUnitAmount(0.2), toBaseUnitAmount(0.1)],
forwarderFeeRecipientAddresses: [feeRecipient, feeRecipient],
});
});
it('should fail if ethFeeAmounts is longer than feeRecipients', async () => {
const order = await maker.signOrderAsync({
makerAssetAmount: toBaseUnitAmount(157),
takerAssetAmount: toBaseUnitAmount(36),
});
const forwarderFeeAmounts = [toBaseUnitAmount(0.2)];
const forwarderFeeRecipientAddresses: string[] = [];
const revertError = new ExchangeForwarderRevertErrors.EthFeeLengthMismatchError(
new BigNumber(forwarderFeeAmounts.length),
new BigNumber(forwarderFeeRecipientAddresses.length),
);
await testFactory.marketSellTestAsync([order], 0.67, {
forwarderFeeAmount,
forwarderFeeRecipientAddresses: [],
forwarderFeeAmounts,
forwarderFeeRecipientAddresses,
revertError,
});
});
it('should fail if feeRecipients is longer than ethFeeAmounts', async () => {
const order = await maker.signOrderAsync({
makerAssetAmount: toBaseUnitAmount(157),
takerAssetAmount: toBaseUnitAmount(36),
});
const forwarderFeeAmounts: BigNumber[] = [];
const forwarderFeeRecipientAddresses = [randomAddress()];
const revertError = new ExchangeForwarderRevertErrors.EthFeeLengthMismatchError(
new BigNumber(forwarderFeeAmounts.length),
new BigNumber(forwarderFeeRecipientAddresses.length),
);
await testFactory.marketSellTestAsync([order], 0.67, {
forwarderFeeAmounts,
forwarderFeeRecipientAddresses,
revertError,
});
});
@@ -518,13 +553,7 @@ blockchainTests('Forwarder integration tests', env => {
await balanceStore.updateBalancesAsync();
// Execute test case
const tx = await forwarder
.marketBuyOrdersWithEth(
[order],
desiredMakerAssetFillAmount,
[order.signature],
constants.ZERO_AMOUNT,
[forwarderFeeRecipient.address],
)
.marketBuyOrdersWithEth([order], desiredMakerAssetFillAmount, [order.signature], [], [])
.awaitTransactionSuccessAsync({
value: ethValue,
from: taker.address,
@@ -565,13 +594,7 @@ blockchainTests('Forwarder integration tests', env => {
await balanceStore.updateBalancesAsync();
// Execute test case
const tx = await forwarder
.marketBuyOrdersWithEth(
[order],
desiredMakerAssetFillAmount,
[order.signature],
constants.ZERO_AMOUNT,
[forwarderFeeRecipient.address],
)
.marketBuyOrdersWithEth([order], desiredMakerAssetFillAmount, [order.signature], [], [])
.awaitTransactionSuccessAsync({
value: takerAssetFillAmount.plus(DeploymentManager.protocolFee),
from: taker.address,
@@ -606,21 +629,39 @@ blockchainTests('Forwarder integration tests', env => {
takerAssetAmount: toBaseUnitAmount(11),
});
await testFactory.marketBuyTestAsync([order], 0.33, {
forwarderFeeAmount: toBaseUnitAmount(0.2),
forwarderFeeAmounts: [toBaseUnitAmount(0.2)],
forwarderFeeRecipientAddresses: [randomAddress()],
});
});
it('should fail if there is not enough ETH remaining to complete the fill', async () => {
const order = await maker.signOrderAsync();
const forwarderFeeAmounts = [toBaseUnitAmount(1)];
const revertError = new ExchangeForwarderRevertErrors.CompleteBuyFailedError(
order.takerAssetAmount,
constants.ZERO_AMOUNT,
);
await testFactory.marketBuyTestAsync([order], 0.5, {
ethValueAdjustment: -1,
forwarderFeeAmounts,
forwarderFeeRecipientAddresses: [randomAddress()],
revertError,
});
});
it('should fail if there is not enough ETH remaining to pay the fee', async () => {
const order = await maker.signOrderAsync();
const forwarderFeeAmount = toBaseUnitAmount(1);
const forwarderFeeAmounts = [toBaseUnitAmount(1)];
const value = forwarderFeeAmounts[0].minus(1);
const revertError = new ExchangeForwarderRevertErrors.InsufficientEthForFeeError(
forwarderFeeAmount,
forwarderFeeAmount.minus(1),
forwarderFeeAmounts[0],
value,
);
await testFactory.marketBuyTestAsync([order], 0.5, {
ethValueAdjustment: -1,
forwarderFeeAmount,
revertError,
});
return expect(
forwarder
.marketBuyOrdersWithEth([order], order.makerAssetAmount, [order.signature], forwarderFeeAmounts, [
randomAddress(),
])
.awaitTransactionSuccessAsync({ value }),
).to.revertWith(revertError);
});
});
});

View File

@@ -5,7 +5,6 @@ import { AssetProxyId, OrderInfo, SignedOrder } from '@0x/types';
import { BigNumber, hexUtils, RevertError } from '@0x/utils';
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
import { FeeRecipient } from '../framework/actors/fee_recipient';
import { Taker } from '../framework/actors/taker';
import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
import { LocalBalanceStore } from '../framework/balances/local_balance_store';
@@ -19,7 +18,7 @@ interface ForwarderFillState {
}
interface MarketSellOptions {
forwarderFeeAmount: BigNumber;
forwarderFeeAmounts: BigNumber[];
forwarderFeeRecipientAddresses: string[];
revertError: RevertError;
bridgeExcessBuyAmount: BigNumber;
@@ -57,7 +56,6 @@ export class ForwarderTestFactory {
private readonly _deployment: DeploymentManager,
private readonly _balanceStore: BlockchainBalanceStore,
private readonly _taker: Taker,
private readonly _forwarderFeeRecipients: FeeRecipient[],
) {}
public async marketBuyTestAsync(
@@ -66,10 +64,8 @@ export class ForwarderTestFactory {
options: Partial<MarketBuyOptions> = {},
): Promise<void> {
const ethValueAdjustment = options.ethValueAdjustment || 0;
const forwarderFeeAmount = options.forwarderFeeAmount || constants.ZERO_AMOUNT;
const forwarderFeeRecipientAddresses =
options.forwarderFeeRecipientAddresses ||
this._forwarderFeeRecipients.map(feeRecipient => feeRecipient.address);
const forwarderFeeAmounts = options.forwarderFeeAmounts || [];
const forwarderFeeRecipientAddresses = options.forwarderFeeRecipientAddresses || [];
const orderInfoBefore = await Promise.all(
orders.map(order => this._deployment.exchange.getOrderInfo(order).callAsync()),
@@ -91,11 +87,13 @@ export class ForwarderTestFactory {
orders,
makerAssetAcquiredAmount.minus(options.bridgeExcessBuyAmount || 0),
orders.map(signedOrder => signedOrder.signature),
forwarderFeeAmount,
forwarderFeeAmounts,
forwarderFeeRecipientAddresses,
)
.awaitTransactionSuccessAsync({
value: wethSpentAmount.plus(forwarderFeeAmount).plus(ethValueAdjustment),
value: wethSpentAmount
.plus(forwarderFeeAmounts.reduce((prev, curr) => prev.plus(curr), constants.ZERO_AMOUNT))
.plus(ethValueAdjustment),
from: this._taker.address,
});
@@ -128,20 +126,20 @@ export class ForwarderTestFactory {
options,
);
const forwarderFeeAmount = options.forwarderFeeAmount || constants.ZERO_AMOUNT;
const forwarderFeeRecipientAddresses =
options.forwarderFeeRecipientAddresses ||
this._forwarderFeeRecipients.map(feeRecipient => feeRecipient.address);
const forwarderFeeAmounts = options.forwarderFeeAmounts || [];
const forwarderFeeRecipientAddresses = options.forwarderFeeRecipientAddresses || [];
const tx = this._forwarder
.marketSellOrdersWithEth(
orders,
orders.map(signedOrder => signedOrder.signature),
forwarderFeeAmount,
forwarderFeeAmounts,
forwarderFeeRecipientAddresses,
)
.awaitTransactionSuccessAsync({
value: wethSpentAmount.plus(forwarderFeeAmount),
value: wethSpentAmount.plus(
forwarderFeeAmounts.reduce((prev, curr) => prev.plus(curr), constants.ZERO_AMOUNT),
),
from: this._taker.address,
});
@@ -186,6 +184,15 @@ export class ForwarderTestFactory {
): Promise<ForwarderFillState> {
await this._balanceStore.updateBalancesAsync();
const balances = LocalBalanceStore.create(this._balanceStore);
const forwarderFeeAmounts = options.forwarderFeeAmounts || [];
const forwarderFeeRecipientAddresses = options.forwarderFeeRecipientAddresses || [];
forwarderFeeAmounts.forEach((feeAmount, i) =>
// In reality the Forwarder is a middleman in this transaction and the ETH gets wrapped and unwrapped.
balances.sendEth(this._taker.address, forwarderFeeRecipientAddresses[i], feeAmount),
);
const currentTotal = {
wethSpentAmount: constants.ZERO_AMOUNT,
makerAssetAcquiredAmount: constants.ZERO_AMOUNT,
@@ -216,17 +223,6 @@ export class ForwarderTestFactory {
);
}
const ethSpentOnForwarderFee = options.forwarderFeeAmount || constants.ZERO_AMOUNT;
const forwarderFeeRecipientAddresses =
options.forwarderFeeRecipientAddresses ||
this._forwarderFeeRecipients.map(feeRecipient => feeRecipient.address);
const ethFeePerFeeRecipient = ethSpentOnForwarderFee.dividedToIntegerBy(forwarderFeeRecipientAddresses.length);
forwarderFeeRecipientAddresses.forEach(feeRecipientAddress =>
// In reality the Forwarder is a middleman in this transaction and the ETH gets wrapped and unwrapped.
balances.sendEth(this._taker.address, feeRecipientAddress, ethFeePerFeeRecipient),
);
return { ...currentTotal, balances };
}