Add tests with multiple fee recipients
This commit is contained in:
@@ -20,7 +20,7 @@ import { TestEth2DaiContract, TestUniswapExchangeContract } from '../wrappers';
|
||||
import { deployForwarderAsync } from './deploy_forwarder';
|
||||
import { ForwarderTestFactory } from './forwarder_test_factory';
|
||||
|
||||
blockchainTests.resets.only('Forwarder <> ERC20Bridge integration tests', env => {
|
||||
blockchainTests.resets('Forwarder <> ERC20Bridge integration tests', env => {
|
||||
let deployment: DeploymentManager;
|
||||
let balanceStore: BlockchainBalanceStore;
|
||||
let testFactory: ForwarderTestFactory;
|
||||
@@ -146,7 +146,7 @@ blockchainTests.resets.only('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, [forwarderFeeRecipient]);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
|
@@ -7,9 +7,10 @@ import {
|
||||
constants,
|
||||
expect,
|
||||
getLatestBlockTimestampAsync,
|
||||
randomAddress,
|
||||
toBaseUnitAmount,
|
||||
} from '@0x/contracts-test-utils';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { BigNumber, SafeMathRevertErrors } from '@0x/utils';
|
||||
|
||||
import { Actor } from '../framework/actors/base';
|
||||
import { FeeRecipient } from '../framework/actors/fee_recipient';
|
||||
@@ -23,7 +24,7 @@ import { DeploymentManager } from '../framework/deployment_manager';
|
||||
import { deployForwarderAsync } from './deploy_forwarder';
|
||||
import { ForwarderTestFactory } from './forwarder_test_factory';
|
||||
|
||||
blockchainTests.only('Forwarder integration tests', env => {
|
||||
blockchainTests('Forwarder integration tests', env => {
|
||||
let deployment: DeploymentManager;
|
||||
let forwarder: ForwarderContract;
|
||||
let balanceStore: BlockchainBalanceStore;
|
||||
@@ -101,7 +102,7 @@ blockchainTests.only('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, [forwarderFeeRecipient]);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
@@ -179,12 +180,9 @@ blockchainTests.only('Forwarder integration tests', env => {
|
||||
await balanceStore.updateBalancesAsync();
|
||||
// Execute test case
|
||||
const tx = await forwarder
|
||||
.marketSellOrdersWithEth(
|
||||
[order],
|
||||
[order.signature],
|
||||
constants.ZERO_AMOUNT,
|
||||
.marketSellOrdersWithEth([order], [order.signature], constants.ZERO_AMOUNT, [
|
||||
forwarderFeeRecipient.address,
|
||||
)
|
||||
])
|
||||
.awaitTransactionSuccessAsync({
|
||||
value: order.takerAssetAmount.plus(DeploymentManager.protocolFee),
|
||||
from: taker.address,
|
||||
@@ -223,12 +221,9 @@ blockchainTests.only('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,
|
||||
.marketSellOrdersWithEth([order], [order.signature], constants.ZERO_AMOUNT, [
|
||||
forwarderFeeRecipient.address,
|
||||
)
|
||||
])
|
||||
.awaitTransactionSuccessAsync({
|
||||
value: ethValue,
|
||||
from: taker.address,
|
||||
@@ -314,6 +309,44 @@ blockchainTests.only('Forwarder integration tests', env => {
|
||||
forwarderFeeAmount: toBaseUnitAmount(0.2),
|
||||
});
|
||||
});
|
||||
it('should fill the order and send 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),
|
||||
forwarderFeeRecipientAddresses: [randomAddress(), randomAddress()],
|
||||
});
|
||||
});
|
||||
it('should fill the order and send 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),
|
||||
forwarderFeeRecipientAddresses: [feeRecipient, feeRecipient],
|
||||
});
|
||||
});
|
||||
it('should fail if a fee is specified with no feeRecipient', 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,
|
||||
);
|
||||
await testFactory.marketSellTestAsync([order], 0.67, {
|
||||
forwarderFeeAmount,
|
||||
forwarderFeeRecipientAddresses: [],
|
||||
revertError,
|
||||
});
|
||||
});
|
||||
});
|
||||
blockchainTests.resets('marketBuyOrdersWithEth without extra fees', () => {
|
||||
it('should buy the exact amount of makerAsset in a single order', async () => {
|
||||
@@ -490,7 +523,7 @@ blockchainTests.only('Forwarder integration tests', env => {
|
||||
desiredMakerAssetFillAmount,
|
||||
[order.signature],
|
||||
constants.ZERO_AMOUNT,
|
||||
forwarderFeeRecipient.address,
|
||||
[forwarderFeeRecipient.address],
|
||||
)
|
||||
.awaitTransactionSuccessAsync({
|
||||
value: ethValue,
|
||||
@@ -537,7 +570,7 @@ blockchainTests.only('Forwarder integration tests', env => {
|
||||
desiredMakerAssetFillAmount,
|
||||
[order.signature],
|
||||
constants.ZERO_AMOUNT,
|
||||
forwarderFeeRecipient.address,
|
||||
[forwarderFeeRecipient.address],
|
||||
)
|
||||
.awaitTransactionSuccessAsync({
|
||||
value: takerAssetFillAmount.plus(DeploymentManager.protocolFee),
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { IAssetDataContract } from '@0x/contracts-asset-proxy';
|
||||
import { ForwarderContract } from '@0x/contracts-exchange-forwarder';
|
||||
import { constants, expect, getPercentageOfValue, hexSlice, OrderStatus, provider } from '@0x/contracts-test-utils';
|
||||
import { constants, expect, hexSlice, OrderStatus, provider } from '@0x/contracts-test-utils';
|
||||
import { AssetProxyId, OrderInfo, SignedOrder } from '@0x/types';
|
||||
import { BigNumber, hexUtils, RevertError } from '@0x/utils';
|
||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
@@ -20,6 +20,7 @@ interface ForwarderFillState {
|
||||
|
||||
interface MarketSellOptions {
|
||||
forwarderFeeAmount: BigNumber;
|
||||
forwarderFeeRecipientAddresses: string[];
|
||||
revertError: RevertError;
|
||||
bridgeExcessBuyAmount: BigNumber;
|
||||
}
|
||||
@@ -56,7 +57,7 @@ export class ForwarderTestFactory {
|
||||
private readonly _deployment: DeploymentManager,
|
||||
private readonly _balanceStore: BlockchainBalanceStore,
|
||||
private readonly _taker: Taker,
|
||||
private readonly _forwarderFeeRecipient: FeeRecipient,
|
||||
private readonly _forwarderFeeRecipients: FeeRecipient[],
|
||||
) {}
|
||||
|
||||
public async marketBuyTestAsync(
|
||||
@@ -66,6 +67,9 @@ export class ForwarderTestFactory {
|
||||
): 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 orderInfoBefore = await Promise.all(
|
||||
orders.map(order => this._deployment.exchange.getOrderInfo(order).callAsync()),
|
||||
@@ -88,7 +92,7 @@ export class ForwarderTestFactory {
|
||||
makerAssetAcquiredAmount.minus(options.bridgeExcessBuyAmount || 0),
|
||||
orders.map(signedOrder => signedOrder.signature),
|
||||
forwarderFeeAmount,
|
||||
this._forwarderFeeRecipient.address,
|
||||
forwarderFeeRecipientAddresses,
|
||||
)
|
||||
.awaitTransactionSuccessAsync({
|
||||
value: wethSpentAmount.plus(forwarderFeeAmount).plus(ethValueAdjustment),
|
||||
@@ -125,13 +129,16 @@ export class ForwarderTestFactory {
|
||||
);
|
||||
|
||||
const forwarderFeeAmount = options.forwarderFeeAmount || constants.ZERO_AMOUNT;
|
||||
const forwarderFeeRecipientAddresses =
|
||||
options.forwarderFeeRecipientAddresses ||
|
||||
this._forwarderFeeRecipients.map(feeRecipient => feeRecipient.address);
|
||||
|
||||
const tx = this._forwarder
|
||||
.marketSellOrdersWithEth(
|
||||
orders,
|
||||
orders.map(signedOrder => signedOrder.signature),
|
||||
forwarderFeeAmount,
|
||||
this._forwarderFeeRecipient.address,
|
||||
forwarderFeeRecipientAddresses,
|
||||
)
|
||||
.awaitTransactionSuccessAsync({
|
||||
value: wethSpentAmount.plus(forwarderFeeAmount),
|
||||
@@ -210,9 +217,15 @@ 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);
|
||||
|
||||
// In reality the Forwarder is a middleman in this transaction and the ETH gets wrapped and unwrapped.
|
||||
balances.sendEth(this._taker.address, this._forwarderFeeRecipient.address, ethSpentOnForwarderFee);
|
||||
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 };
|
||||
}
|
||||
|
@@ -67,6 +67,7 @@ export class LocalBalanceStore extends BalanceStore {
|
||||
* @param amount Amount of ETH to transfer.
|
||||
*/
|
||||
public sendEth(fromAddress: string, toAddress: string, amount: Numberish): void {
|
||||
this.balances.eth[toAddress] = this.balances.eth[toAddress] || constants.ZERO_AMOUNT;
|
||||
this.balances.eth[fromAddress] = this.balances.eth[fromAddress].minus(amount);
|
||||
this.balances.eth[toAddress] = this.balances.eth[toAddress].plus(amount);
|
||||
}
|
||||
|
Reference in New Issue
Block a user