@0x:contracts-integrations
Added a sanity check for different token types
This commit is contained in:
parent
4e50b9b479
commit
301b5e1721
@ -1,3 +1,4 @@
|
|||||||
|
import { ERC1155MintableContract } from '@0x/contracts-erc1155';
|
||||||
import { DummyERC20TokenContract, WETH9Contract } from '@0x/contracts-erc20';
|
import { DummyERC20TokenContract, WETH9Contract } from '@0x/contracts-erc20';
|
||||||
import { DummyERC721TokenContract } from '@0x/contracts-erc721';
|
import { DummyERC721TokenContract } from '@0x/contracts-erc721';
|
||||||
import { constants, getRandomInteger, TransactionFactory } from '@0x/contracts-test-utils';
|
import { constants, getRandomInteger, TransactionFactory } from '@0x/contracts-test-utils';
|
||||||
@ -95,6 +96,37 @@ export class Actor {
|
|||||||
return tokenIds;
|
return tokenIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mints some number of ERC1115 fungible tokens and approves a spender (defaults to the ERC1155 asset proxy)
|
||||||
|
* to transfer the token.
|
||||||
|
*/
|
||||||
|
public async configureERC1155TokenAsync(
|
||||||
|
token: ERC1155MintableContract,
|
||||||
|
spender?: string,
|
||||||
|
amount?: BigNumber,
|
||||||
|
): Promise<BigNumber> {
|
||||||
|
// Create a fungible token.
|
||||||
|
const id = await token.create.callAsync('', false, { from: this.address });
|
||||||
|
await token.create.awaitTransactionSuccessAsync('', false, { from: this.address });
|
||||||
|
|
||||||
|
// Mint the token
|
||||||
|
await token.mintFungible.awaitTransactionSuccessAsync(
|
||||||
|
id,
|
||||||
|
[this.address],
|
||||||
|
[amount || constants.INITIAL_ERC20_BALANCE],
|
||||||
|
{ from: this.address },
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set approval for all token types for the spender.
|
||||||
|
await token.setApprovalForAll.awaitTransactionSuccessAsync(
|
||||||
|
spender || this.deployment.assetProxies.erc1155Proxy.address,
|
||||||
|
true,
|
||||||
|
{ from: this.address },
|
||||||
|
);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signs a transaction.
|
* Signs a transaction.
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { DevUtilsContract } from '@0x/contracts-dev-utils';
|
import { DevUtilsContract } from '@0x/contracts-dev-utils';
|
||||||
import { BlockchainBalanceStore } from '@0x/contracts-exchange';
|
import { BlockchainBalanceStore, TokenIds } from '@0x/contracts-exchange';
|
||||||
import { ReferenceFunctions as LibReferenceFunctions } from '@0x/contracts-exchange-libs';
|
import { ReferenceFunctions as LibReferenceFunctions } from '@0x/contracts-exchange-libs';
|
||||||
import { toBaseUnitAmount } from '@0x/contracts-staking';
|
import { toBaseUnitAmount } from '@0x/contracts-staking';
|
||||||
import { blockchainTests, constants, expect } from '@0x/contracts-test-utils';
|
import { blockchainTests, constants, expect } from '@0x/contracts-test-utils';
|
||||||
@ -17,23 +17,29 @@ const { isRoundingErrorCeil, isRoundingErrorFloor } = LibReferenceFunctions;
|
|||||||
|
|
||||||
const ZERO = constants.ZERO_AMOUNT;
|
const ZERO = constants.ZERO_AMOUNT;
|
||||||
|
|
||||||
blockchainTests.resets.only('matchOrders', env => {
|
blockchainTests.resets('matchOrders', env => {
|
||||||
|
// The fee recipient addresses.
|
||||||
let feeRecipientLeft: Actor;
|
let feeRecipientLeft: Actor;
|
||||||
let feeRecipientRight: Actor;
|
let feeRecipientRight: Actor;
|
||||||
|
|
||||||
|
// The address that should be responsible for matching orders.
|
||||||
let matcher: Actor;
|
let matcher: Actor;
|
||||||
|
|
||||||
|
// Market makers who have opposite maker and taker assets.
|
||||||
let makerLeft: Maker;
|
let makerLeft: Maker;
|
||||||
let makerRight: Maker;
|
let makerRight: Maker;
|
||||||
|
|
||||||
|
// The addresses of important assets for testing.
|
||||||
let makerAssetAddressLeft: string;
|
let makerAssetAddressLeft: string;
|
||||||
let makerAssetAddressRight: string;
|
let makerAssetAddressRight: string;
|
||||||
let feeAssetAddress: string;
|
let feeAssetAddress: string;
|
||||||
|
|
||||||
|
let deployment: DeploymentManager;
|
||||||
let matchOrderTester: MatchOrderTester;
|
let matchOrderTester: MatchOrderTester;
|
||||||
|
|
||||||
const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider, txDefaults);
|
const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, env.provider, env.txDefaults);
|
||||||
let deployment: DeploymentManager;
|
let leftId: BigNumber;
|
||||||
|
let rightId: BigNumber;
|
||||||
|
|
||||||
const PROTOCOL_FEE = DeploymentManager.protocolFeeMultiplier.times(constants.DEFAULT_GAS_PRICE);
|
const PROTOCOL_FEE = DeploymentManager.protocolFeeMultiplier.times(constants.DEFAULT_GAS_PRICE);
|
||||||
|
|
||||||
@ -99,6 +105,13 @@ blockchainTests.resets.only('matchOrders', env => {
|
|||||||
feeRecipientRight.configureERC20TokenAsync(deployment.tokens.weth),
|
feeRecipientRight.configureERC20TokenAsync(deployment.tokens.weth),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
leftId = await makerLeft.configureERC1155TokenAsync(deployment.tokens.erc1155[0]);
|
||||||
|
[rightId] = await makerRight.configureERC721TokenAsync(deployment.tokens.erc721[0]);
|
||||||
|
|
||||||
|
const tokenIds: TokenIds = { erc721: {}, erc1155: {} };
|
||||||
|
tokenIds.erc1155[deployment.tokens.erc1155[0].address] = { fungible: [leftId], nonFungible: [] };
|
||||||
|
tokenIds.erc721[deployment.tokens.erc721[0].address] = [rightId];
|
||||||
|
|
||||||
const blockchainBalanceStore = new BlockchainBalanceStore(
|
const blockchainBalanceStore = new BlockchainBalanceStore(
|
||||||
{
|
{
|
||||||
feeRecipientLeft: feeRecipientLeft.address,
|
feeRecipientLeft: feeRecipientLeft.address,
|
||||||
@ -115,8 +128,14 @@ blockchainTests.resets.only('matchOrders', env => {
|
|||||||
feeToken: deployment.tokens.erc20[2],
|
feeToken: deployment.tokens.erc20[2],
|
||||||
weth: deployment.tokens.weth,
|
weth: deployment.tokens.weth,
|
||||||
},
|
},
|
||||||
|
erc721: {
|
||||||
|
token: deployment.tokens.erc721[0],
|
||||||
|
},
|
||||||
|
erc1155: {
|
||||||
|
token: deployment.tokens.erc1155[0],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{},
|
tokenIds,
|
||||||
);
|
);
|
||||||
|
|
||||||
matchOrderTester = new MatchOrderTester(deployment, blockchainBalanceStore);
|
matchOrderTester = new MatchOrderTester(deployment, blockchainBalanceStore);
|
||||||
@ -2418,39 +2437,6 @@ blockchainTests.resets.only('matchOrders', env => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/* FIXME
|
|
||||||
const leftMakerAssetAmount = _.includes(fungibleTypes, combo.leftMaker)
|
|
||||||
? toBaseUnitAmount(15, 18)
|
|
||||||
: toBaseUnitAmount(1, 0);
|
|
||||||
const leftTakerAssetAmount = _.includes(fungibleTypes, combo.rightMaker)
|
|
||||||
? toBaseUnitAmount(30, 18)
|
|
||||||
: toBaseUnitAmount(1, 0);
|
|
||||||
const rightMakerAssetAmount = _.includes(fungibleTypes, combo.rightMaker)
|
|
||||||
? toBaseUnitAmount(30, 18)
|
|
||||||
: toBaseUnitAmount(1, 0);
|
|
||||||
const rightTakerAssetAmount = _.includes(fungibleTypes, combo.leftMaker)
|
|
||||||
? toBaseUnitAmount(14, 18)
|
|
||||||
: toBaseUnitAmount(1, 0);
|
|
||||||
const leftMakerFeeAssetAmount = _.includes(fungibleTypes, combo.leftMakerFee)
|
|
||||||
? toBaseUnitAmount(8, 12)
|
|
||||||
: toBaseUnitAmount(1, 0);
|
|
||||||
const rightMakerFeeAssetAmount = _.includes(fungibleTypes, combo.rightMakerFee)
|
|
||||||
? toBaseUnitAmount(7, 12)
|
|
||||||
: toBaseUnitAmount(1, 0);
|
|
||||||
const leftTakerFeeAssetAmount = _.includes(fungibleTypes, combo.leftTakerFee)
|
|
||||||
? toBaseUnitAmount(6, 12)
|
|
||||||
: toBaseUnitAmount(1, 0);
|
|
||||||
const rightTakerFeeAssetAmount = _.includes(fungibleTypes, combo.rightTakerFee)
|
|
||||||
? toBaseUnitAmount(5, 12)
|
|
||||||
: toBaseUnitAmount(1, 0);
|
|
||||||
const leftMakerAssetReceivedByTakerAmount = _.includes(fungibleTypes, combo.leftMaker)
|
|
||||||
? leftMakerAssetAmount.minus(rightTakerAssetAmount)
|
|
||||||
: toBaseUnitAmount(0, 0);
|
|
||||||
const rightMakerAssetReceivedByTakerAmount = _.includes(fungibleTypes, combo.leftMaker)
|
|
||||||
? rightMakerAssetAmount.minus(leftTakerAssetAmount)
|
|
||||||
: toBaseUnitAmount(0, 0);
|
|
||||||
*/
|
|
||||||
|
|
||||||
describe('batchMatchOrders and batchMatchOrdersWithMaximalFill rich errors', async () => {
|
describe('batchMatchOrders and batchMatchOrdersWithMaximalFill rich errors', async () => {
|
||||||
it('should fail if there are zero leftOrders with the ZeroLeftOrders rich error reason', async () => {
|
it('should fail if there are zero leftOrders with the ZeroLeftOrders rich error reason', async () => {
|
||||||
const leftOrders: SignedOrder[] = [];
|
const leftOrders: SignedOrder[] = [];
|
||||||
@ -3149,5 +3135,58 @@ blockchainTests.resets.only('matchOrders', env => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('token sanity checks', () => {
|
||||||
|
it('should be able to match ERC721 tokens with ERC1155 tokens', async () => {
|
||||||
|
const leftMakerAssetData = assetDataUtils.encodeERC1155AssetData(
|
||||||
|
deployment.tokens.erc1155[0].address,
|
||||||
|
[leftId],
|
||||||
|
[new BigNumber(1)],
|
||||||
|
'0x',
|
||||||
|
);
|
||||||
|
const rightMakerAssetData = assetDataUtils.encodeERC721AssetData(
|
||||||
|
deployment.tokens.erc721[0].address,
|
||||||
|
rightId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const signedOrderLeft = await makerLeft.signOrderAsync({
|
||||||
|
makerAssetAmount: toBaseUnitAmount(100, 0),
|
||||||
|
takerAssetAmount: toBaseUnitAmount(1, 0),
|
||||||
|
makerAssetData: leftMakerAssetData,
|
||||||
|
takerAssetData: rightMakerAssetData,
|
||||||
|
});
|
||||||
|
const signedOrderRight = await makerRight.signOrderAsync({
|
||||||
|
makerAssetAmount: toBaseUnitAmount(1, 0),
|
||||||
|
takerAssetAmount: toBaseUnitAmount(100, 0),
|
||||||
|
makerAssetData: rightMakerAssetData,
|
||||||
|
takerAssetData: leftMakerAssetData,
|
||||||
|
});
|
||||||
|
|
||||||
|
const expectedTransferAmounts = {
|
||||||
|
// Left Maker
|
||||||
|
leftMakerAssetSoldByLeftMakerAmount: toBaseUnitAmount(100, 0),
|
||||||
|
leftMakerFeeAssetPaidByLeftMakerAmount: toBaseUnitAmount(100, 16), // 100%
|
||||||
|
// Right Maker
|
||||||
|
rightMakerAssetSoldByRightMakerAmount: toBaseUnitAmount(1, 0),
|
||||||
|
rightMakerFeeAssetPaidByRightMakerAmount: toBaseUnitAmount(100, 16), // 100%
|
||||||
|
// Taker
|
||||||
|
leftTakerFeeAssetPaidByTakerAmount: toBaseUnitAmount(100, 16), // 100%
|
||||||
|
rightTakerFeeAssetPaidByTakerAmount: toBaseUnitAmount(100, 16), // 100%
|
||||||
|
leftProtocolFeePaidByTakerAmount: PROTOCOL_FEE,
|
||||||
|
rightProtocolFeePaidByTakerAmount: PROTOCOL_FEE,
|
||||||
|
};
|
||||||
|
|
||||||
|
await matchOrderTester.matchOrdersAndAssertEffectsAsync(
|
||||||
|
{
|
||||||
|
leftOrder: signedOrderLeft,
|
||||||
|
rightOrder: signedOrderRight,
|
||||||
|
},
|
||||||
|
expectedTransferAmounts,
|
||||||
|
matcher.address,
|
||||||
|
PROTOCOL_FEE.times(2),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
// tslint:disable-line:max-file-line-count
|
// tslint:disable-line:max-file-line-count
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { DevUtilsContract } from '@0x/contracts-dev-utils';
|
import { DevUtilsContract } from '@0x/contracts-dev-utils';
|
||||||
import { BlockchainBalanceStore, ExchangeContract, LocalBalanceStore } from '@0x/contracts-exchange';
|
import { BlockchainBalanceStore, ExchangeContract, LocalBalanceStore } from '@0x/contracts-exchange';
|
||||||
import { constants, expect, OrderStatus } from '@0x/contracts-test-utils';
|
import { constants, expect, OrderStatus, TransactionHelper } from '@0x/contracts-test-utils';
|
||||||
import { orderHashUtils } from '@0x/order-utils';
|
import { orderHashUtils } from '@0x/order-utils';
|
||||||
import { BatchMatchedFillResults, FillResults, MatchedFillResults, SignedOrder } from '@0x/types';
|
import { BatchMatchedFillResults, FillResults, MatchedFillResults, SignedOrder } from '@0x/types';
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
@ -244,9 +244,9 @@ export class MatchOrderTester {
|
|||||||
orders,
|
orders,
|
||||||
takerAddress,
|
takerAddress,
|
||||||
this._deployment.staking.stakingProxy.address,
|
this._deployment.staking.stakingProxy.address,
|
||||||
this._blockchainBalanceStore,
|
|
||||||
toFullMatchTransferAmounts(expectedTransferAmounts),
|
toFullMatchTransferAmounts(expectedTransferAmounts),
|
||||||
this._devUtils,
|
this._devUtils,
|
||||||
|
this._blockchainBalanceStore,
|
||||||
localBalanceStore,
|
localBalanceStore,
|
||||||
);
|
);
|
||||||
const expectedResults = convertToMatchResults(expectedMatchResults);
|
const expectedResults = convertToMatchResults(expectedMatchResults);
|
||||||
@ -377,16 +377,15 @@ async function simulateBatchMatchOrdersAsync(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME - These arguments should be reordered
|
|
||||||
// Add the latest match to the batch match results
|
// Add the latest match to the batch match results
|
||||||
batchMatchResults.matches.push(
|
batchMatchResults.matches.push(
|
||||||
await simulateMatchOrdersAsync(
|
await simulateMatchOrdersAsync(
|
||||||
matchedOrders,
|
matchedOrders,
|
||||||
takerAddress,
|
takerAddress,
|
||||||
stakingProxyAddress,
|
stakingProxyAddress,
|
||||||
blockchainBalanceStore,
|
|
||||||
toFullMatchTransferAmounts(transferAmounts[i]),
|
toFullMatchTransferAmounts(transferAmounts[i]),
|
||||||
devUtils,
|
devUtils,
|
||||||
|
blockchainBalanceStore,
|
||||||
localBalanceStore,
|
localBalanceStore,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -434,7 +433,6 @@ async function simulateBatchMatchOrdersAsync(
|
|||||||
return batchMatchResults;
|
return batchMatchResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME - Is it possible to remove `transferAmounts`
|
|
||||||
/**
|
/**
|
||||||
* Simulates matching two orders by transferring amounts defined in
|
* Simulates matching two orders by transferring amounts defined in
|
||||||
* `transferAmounts` and returns the results.
|
* `transferAmounts` and returns the results.
|
||||||
@ -448,9 +446,9 @@ async function simulateMatchOrdersAsync(
|
|||||||
orders: MatchedOrders,
|
orders: MatchedOrders,
|
||||||
takerAddress: string,
|
takerAddress: string,
|
||||||
stakingProxyAddress: string,
|
stakingProxyAddress: string,
|
||||||
blockchainBalanceStore: BlockchainBalanceStore, // FIXME - Is this right?
|
|
||||||
transferAmounts: MatchTransferAmounts,
|
transferAmounts: MatchTransferAmounts,
|
||||||
devUtils: DevUtilsContract,
|
devUtils: DevUtilsContract,
|
||||||
|
blockchainBalanceStore: BlockchainBalanceStore,
|
||||||
localBalanceStore: LocalBalanceStore,
|
localBalanceStore: LocalBalanceStore,
|
||||||
): Promise<MatchResults> {
|
): Promise<MatchResults> {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
@ -478,7 +476,6 @@ async function simulateMatchOrdersAsync(
|
|||||||
orders.rightOrder.makerAssetData,
|
orders.rightOrder.makerAssetData,
|
||||||
);
|
);
|
||||||
|
|
||||||
// FIXME - Is this a necessary condition?
|
|
||||||
if (orders.leftOrder.makerAddress !== orders.leftOrder.feeRecipientAddress) {
|
if (orders.leftOrder.makerAddress !== orders.leftOrder.feeRecipientAddress) {
|
||||||
// Left maker fees
|
// Left maker fees
|
||||||
localBalanceStore.transferAsset(
|
localBalanceStore.transferAsset(
|
||||||
@ -489,7 +486,6 @@ async function simulateMatchOrdersAsync(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME - Is this a necessary condition?
|
|
||||||
// Left maker asset -> right maker
|
// Left maker asset -> right maker
|
||||||
localBalanceStore.transferAsset(
|
localBalanceStore.transferAsset(
|
||||||
orders.leftOrder.makerAddress,
|
orders.leftOrder.makerAddress,
|
||||||
@ -498,7 +494,6 @@ async function simulateMatchOrdersAsync(
|
|||||||
orders.leftOrder.makerAssetData,
|
orders.leftOrder.makerAssetData,
|
||||||
);
|
);
|
||||||
|
|
||||||
// FIXME - Is this a necessary condition?
|
|
||||||
if (orders.rightOrder.makerAddress !== orders.rightOrder.feeRecipientAddress) {
|
if (orders.rightOrder.makerAddress !== orders.rightOrder.feeRecipientAddress) {
|
||||||
// Right maker fees
|
// Right maker fees
|
||||||
localBalanceStore.transferAsset(
|
localBalanceStore.transferAsset(
|
||||||
@ -676,7 +671,6 @@ function simulateFillEvents(
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME - Refactor this to use filterToLogsArguments
|
|
||||||
/**
|
/**
|
||||||
* Extract `Fill` events from a transaction receipt.
|
* Extract `Fill` events from a transaction receipt.
|
||||||
*/
|
*/
|
||||||
@ -830,7 +824,6 @@ function getLastMatch(batchMatchResults: BatchMatchResults): MatchResults {
|
|||||||
return batchMatchResults.matches[batchMatchResults.matches.length - 1];
|
return batchMatchResults.matches[batchMatchResults.matches.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME - This can probably be removed in favor of the reference functions.
|
|
||||||
/**
|
/**
|
||||||
* Add a new fill results object to a total fill results object destructively.
|
* Add a new fill results object to a total fill results object destructively.
|
||||||
* @param total The total fill results that should be updated.
|
* @param total The total fill results that should be updated.
|
||||||
@ -841,6 +834,7 @@ function addFillResults(total: FillEventArgs, fill: FillEventArgs): void {
|
|||||||
expect(total.orderHash).to.be.eq(fill.orderHash);
|
expect(total.orderHash).to.be.eq(fill.orderHash);
|
||||||
expect(total.makerAddress).to.be.eq(fill.makerAddress);
|
expect(total.makerAddress).to.be.eq(fill.makerAddress);
|
||||||
expect(total.takerAddress).to.be.eq(fill.takerAddress);
|
expect(total.takerAddress).to.be.eq(fill.takerAddress);
|
||||||
|
|
||||||
// Add the fill results together
|
// Add the fill results together
|
||||||
total.makerAssetFilledAmount = total.makerAssetFilledAmount.plus(fill.makerAssetFilledAmount);
|
total.makerAssetFilledAmount = total.makerAssetFilledAmount.plus(fill.makerAssetFilledAmount);
|
||||||
total.takerAssetFilledAmount = total.takerAssetFilledAmount.plus(fill.takerAssetFilledAmount);
|
total.takerAssetFilledAmount = total.takerAssetFilledAmount.plus(fill.takerAssetFilledAmount);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user