Replace assetDataUtils with DevUtilsContract wherever possible (#2304)

* Replace assetDataUtils with DevUtilsContract wherever possible

Does not replace from @0x/instant and some @0x/order-utils uses

* Add revertIfInvalidAssetData to LibAssetData

This is needed to replace `assetDataUtils.decodeAssetDataOrThrow`.
Because it's used in packages and not only contracts, we should wait
to deploy the updated contract so we can update `@0x/contract-artifacts`,
`@0x/abi-gen-wrappers`, and `@0x/contract-wrappers` first.

* remove usages of signatureUtils

* fix test for  optimised encoding

* refactor @0x/contracts-integrations

* update changelogs

* Move @0x/contracts-dev-utils from devDependencies to dependencies
It is exported as part of the package
This commit is contained in:
Xianny
2019-11-06 19:40:20 -08:00
committed by GitHub
parent ec26cff656
commit 6a852ab0ed
56 changed files with 1408 additions and 970 deletions

View File

@@ -1,4 +1,5 @@
import { CoordinatorContract, SignedCoordinatorApproval } from '@0x/contracts-coordinator';
import { DevUtilsContract } from '@0x/contracts-dev-utils';
import {
BlockchainBalanceStore,
constants as exchangeConstants,
@@ -10,8 +11,16 @@ import {
ExchangeFunctionName,
LocalBalanceStore,
} from '@0x/contracts-exchange';
import { blockchainTests, constants, expect, hexConcat, hexSlice, verifyEvents } from '@0x/contracts-test-utils';
import { assetDataUtils, CoordinatorRevertErrors, orderHashUtils, transactionHashUtils } from '@0x/order-utils';
import {
blockchainTests,
constants,
expect,
hexConcat,
hexSlice,
provider,
verifyEvents,
} from '@0x/contracts-test-utils';
import { CoordinatorRevertErrors, orderHashUtils, transactionHashUtils } from '@0x/order-utils';
import { SignedOrder, SignedZeroExTransaction } from '@0x/types';
import { BigNumber } from '@0x/utils';
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
@@ -26,6 +35,7 @@ blockchainTests.resets('Coordinator integration tests', env => {
let deployment: DeploymentManager;
let coordinator: CoordinatorContract;
let balanceStore: BlockchainBalanceStore;
let devUtils: DevUtilsContract;
let maker: Maker;
let taker: Actor;
@@ -38,6 +48,7 @@ blockchainTests.resets('Coordinator integration tests', env => {
numErc1155TokensToDeploy: 0,
});
coordinator = await deployCoordinatorAsync(deployment, env);
devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider);
const [makerToken, takerToken, makerFeeToken, takerFeeToken] = deployment.tokens.erc20;
@@ -53,10 +64,10 @@ blockchainTests.resets('Coordinator integration tests', env => {
orderConfig: {
senderAddress: coordinator.address,
feeRecipientAddress: feeRecipient.address,
makerAssetData: assetDataUtils.encodeERC20AssetData(makerToken.address),
takerAssetData: assetDataUtils.encodeERC20AssetData(takerToken.address),
makerFeeAssetData: assetDataUtils.encodeERC20AssetData(makerFeeToken.address),
takerFeeAssetData: assetDataUtils.encodeERC20AssetData(takerFeeToken.address),
makerAssetData: await devUtils.encodeERC20AssetData.callAsync(makerToken.address),
takerAssetData: await devUtils.encodeERC20AssetData.callAsync(takerToken.address),
makerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(makerFeeToken.address),
takerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(takerFeeToken.address),
},
});
@@ -77,30 +88,40 @@ blockchainTests.resets('Coordinator integration tests', env => {
);
});
function simulateFills(
async function simulateFillsAsync(
orders: SignedOrder[],
txReceipt: TransactionReceiptWithDecodedLogs,
msgValue?: BigNumber,
): LocalBalanceStore {
): Promise<LocalBalanceStore> {
let remainingValue = msgValue || constants.ZERO_AMOUNT;
const localBalanceStore = LocalBalanceStore.create(balanceStore);
const localBalanceStore = LocalBalanceStore.create(devUtils, balanceStore);
// Transaction gas cost
localBalanceStore.burnGas(txReceipt.from, DeploymentManager.gasPrice.times(txReceipt.gasUsed));
for (const order of orders) {
// Taker -> Maker
localBalanceStore.transferAsset(taker.address, maker.address, order.takerAssetAmount, order.takerAssetData);
await localBalanceStore.transferAssetAsync(
taker.address,
maker.address,
order.takerAssetAmount,
order.takerAssetData,
);
// Maker -> Taker
localBalanceStore.transferAsset(maker.address, taker.address, order.makerAssetAmount, order.makerAssetData);
await localBalanceStore.transferAssetAsync(
maker.address,
taker.address,
order.makerAssetAmount,
order.makerAssetData,
);
// Taker -> Fee Recipient
localBalanceStore.transferAsset(
await localBalanceStore.transferAssetAsync(
taker.address,
feeRecipient.address,
order.takerFee,
order.takerFeeAssetData,
);
// Maker -> Fee Recipient
localBalanceStore.transferAsset(
await localBalanceStore.transferAssetAsync(
maker.address,
feeRecipient.address,
order.makerFee,
@@ -116,11 +137,11 @@ blockchainTests.resets('Coordinator integration tests', env => {
);
remainingValue = remainingValue.minus(DeploymentManager.protocolFee);
} else {
localBalanceStore.transferAsset(
await localBalanceStore.transferAssetAsync(
taker.address,
deployment.staking.stakingProxy.address,
DeploymentManager.protocolFee,
assetDataUtils.encodeERC20AssetData(deployment.tokens.weth.address),
await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.weth.address),
);
}
}
@@ -174,7 +195,7 @@ blockchainTests.resets('Coordinator integration tests', env => {
{ from: taker.address, value: DeploymentManager.protocolFee },
);
const expectedBalances = simulateFills([order], txReceipt, DeploymentManager.protocolFee);
const expectedBalances = await simulateFillsAsync([order], txReceipt, DeploymentManager.protocolFee);
await balanceStore.updateBalancesAsync();
balanceStore.assertEquals(expectedBalances);
verifyEvents(txReceipt, [expectedFillEvent(order)], ExchangeEvents.Fill);
@@ -189,7 +210,7 @@ blockchainTests.resets('Coordinator integration tests', env => {
{ from: feeRecipient.address, value: DeploymentManager.protocolFee },
);
const expectedBalances = simulateFills([order], txReceipt, DeploymentManager.protocolFee);
const expectedBalances = await simulateFillsAsync([order], txReceipt, DeploymentManager.protocolFee);
await balanceStore.updateBalancesAsync();
balanceStore.assertEquals(expectedBalances);
verifyEvents(txReceipt, [expectedFillEvent(order)], ExchangeEvents.Fill);
@@ -204,7 +225,11 @@ blockchainTests.resets('Coordinator integration tests', env => {
{ from: feeRecipient.address, value: DeploymentManager.protocolFee.plus(1) },
);
const expectedBalances = simulateFills([order], txReceipt, DeploymentManager.protocolFee.plus(1));
const expectedBalances = await simulateFillsAsync(
[order],
txReceipt,
DeploymentManager.protocolFee.plus(1),
);
await balanceStore.updateBalancesAsync();
balanceStore.assertEquals(expectedBalances);
verifyEvents(txReceipt, [expectedFillEvent(order)], ExchangeEvents.Fill);
@@ -219,7 +244,7 @@ blockchainTests.resets('Coordinator integration tests', env => {
{ from: feeRecipient.address },
);
const expectedBalances = simulateFills([order], txReceipt);
const expectedBalances = await simulateFillsAsync([order], txReceipt);
await balanceStore.updateBalancesAsync();
balanceStore.assertEquals(expectedBalances);
verifyEvents(txReceipt, [expectedFillEvent(order)], ExchangeEvents.Fill);
@@ -234,7 +259,7 @@ blockchainTests.resets('Coordinator integration tests', env => {
{ from: feeRecipient.address, value: new BigNumber(1) },
);
const expectedBalances = simulateFills([order], txReceipt, new BigNumber(1));
const expectedBalances = await simulateFillsAsync([order], txReceipt, new BigNumber(1));
await balanceStore.updateBalancesAsync();
balanceStore.assertEquals(expectedBalances);
verifyEvents(txReceipt, [expectedFillEvent(order)], ExchangeEvents.Fill);
@@ -318,7 +343,7 @@ blockchainTests.resets('Coordinator integration tests', env => {
{ from: taker.address, value },
);
const expectedBalances = simulateFills(orders, txReceipt, value);
const expectedBalances = await simulateFillsAsync(orders, txReceipt, value);
await balanceStore.updateBalancesAsync();
balanceStore.assertEquals(expectedBalances);
verifyEvents(txReceipt, orders.map(order => expectedFillEvent(order)), ExchangeEvents.Fill);
@@ -334,7 +359,7 @@ blockchainTests.resets('Coordinator integration tests', env => {
{ from: feeRecipient.address, value },
);
const expectedBalances = simulateFills(orders, txReceipt, value);
const expectedBalances = await simulateFillsAsync(orders, txReceipt, value);
await balanceStore.updateBalancesAsync();
balanceStore.assertEquals(expectedBalances);
verifyEvents(txReceipt, orders.map(order => expectedFillEvent(order)), ExchangeEvents.Fill);
@@ -350,7 +375,7 @@ blockchainTests.resets('Coordinator integration tests', env => {
{ from: feeRecipient.address, value },
);
const expectedBalances = simulateFills(orders, txReceipt, value);
const expectedBalances = await simulateFillsAsync(orders, txReceipt, value);
await balanceStore.updateBalancesAsync();
balanceStore.assertEquals(expectedBalances);
verifyEvents(txReceipt, orders.map(order => expectedFillEvent(order)), ExchangeEvents.Fill);

View File

@@ -1,3 +1,4 @@
import { DevUtilsContract } from '@0x/contracts-dev-utils';
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
import { DummyERC721TokenContract } from '@0x/contracts-erc721';
import {
@@ -13,9 +14,10 @@ import {
expect,
getLatestBlockTimestampAsync,
getPercentageOfValue,
provider,
toBaseUnitAmount,
} from '@0x/contracts-test-utils';
import { assetDataUtils, ForwarderRevertErrors } from '@0x/order-utils';
import { ForwarderRevertErrors } from '@0x/order-utils';
import { BigNumber } from '@0x/utils';
import { Actor, actorAddressesByName, FeeRecipient, Maker } from '../actors';
@@ -24,6 +26,8 @@ import { DeploymentManager } from '../utils/deployment_manager';
import { deployForwarderAsync } from './deploy_forwarder';
import { ForwarderTestFactory } from './forwarder_test_factory';
const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider);
blockchainTests('Forwarder integration tests', env => {
let deployment: DeploymentManager;
let forwarder: ForwarderContract;
@@ -53,8 +57,8 @@ blockchainTests('Forwarder integration tests', env => {
[makerToken, makerFeeToken, anotherErc20Token] = deployment.tokens.erc20;
[erc721Token] = deployment.tokens.erc721;
wethAssetData = assetDataUtils.encodeERC20AssetData(deployment.tokens.weth.address);
makerAssetData = assetDataUtils.encodeERC20AssetData(makerToken.address);
wethAssetData = await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.weth.address);
makerAssetData = await devUtils.encodeERC20AssetData.callAsync(makerToken.address);
taker = new Actor({ name: 'Taker', deployment });
orderFeeRecipient = new FeeRecipient({
@@ -75,7 +79,7 @@ blockchainTests('Forwarder integration tests', env => {
makerAssetData,
takerAssetData: wethAssetData,
takerFee: constants.ZERO_AMOUNT,
makerFeeAssetData: assetDataUtils.encodeERC20AssetData(makerFeeToken.address),
makerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(makerFeeToken.address),
takerFeeAssetData: wethAssetData,
},
});
@@ -106,6 +110,7 @@ blockchainTests('Forwarder integration tests', env => {
taker,
orderFeeRecipient,
forwarderFeeRecipient,
devUtils,
);
});
@@ -166,7 +171,7 @@ blockchainTests('Forwarder integration tests', env => {
await testFactory.marketSellTestAsync(orders, 1.34);
});
it('should fail to fill an order with a percentage fee if the asset proxy is not yet approved', async () => {
const unapprovedAsset = assetDataUtils.encodeERC20AssetData(anotherErc20Token.address);
const unapprovedAsset = await devUtils.encodeERC20AssetData.callAsync(anotherErc20Token.address);
const order = await maker.signOrderAsync({
makerAssetData: unapprovedAsset,
takerFee: toBaseUnitAmount(2),
@@ -186,7 +191,7 @@ blockchainTests('Forwarder integration tests', env => {
},
);
const expectedBalances = LocalBalanceStore.create(balanceStore);
const expectedBalances = LocalBalanceStore.create(devUtils, balanceStore);
expectedBalances.burnGas(tx.from, DeploymentManager.gasPrice.times(tx.gasUsed));
// Verify balances
@@ -236,7 +241,7 @@ blockchainTests('Forwarder integration tests', env => {
});
it('should fill orders with different makerAssetData', async () => {
const firstOrder = await maker.signOrderAsync();
const secondOrderMakerAssetData = assetDataUtils.encodeERC20AssetData(anotherErc20Token.address);
const secondOrderMakerAssetData = await devUtils.encodeERC20AssetData.callAsync(anotherErc20Token.address);
const secondOrder = await maker.signOrderAsync({
makerAssetData: secondOrderMakerAssetData,
});
@@ -245,7 +250,7 @@ blockchainTests('Forwarder integration tests', env => {
await testFactory.marketSellTestAsync(orders, 1.5);
});
it('should fail to fill an order with a fee denominated in an asset other than makerAsset or WETH', async () => {
const takerFeeAssetData = assetDataUtils.encodeERC20AssetData(anotherErc20Token.address);
const takerFeeAssetData = await devUtils.encodeERC20AssetData.callAsync(anotherErc20Token.address);
const order = await maker.signOrderAsync({
takerFeeAssetData,
takerFee: toBaseUnitAmount(1),
@@ -336,7 +341,7 @@ blockchainTests('Forwarder integration tests', env => {
});
it('should buy exactly makerAssetBuyAmount in orders with different makerAssetData', async () => {
const firstOrder = await maker.signOrderAsync();
const secondOrderMakerAssetData = assetDataUtils.encodeERC20AssetData(anotherErc20Token.address);
const secondOrderMakerAssetData = await devUtils.encodeERC20AssetData.callAsync(anotherErc20Token.address);
const secondOrder = await maker.signOrderAsync({
makerAssetData: secondOrderMakerAssetData,
});
@@ -385,7 +390,7 @@ blockchainTests('Forwarder integration tests', env => {
it('should buy an ERC721 asset from a single order', async () => {
const erc721Order = await maker.signOrderAsync({
makerAssetAmount: new BigNumber(1),
makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, nftId),
makerAssetData: await devUtils.encodeERC721AssetData.callAsync(erc721Token.address, nftId),
takerFeeAssetData: wethAssetData,
});
await testFactory.marketBuyTestAsync([erc721Order], 1);
@@ -393,14 +398,14 @@ blockchainTests('Forwarder integration tests', env => {
it('should buy an ERC721 asset and pay a WETH fee', async () => {
const erc721orderWithWethFee = await maker.signOrderAsync({
makerAssetAmount: new BigNumber(1),
makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, nftId),
makerAssetData: await devUtils.encodeERC721AssetData.callAsync(erc721Token.address, nftId),
takerFee: toBaseUnitAmount(1),
takerFeeAssetData: wethAssetData,
});
await testFactory.marketBuyTestAsync([erc721orderWithWethFee], 1);
});
it('should fail to fill an order with a fee denominated in an asset other than makerAsset or WETH', async () => {
const takerFeeAssetData = assetDataUtils.encodeERC20AssetData(anotherErc20Token.address);
const takerFeeAssetData = await devUtils.encodeERC20AssetData.callAsync(anotherErc20Token.address);
const order = await maker.signOrderAsync({
takerFeeAssetData,
takerFee: toBaseUnitAmount(1),
@@ -491,11 +496,21 @@ blockchainTests('Forwarder integration tests', env => {
);
// Compute expected balances
const expectedBalances = LocalBalanceStore.create(balanceStore);
expectedBalances.transferAsset(maker.address, taker.address, makerAssetFillAmount, makerAssetData);
const expectedBalances = LocalBalanceStore.create(devUtils, balanceStore);
await expectedBalances.transferAssetAsync(
maker.address,
taker.address,
makerAssetFillAmount,
makerAssetData,
);
expectedBalances.wrapEth(taker.address, deployment.tokens.weth.address, ethValue);
expectedBalances.transferAsset(taker.address, maker.address, primaryTakerAssetFillAmount, wethAssetData);
expectedBalances.transferAsset(
await expectedBalances.transferAssetAsync(
taker.address,
maker.address,
primaryTakerAssetFillAmount,
wethAssetData,
);
await expectedBalances.transferAssetAsync(
taker.address,
deployment.staking.stakingProxy.address,
DeploymentManager.protocolFee,
@@ -537,15 +552,15 @@ blockchainTests('Forwarder integration tests', env => {
);
// Compute expected balances
const expectedBalances = LocalBalanceStore.create(balanceStore);
expectedBalances.transferAsset(maker.address, taker.address, makerAssetFillAmount, makerAssetData);
const expectedBalances = LocalBalanceStore.create(devUtils, balanceStore);
expectedBalances.transferAssetAsync(maker.address, taker.address, makerAssetFillAmount, makerAssetData);
expectedBalances.wrapEth(
taker.address,
deployment.tokens.weth.address,
takerAssetFillAmount.plus(DeploymentManager.protocolFee),
);
expectedBalances.transferAsset(taker.address, maker.address, takerAssetFillAmount, wethAssetData);
expectedBalances.transferAsset(
expectedBalances.transferAssetAsync(taker.address, maker.address, takerAssetFillAmount, wethAssetData);
expectedBalances.transferAssetAsync(
taker.address,
deployment.staking.stakingProxy.address,
DeploymentManager.protocolFee,

View File

@@ -1,3 +1,4 @@
import { DevUtilsContract } from '@0x/contracts-dev-utils';
import { BlockchainBalanceStore, LocalBalanceStore } from '@0x/contracts-exchange';
import { ForwarderContract } from '@0x/contracts-exchange-forwarder';
import { constants, expect, getPercentageOfValue, OrderStatus } from '@0x/contracts-test-utils';
@@ -33,6 +34,7 @@ export class ForwarderTestFactory {
private readonly _taker: Actor,
private readonly _orderFeeRecipient: FeeRecipient,
private readonly _forwarderFeeRecipient: FeeRecipient,
private readonly _devUtils: DevUtilsContract,
) {}
public async marketBuyTestAsync(
@@ -157,7 +159,7 @@ export class ForwarderTestFactory {
options: Partial<MarketBuyOptions>,
): Promise<ForwarderFillState> {
await this._balanceStore.updateBalancesAsync();
const balances = LocalBalanceStore.create(this._balanceStore);
const balances = LocalBalanceStore.create(this._devUtils, this._balanceStore);
const currentTotal = {
wethSpentAmount: constants.ZERO_AMOUNT,
makerAssetAcquiredAmount: constants.ZERO_AMOUNT,
@@ -173,7 +175,7 @@ export class ForwarderTestFactory {
continue;
}
const { wethSpentAmount, makerAssetAcquiredAmount } = this._simulateSingleFill(
const { wethSpentAmount, makerAssetAcquiredAmount } = await this._simulateSingleFillAsync(
balances,
order,
ordersInfoBefore[i].orderTakerAssetFilledAmount,
@@ -197,12 +199,12 @@ export class ForwarderTestFactory {
return { ...currentTotal, balances };
}
private _simulateSingleFill(
private async _simulateSingleFillAsync(
balances: LocalBalanceStore,
order: SignedOrder,
takerAssetFilled: BigNumber,
fillFraction: number,
): ForwarderFillState {
): Promise<ForwarderFillState> {
let { makerAssetAmount, takerAssetAmount, makerFee, takerFee } = order;
makerAssetAmount = makerAssetAmount.times(fillFraction).integerValue(BigNumber.ROUND_CEIL);
takerAssetAmount = takerAssetAmount.times(fillFraction).integerValue(BigNumber.ROUND_CEIL);
@@ -236,27 +238,42 @@ export class ForwarderTestFactory {
// (In reality this is done all at once, but we simulate it order by order)
// Maker -> Forwarder
balances.transferAsset(this._maker.address, this._forwarder.address, makerAssetAmount, order.makerAssetData);
await balances.transferAssetAsync(
this._maker.address,
this._forwarder.address,
makerAssetAmount,
order.makerAssetData,
);
// Maker -> Order fee recipient
balances.transferAsset(this._maker.address, this._orderFeeRecipient.address, makerFee, order.makerFeeAssetData);
await balances.transferAssetAsync(
this._maker.address,
this._orderFeeRecipient.address,
makerFee,
order.makerFeeAssetData,
);
// Forwarder -> Maker
balances.transferAsset(this._forwarder.address, this._maker.address, takerAssetAmount, order.takerAssetData);
await balances.transferAssetAsync(
this._forwarder.address,
this._maker.address,
takerAssetAmount,
order.takerAssetData,
);
// Forwarder -> Order fee recipient
balances.transferAsset(
await balances.transferAssetAsync(
this._forwarder.address,
this._orderFeeRecipient.address,
takerFee,
order.takerFeeAssetData,
);
// Forwarder pays the protocol fee in WETH
balances.transferAsset(
await balances.transferAssetAsync(
this._forwarder.address,
this._deployment.staking.stakingProxy.address,
DeploymentManager.protocolFee,
order.takerAssetData,
);
// Forwarder gives acquired maker asset to taker
balances.transferAsset(
await balances.transferAssetAsync(
this._forwarder.address,
this._taker.address,
makerAssetAcquiredAmount,

View File

@@ -1,4 +1,5 @@
import { artifacts as assetProxyArtifacts } from '@0x/contracts-asset-proxy';
import { DevUtilsContract } from '@0x/contracts-dev-utils';
import { IERC20TokenEvents, IERC20TokenTransferEventArgs } from '@0x/contracts-erc20';
import {
artifacts as exchangeArtifacts,
@@ -16,11 +17,12 @@ import {
expect,
getLatestBlockTimestampAsync,
Numberish,
provider,
toBaseUnitAmount,
TransactionHelper,
verifyEvents,
} from '@0x/contracts-test-utils';
import { assetDataUtils, ExchangeRevertErrors, orderHashUtils } from '@0x/order-utils';
import { ExchangeRevertErrors, orderHashUtils } from '@0x/order-utils';
import { FillResults, OrderStatus, SignedOrder } from '@0x/types';
import { BigNumber } from '@0x/utils';
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
@@ -32,6 +34,7 @@ import { DeploymentManager } from '../utils/deployment_manager';
const { addFillResults, safeGetPartialAmountFloor } = ReferenceFunctions;
const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider);
// tslint:disable:no-unnecessary-type-assertion
blockchainTests.resets('Exchange wrappers', env => {
let maker: Maker;
@@ -67,10 +70,10 @@ blockchainTests.resets('Exchange wrappers', env => {
name: 'market maker',
deployment,
orderConfig: {
makerAssetData: assetDataUtils.encodeERC20AssetData(deployment.tokens.erc20[0].address),
takerAssetData: assetDataUtils.encodeERC20AssetData(deployment.tokens.erc20[1].address),
makerFeeAssetData: assetDataUtils.encodeERC20AssetData(deployment.tokens.erc20[2].address),
takerFeeAssetData: assetDataUtils.encodeERC20AssetData(deployment.tokens.erc20[2].address),
makerAssetData: await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.erc20[0].address),
takerAssetData: await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.erc20[1].address),
makerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.erc20[2].address),
takerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.erc20[2].address),
feeRecipientAddress: feeRecipient,
},
});
@@ -106,9 +109,9 @@ blockchainTests.resets('Exchange wrappers', env => {
await blockchainBalances.updateBalancesAsync();
initialLocalBalances = LocalBalanceStore.create(blockchainBalances);
initialLocalBalances = LocalBalanceStore.create(devUtils, blockchainBalances);
wethAssetData = assetDataUtils.encodeERC20AssetData(deployment.tokens.weth.address);
wethAssetData = await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.weth.address);
txHelper = new TransactionHelper(env.web3Wrapper, {
...assetProxyArtifacts,
@@ -118,7 +121,7 @@ blockchainTests.resets('Exchange wrappers', env => {
});
beforeEach(async () => {
localBalances = LocalBalanceStore.create(initialLocalBalances);
localBalances = LocalBalanceStore.create(devUtils, initialLocalBalances);
});
interface SignedOrderWithValidity {
@@ -126,9 +129,13 @@ blockchainTests.resets('Exchange wrappers', env => {
isValid: boolean;
}
function simulateFill(signedOrder: SignedOrder, expectedFillResults: FillResults, shouldUseWeth: boolean): void {
async function simulateFillAsync(
signedOrder: SignedOrder,
expectedFillResults: FillResults,
shouldUseWeth: boolean,
): Promise<void> {
// taker -> maker
localBalances.transferAsset(
await localBalances.transferAssetAsync(
taker.address,
maker.address,
expectedFillResults.takerAssetFilledAmount,
@@ -136,7 +143,7 @@ blockchainTests.resets('Exchange wrappers', env => {
);
// maker -> taker
localBalances.transferAsset(
await localBalances.transferAssetAsync(
maker.address,
taker.address,
expectedFillResults.makerAssetFilledAmount,
@@ -144,7 +151,7 @@ blockchainTests.resets('Exchange wrappers', env => {
);
// maker -> feeRecipient
localBalances.transferAsset(
await localBalances.transferAssetAsync(
maker.address,
feeRecipient,
expectedFillResults.makerFeePaid,
@@ -152,7 +159,7 @@ blockchainTests.resets('Exchange wrappers', env => {
);
// taker -> feeRecipient
localBalances.transferAsset(
await localBalances.transferAssetAsync(
taker.address,
feeRecipient,
expectedFillResults.takerFeePaid,
@@ -161,7 +168,7 @@ blockchainTests.resets('Exchange wrappers', env => {
// taker -> protocol fees
if (shouldUseWeth) {
localBalances.transferAsset(
await localBalances.transferAssetAsync(
taker.address,
deployment.staking.stakingProxy.address,
expectedFillResults.protocolFeePaid,
@@ -332,7 +339,7 @@ blockchainTests.resets('Exchange wrappers', env => {
const shouldPayWethFees = DeploymentManager.protocolFee.gt(value);
// Simulate filling the order
simulateFill(signedOrder, expectedFillResults, shouldPayWethFees);
await simulateFillAsync(signedOrder, expectedFillResults, shouldPayWethFees);
// Ensure that the correct logs were emitted and that the balances are accurate.
await assertResultsAsync(receipt, [{ signedOrder, expectedFillResults, shouldPayWethFees }]);
@@ -430,7 +437,7 @@ blockchainTests.resets('Exchange wrappers', env => {
}
fillTestInfo.push({ signedOrder, expectedFillResults, shouldPayWethFees });
simulateFill(signedOrder, expectedFillResults, shouldPayWethFees);
await simulateFillAsync(signedOrder, expectedFillResults, shouldPayWethFees);
}
const [fillResults, receipt] = await txHelper.getResultAndReceiptAsync(
@@ -492,7 +499,7 @@ blockchainTests.resets('Exchange wrappers', env => {
}
fillTestInfo.push({ signedOrder, expectedFillResults, shouldPayWethFees });
simulateFill(signedOrder, expectedFillResults, shouldPayWethFees);
await simulateFillAsync(signedOrder, expectedFillResults, shouldPayWethFees);
}
const [fillResults, receipt] = await txHelper.getResultAndReceiptAsync(
@@ -583,7 +590,7 @@ blockchainTests.resets('Exchange wrappers', env => {
}
fillTestInfo.push({ signedOrder, expectedFillResults, shouldPayWethFees });
simulateFill(signedOrder, expectedFillResults, shouldPayWethFees);
await simulateFillAsync(signedOrder, expectedFillResults, shouldPayWethFees);
} else {
totalFillResults.push(nullFillResults);
}
@@ -696,7 +703,7 @@ blockchainTests.resets('Exchange wrappers', env => {
takerFillAmount,
);
simulateFill(signedOrder, expectedFillResults, shouldPayWethFees);
await simulateFillAsync(signedOrder, expectedFillResults, shouldPayWethFees);
fillTestInfo.push({ signedOrder, expectedFillResults, shouldPayWethFees });
totalFillResults = addFillResults(totalFillResults, expectedFillResults);
@@ -774,7 +781,9 @@ blockchainTests.resets('Exchange wrappers', env => {
});
it('should fill a signedOrder that does not use the same takerAssetAddress (eth protocol fee)', async () => {
const differentTakerAssetData = assetDataUtils.encodeERC20AssetData(deployment.tokens.erc20[2].address);
const differentTakerAssetData = await devUtils.encodeERC20AssetData.callAsync(
deployment.tokens.erc20[2].address,
);
signedOrders = [
await maker.signOrderAsync(),
@@ -795,7 +804,9 @@ blockchainTests.resets('Exchange wrappers', env => {
});
it('should fill a signedOrder that does not use the same takerAssetAddress (weth protocol fee)', async () => {
const differentTakerAssetData = assetDataUtils.encodeERC20AssetData(deployment.tokens.erc20[2].address);
const differentTakerAssetData = await devUtils.encodeERC20AssetData.callAsync(
deployment.tokens.erc20[2].address,
);
signedOrders = [
await maker.signOrderAsync(),
@@ -890,7 +901,7 @@ blockchainTests.resets('Exchange wrappers', env => {
makerAssetBought,
);
simulateFill(signedOrder, expectedFillResults, shouldPayWethFees);
await simulateFillAsync(signedOrder, expectedFillResults, shouldPayWethFees);
fillTestInfo.push({ signedOrder, expectedFillResults, shouldPayWethFees });
totalFillResults = addFillResults(totalFillResults, expectedFillResults);
@@ -968,7 +979,9 @@ blockchainTests.resets('Exchange wrappers', env => {
});
it('should fill a signedOrder that does not use the same makerAssetAddress (eth protocol fee)', async () => {
const differentMakerAssetData = assetDataUtils.encodeERC20AssetData(deployment.tokens.erc20[2].address);
const differentMakerAssetData = await devUtils.encodeERC20AssetData.callAsync(
deployment.tokens.erc20[2].address,
);
signedOrders = [
await maker.signOrderAsync(),
@@ -990,7 +1003,9 @@ blockchainTests.resets('Exchange wrappers', env => {
});
it('should fill a signedOrder that does not use the same makerAssetAddress (weth protocol fee)', async () => {
const differentMakerAssetData = assetDataUtils.encodeERC20AssetData(deployment.tokens.erc20[2].address);
const differentMakerAssetData = await devUtils.encodeERC20AssetData.callAsync(
deployment.tokens.erc20[2].address,
);
signedOrders = [
await maker.signOrderAsync(),

View File

@@ -1,3 +1,4 @@
import { DevUtilsContract } from '@0x/contracts-dev-utils';
import { IERC20TokenEvents, IERC20TokenTransferEventArgs } from '@0x/contracts-erc20';
import {
BlockchainBalanceStore,
@@ -13,8 +14,8 @@ import {
IStakingEventsRewardsPaidEventArgs,
IStakingEventsStakingPoolEarnedRewardsInEpochEventArgs,
} from '@0x/contracts-staking';
import { blockchainTests, constants, expect, toBaseUnitAmount, verifyEvents } from '@0x/contracts-test-utils';
import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
import { blockchainTests, constants, expect, provider, toBaseUnitAmount, verifyEvents } from '@0x/contracts-test-utils';
import { orderHashUtils } from '@0x/order-utils';
import { SignedOrder } from '@0x/types';
import { BigNumber } from '@0x/utils';
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
@@ -22,6 +23,7 @@ import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
import { actorAddressesByName, FeeRecipient, Maker, OperatorStakerMaker, StakerKeeper, Taker } from '../actors';
import { DeploymentManager } from '../utils/deployment_manager';
const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider);
blockchainTests.resets('fillOrder integration tests', env => {
let deployment: DeploymentManager;
let balanceStore: BlockchainBalanceStore;
@@ -48,10 +50,10 @@ blockchainTests.resets('fillOrder integration tests', env => {
});
const orderConfig = {
feeRecipientAddress: feeRecipient.address,
makerAssetData: assetDataUtils.encodeERC20AssetData(makerToken.address),
takerAssetData: assetDataUtils.encodeERC20AssetData(takerToken.address),
makerFeeAssetData: assetDataUtils.encodeERC20AssetData(makerToken.address),
takerFeeAssetData: assetDataUtils.encodeERC20AssetData(takerToken.address),
makerAssetData: await devUtils.encodeERC20AssetData.callAsync(makerToken.address),
takerAssetData: await devUtils.encodeERC20AssetData.callAsync(takerToken.address),
makerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(makerToken.address),
takerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(takerToken.address),
makerFee: constants.ZERO_AMOUNT,
takerFee: constants.ZERO_AMOUNT,
};
@@ -93,20 +95,30 @@ blockchainTests.resets('fillOrder integration tests', env => {
await balanceStore.updateBalancesAsync();
});
function simulateFill(
async function simulateFillAsync(
order: SignedOrder,
txReceipt: TransactionReceiptWithDecodedLogs,
msgValue?: BigNumber,
): LocalBalanceStore {
): Promise<LocalBalanceStore> {
let remainingValue = msgValue !== undefined ? msgValue : DeploymentManager.protocolFee;
const localBalanceStore = LocalBalanceStore.create(balanceStore);
const localBalanceStore = LocalBalanceStore.create(devUtils, balanceStore);
// Transaction gas cost
localBalanceStore.burnGas(txReceipt.from, DeploymentManager.gasPrice.times(txReceipt.gasUsed));
// Taker -> Maker
localBalanceStore.transferAsset(taker.address, maker.address, order.takerAssetAmount, order.takerAssetData);
await localBalanceStore.transferAssetAsync(
taker.address,
maker.address,
order.takerAssetAmount,
order.takerAssetData,
);
// Maker -> Taker
localBalanceStore.transferAsset(maker.address, taker.address, order.makerAssetAmount, order.makerAssetData);
await localBalanceStore.transferAssetAsync(
maker.address,
taker.address,
order.makerAssetAmount,
order.makerAssetData,
);
// Protocol fee
if (remainingValue.isGreaterThanOrEqualTo(DeploymentManager.protocolFee)) {
@@ -117,11 +129,11 @@ blockchainTests.resets('fillOrder integration tests', env => {
);
remainingValue = remainingValue.minus(DeploymentManager.protocolFee);
} else {
localBalanceStore.transferAsset(
await localBalanceStore.transferAssetAsync(
taker.address,
deployment.staking.stakingProxy.address,
DeploymentManager.protocolFee,
assetDataUtils.encodeERC20AssetData(deployment.tokens.weth.address),
await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.weth.address),
);
}
@@ -178,7 +190,7 @@ blockchainTests.resets('fillOrder integration tests', env => {
const receipt = await taker.fillOrderAsync(order, order.takerAssetAmount);
// Check balances
const expectedBalances = simulateFill(order, receipt);
const expectedBalances = await simulateFillAsync(order, receipt);
await balanceStore.updateBalancesAsync();
balanceStore.assertEquals(expectedBalances);
@@ -204,7 +216,7 @@ blockchainTests.resets('fillOrder integration tests', env => {
const receipt = await taker.fillOrderAsync(order, order.takerAssetAmount);
// Check balances
const expectedBalances = simulateFill(order, receipt);
const expectedBalances = await simulateFillAsync(order, receipt);
await balanceStore.updateBalancesAsync();
balanceStore.assertEquals(expectedBalances);
@@ -237,7 +249,7 @@ blockchainTests.resets('fillOrder integration tests', env => {
// Fetch the current balances
await balanceStore.updateBalancesAsync();
const expectedBalances = LocalBalanceStore.create(balanceStore);
const expectedBalances = LocalBalanceStore.create(devUtils, balanceStore);
// End the epoch. This should wrap the staking proxy's ETH balance.
const endEpochReceipt = await delegator.endEpochAsync();
@@ -279,11 +291,11 @@ blockchainTests.resets('fillOrder integration tests', env => {
const [finalizePoolReceipt] = await delegator.finalizePoolsAsync([poolId]);
// Check balances
expectedBalances.transferAsset(
await expectedBalances.transferAssetAsync(
deployment.staking.stakingProxy.address,
operator.address,
operatorReward,
assetDataUtils.encodeERC20AssetData(deployment.tokens.weth.address),
await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.weth.address),
);
expectedBalances.burnGas(delegator.address, DeploymentManager.gasPrice.times(finalizePoolReceipt.gasUsed));
await balanceStore.updateBalancesAsync();
@@ -340,7 +352,7 @@ blockchainTests.resets('fillOrder integration tests', env => {
const order = await maker.signOrderAsync();
const receipt = await taker.fillOrderAsync(order, order.takerAssetAmount, { value: constants.ZERO_AMOUNT });
const rewardsAvailable = DeploymentManager.protocolFee;
const expectedBalances = simulateFill(order, receipt, constants.ZERO_AMOUNT);
const expectedBalances = await simulateFillAsync(order, receipt, constants.ZERO_AMOUNT);
// End the epoch. This should wrap the staking proxy's ETH balance.
const endEpochReceipt = await delegator.endEpochAsync();
@@ -359,11 +371,11 @@ blockchainTests.resets('fillOrder integration tests', env => {
const [finalizePoolReceipt] = await delegator.finalizePoolsAsync([poolId]);
// Check balances
expectedBalances.transferAsset(
await expectedBalances.transferAssetAsync(
deployment.staking.stakingProxy.address,
operator.address,
operatorReward,
assetDataUtils.encodeERC20AssetData(deployment.tokens.weth.address),
await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.weth.address),
);
expectedBalances.burnGas(delegator.address, DeploymentManager.gasPrice.times(finalizePoolReceipt.gasUsed));
await balanceStore.updateBalancesAsync();