Add return value checks to wrapper tests
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
|||||||
chaiSetup,
|
chaiSetup,
|
||||||
constants,
|
constants,
|
||||||
ERC20BalancesByOwner,
|
ERC20BalancesByOwner,
|
||||||
|
FillResults,
|
||||||
getLatestBlockTimestampAsync,
|
getLatestBlockTimestampAsync,
|
||||||
increaseTimeAndMineBlockAsync,
|
increaseTimeAndMineBlockAsync,
|
||||||
OrderFactory,
|
OrderFactory,
|
||||||
@@ -64,6 +65,13 @@ describe('Exchange wrappers', () => {
|
|||||||
let defaultTakerAssetAddress: string;
|
let defaultTakerAssetAddress: string;
|
||||||
let defaultFeeAssetAddress: string;
|
let defaultFeeAssetAddress: string;
|
||||||
|
|
||||||
|
const nullFillResults: FillResults = {
|
||||||
|
makerAssetFilledAmount: new BigNumber(0),
|
||||||
|
takerAssetFilledAmount: new BigNumber(0),
|
||||||
|
makerFeePaid: new BigNumber(0),
|
||||||
|
takerFeePaid: new BigNumber(0),
|
||||||
|
};
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
await blockchainLifecycle.startAsync();
|
await blockchainLifecycle.startAsync();
|
||||||
});
|
});
|
||||||
@@ -152,7 +160,7 @@ describe('Exchange wrappers', () => {
|
|||||||
});
|
});
|
||||||
describe('fillOrKillOrder', () => {
|
describe('fillOrKillOrder', () => {
|
||||||
const reentrancyTest = (functionNames: string[]) => {
|
const reentrancyTest = (functionNames: string[]) => {
|
||||||
_.forEach(functionNames, async (functionName: string, functionId: number) => {
|
for (const [functionId, functionName] of functionNames.entries()) {
|
||||||
const description = `should not allow fillOrKillOrder to reenter the Exchange contract via ${functionName}`;
|
const description = `should not allow fillOrKillOrder to reenter the Exchange contract via ${functionName}`;
|
||||||
it(description, async () => {
|
it(description, async () => {
|
||||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||||
@@ -165,7 +173,7 @@ describe('Exchange wrappers', () => {
|
|||||||
const tx = exchangeWrapper.fillOrKillOrderAsync(signedOrder, takerAddress);
|
const tx = exchangeWrapper.fillOrKillOrderAsync(signedOrder, takerAddress);
|
||||||
return expect(tx).to.revertWith(RevertReason.ReentrancyIllegal);
|
return expect(tx).to.revertWith(RevertReason.ReentrancyIllegal);
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
describe('fillOrKillOrder reentrancy tests', () => reentrancyTest(exchangeConstants.FUNCTIONS_WITH_MUTEX));
|
describe('fillOrKillOrder reentrancy tests', () => reentrancyTest(exchangeConstants.FUNCTIONS_WITH_MUTEX));
|
||||||
|
|
||||||
@@ -175,10 +183,16 @@ describe('Exchange wrappers', () => {
|
|||||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(200), 18),
|
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(200), 18),
|
||||||
});
|
});
|
||||||
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
||||||
|
|
||||||
|
const fillResults = await exchange.fillOrKillOrder.callAsync(
|
||||||
|
signedOrder,
|
||||||
|
takerAssetFillAmount,
|
||||||
|
signedOrder.signature,
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.fillOrKillOrderAsync(signedOrder, takerAddress, {
|
await exchangeWrapper.fillOrKillOrderAsync(signedOrder, takerAddress, {
|
||||||
takerAssetFillAmount,
|
takerAssetFillAmount,
|
||||||
});
|
});
|
||||||
|
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
const makerAssetFilledAmount = takerAssetFillAmount
|
const makerAssetFilledAmount = takerAssetFillAmount
|
||||||
@@ -190,6 +204,12 @@ describe('Exchange wrappers', () => {
|
|||||||
const takerFee = signedOrder.takerFee
|
const takerFee = signedOrder.takerFee
|
||||||
.times(makerAssetFilledAmount)
|
.times(makerAssetFilledAmount)
|
||||||
.dividedToIntegerBy(signedOrder.makerAssetAmount);
|
.dividedToIntegerBy(signedOrder.makerAssetAmount);
|
||||||
|
|
||||||
|
expect(fillResults.makerAssetFilledAmount).to.bignumber.equal(makerAssetFilledAmount);
|
||||||
|
expect(fillResults.takerAssetFilledAmount).to.bignumber.equal(takerAssetFillAmount);
|
||||||
|
expect(fillResults.makerFeePaid).to.bignumber.equal(makerFee);
|
||||||
|
expect(fillResults.takerFeePaid).to.bignumber.equal(takerFee);
|
||||||
|
|
||||||
expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
|
expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
|
||||||
erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFilledAmount),
|
erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFilledAmount),
|
||||||
);
|
);
|
||||||
@@ -240,7 +260,7 @@ describe('Exchange wrappers', () => {
|
|||||||
|
|
||||||
describe('fillOrderNoThrow', () => {
|
describe('fillOrderNoThrow', () => {
|
||||||
const reentrancyTest = (functionNames: string[]) => {
|
const reentrancyTest = (functionNames: string[]) => {
|
||||||
_.forEach(functionNames, async (functionName: string, functionId: number) => {
|
for (const [functionId, functionName] of functionNames.entries()) {
|
||||||
const description = `should not allow fillOrderNoThrow to reenter the Exchange contract via ${functionName}`;
|
const description = `should not allow fillOrderNoThrow to reenter the Exchange contract via ${functionName}`;
|
||||||
it(description, async () => {
|
it(description, async () => {
|
||||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||||
@@ -254,7 +274,7 @@ describe('Exchange wrappers', () => {
|
|||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
expect(erc20Balances).to.deep.equal(newBalances);
|
expect(erc20Balances).to.deep.equal(newBalances);
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
describe('fillOrderNoThrow reentrancy tests', () => reentrancyTest(exchangeConstants.FUNCTIONS_WITH_MUTEX));
|
describe('fillOrderNoThrow reentrancy tests', () => reentrancyTest(exchangeConstants.FUNCTIONS_WITH_MUTEX));
|
||||||
|
|
||||||
@@ -265,6 +285,12 @@ describe('Exchange wrappers', () => {
|
|||||||
});
|
});
|
||||||
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
||||||
|
|
||||||
|
const fillResults = await exchange.fillOrderNoThrow.callAsync(
|
||||||
|
signedOrder,
|
||||||
|
takerAssetFillAmount,
|
||||||
|
signedOrder.signature,
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress, {
|
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress, {
|
||||||
takerAssetFillAmount,
|
takerAssetFillAmount,
|
||||||
// HACK(albrow): We need to hardcode the gas estimate here because
|
// HACK(albrow): We need to hardcode the gas estimate here because
|
||||||
@@ -272,8 +298,8 @@ describe('Exchange wrappers', () => {
|
|||||||
// delegatecall and swallow errors.
|
// delegatecall and swallow errors.
|
||||||
gas: 250000,
|
gas: 250000,
|
||||||
});
|
});
|
||||||
|
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
const makerAssetFilledAmount = takerAssetFillAmount
|
const makerAssetFilledAmount = takerAssetFillAmount
|
||||||
.times(signedOrder.makerAssetAmount)
|
.times(signedOrder.makerAssetAmount)
|
||||||
.dividedToIntegerBy(signedOrder.takerAssetAmount);
|
.dividedToIntegerBy(signedOrder.takerAssetAmount);
|
||||||
@@ -284,6 +310,11 @@ describe('Exchange wrappers', () => {
|
|||||||
.times(makerAssetFilledAmount)
|
.times(makerAssetFilledAmount)
|
||||||
.dividedToIntegerBy(signedOrder.makerAssetAmount);
|
.dividedToIntegerBy(signedOrder.makerAssetAmount);
|
||||||
|
|
||||||
|
expect(fillResults.makerAssetFilledAmount).to.bignumber.equal(makerAssetFilledAmount);
|
||||||
|
expect(fillResults.takerAssetFilledAmount).to.bignumber.equal(takerAssetFillAmount);
|
||||||
|
expect(fillResults.makerFeePaid).to.bignumber.equal(makerFee);
|
||||||
|
expect(fillResults.takerFeePaid).to.bignumber.equal(takerFee);
|
||||||
|
|
||||||
expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
|
expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
|
||||||
erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFilledAmount),
|
erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFilledAmount),
|
||||||
);
|
);
|
||||||
@@ -312,8 +343,16 @@ describe('Exchange wrappers', () => {
|
|||||||
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100000), 18),
|
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100000), 18),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const fillResults = await exchange.fillOrderNoThrow.callAsync(
|
||||||
|
signedOrder,
|
||||||
|
signedOrder.takerAssetAmount,
|
||||||
|
signedOrder.signature,
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress);
|
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress);
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
|
expect(fillResults).to.deep.equal(nullFillResults);
|
||||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -322,19 +361,34 @@ describe('Exchange wrappers', () => {
|
|||||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100000), 18),
|
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100000), 18),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const fillResults = await exchange.fillOrderNoThrow.callAsync(
|
||||||
|
signedOrder,
|
||||||
|
signedOrder.takerAssetAmount,
|
||||||
|
signedOrder.signature,
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress);
|
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress);
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
|
expect(fillResults).to.deep.equal(nullFillResults);
|
||||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not change erc20Balances if maker allowances are too low to fill order', async () => {
|
it('should not change erc20Balances if maker allowances are too low to fill order', async () => {
|
||||||
const signedOrder = await orderFactory.newSignedOrderAsync();
|
const signedOrder = await orderFactory.newSignedOrderAsync();
|
||||||
|
|
||||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||||
await erc20TokenA.approve.sendTransactionAsync(erc20Proxy.address, new BigNumber(0), {
|
await erc20TokenA.approve.sendTransactionAsync(erc20Proxy.address, new BigNumber(0), {
|
||||||
from: makerAddress,
|
from: makerAddress,
|
||||||
}),
|
}),
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
|
const fillResults = await exchange.fillOrderNoThrow.callAsync(
|
||||||
|
signedOrder,
|
||||||
|
signedOrder.takerAssetAmount,
|
||||||
|
signedOrder.signature,
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress);
|
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress);
|
||||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||||
await erc20TokenA.approve.sendTransactionAsync(erc20Proxy.address, constants.INITIAL_ERC20_ALLOWANCE, {
|
await erc20TokenA.approve.sendTransactionAsync(erc20Proxy.address, constants.INITIAL_ERC20_ALLOWANCE, {
|
||||||
@@ -342,19 +396,27 @@ describe('Exchange wrappers', () => {
|
|||||||
}),
|
}),
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
|
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
|
expect(fillResults).to.deep.equal(nullFillResults);
|
||||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not change erc20Balances if taker allowances are too low to fill order', async () => {
|
it('should not change erc20Balances if taker allowances are too low to fill order', async () => {
|
||||||
const signedOrder = await orderFactory.newSignedOrderAsync();
|
const signedOrder = await orderFactory.newSignedOrderAsync();
|
||||||
|
|
||||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||||
await erc20TokenB.approve.sendTransactionAsync(erc20Proxy.address, new BigNumber(0), {
|
await erc20TokenB.approve.sendTransactionAsync(erc20Proxy.address, new BigNumber(0), {
|
||||||
from: takerAddress,
|
from: takerAddress,
|
||||||
}),
|
}),
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
|
const fillResults = await exchange.fillOrderNoThrow.callAsync(
|
||||||
|
signedOrder,
|
||||||
|
signedOrder.takerAssetAmount,
|
||||||
|
signedOrder.signature,
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress);
|
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress);
|
||||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||||
await erc20TokenB.approve.sendTransactionAsync(erc20Proxy.address, constants.INITIAL_ERC20_ALLOWANCE, {
|
await erc20TokenB.approve.sendTransactionAsync(erc20Proxy.address, constants.INITIAL_ERC20_ALLOWANCE, {
|
||||||
@@ -362,8 +424,9 @@ describe('Exchange wrappers', () => {
|
|||||||
}),
|
}),
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
|
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
|
expect(fillResults).to.deep.equal(nullFillResults);
|
||||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -374,8 +437,17 @@ describe('Exchange wrappers', () => {
|
|||||||
makerFee: new BigNumber(1),
|
makerFee: new BigNumber(1),
|
||||||
makerAssetData: assetDataUtils.encodeERC20AssetData(feeToken.address),
|
makerAssetData: assetDataUtils.encodeERC20AssetData(feeToken.address),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const fillResults = await exchange.fillOrderNoThrow.callAsync(
|
||||||
|
signedOrder,
|
||||||
|
signedOrder.takerAssetAmount,
|
||||||
|
signedOrder.signature,
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress);
|
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress);
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
|
expect(fillResults).to.deep.equal(nullFillResults);
|
||||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -398,8 +470,17 @@ describe('Exchange wrappers', () => {
|
|||||||
takerFee: new BigNumber(1),
|
takerFee: new BigNumber(1),
|
||||||
takerAssetData: assetDataUtils.encodeERC20AssetData(feeToken.address),
|
takerAssetData: assetDataUtils.encodeERC20AssetData(feeToken.address),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const fillResults = await exchange.fillOrderNoThrow.callAsync(
|
||||||
|
signedOrder,
|
||||||
|
signedOrder.takerAssetAmount,
|
||||||
|
signedOrder.signature,
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress);
|
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress);
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
|
expect(fillResults).to.deep.equal(nullFillResults);
|
||||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -410,8 +491,17 @@ describe('Exchange wrappers', () => {
|
|||||||
takerFee: new BigNumber(1),
|
takerFee: new BigNumber(1),
|
||||||
takerAssetData: assetDataUtils.encodeERC20AssetData(feeToken.address),
|
takerAssetData: assetDataUtils.encodeERC20AssetData(feeToken.address),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const fillResults = await exchange.fillOrderNoThrow.callAsync(
|
||||||
|
signedOrder,
|
||||||
|
signedOrder.takerAssetAmount,
|
||||||
|
signedOrder.signature,
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress);
|
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress);
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
|
expect(fillResults).to.deep.equal(nullFillResults);
|
||||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -432,6 +522,13 @@ describe('Exchange wrappers', () => {
|
|||||||
expect(initialOwnerTakerAsset).to.be.bignumber.equal(takerAddress);
|
expect(initialOwnerTakerAsset).to.be.bignumber.equal(takerAddress);
|
||||||
// Call Exchange
|
// Call Exchange
|
||||||
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
||||||
|
|
||||||
|
const fillResults = await exchange.fillOrKillOrder.callAsync(
|
||||||
|
signedOrder,
|
||||||
|
takerAssetFillAmount,
|
||||||
|
signedOrder.signature,
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress, {
|
await exchangeWrapper.fillOrderNoThrowAsync(signedOrder, takerAddress, {
|
||||||
takerAssetFillAmount,
|
takerAssetFillAmount,
|
||||||
// HACK(albrow): We need to hardcode the gas estimate here because
|
// HACK(albrow): We need to hardcode the gas estimate here because
|
||||||
@@ -439,7 +536,13 @@ describe('Exchange wrappers', () => {
|
|||||||
// delegatecall and swallow errors.
|
// delegatecall and swallow errors.
|
||||||
gas: 280000,
|
gas: 280000,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Verify post-conditions
|
// Verify post-conditions
|
||||||
|
expect(fillResults.makerAssetFilledAmount).to.bignumber.equal(signedOrder.makerAssetAmount);
|
||||||
|
expect(fillResults.takerAssetFilledAmount).to.bignumber.equal(signedOrder.takerAssetAmount);
|
||||||
|
expect(fillResults.makerFeePaid).to.bignumber.equal(signedOrder.makerFee);
|
||||||
|
expect(fillResults.takerFeePaid).to.bignumber.equal(signedOrder.takerFee);
|
||||||
|
|
||||||
const newOwnerMakerAsset = await erc721Token.ownerOf.callAsync(makerAssetId);
|
const newOwnerMakerAsset = await erc721Token.ownerOf.callAsync(makerAssetId);
|
||||||
expect(newOwnerMakerAsset).to.be.bignumber.equal(takerAddress);
|
expect(newOwnerMakerAsset).to.be.bignumber.equal(takerAddress);
|
||||||
const newOwnerTakerAsset = await erc721Token.ownerOf.callAsync(takerAssetId);
|
const newOwnerTakerAsset = await erc721Token.ownerOf.callAsync(takerAssetId);
|
||||||
@@ -541,7 +644,7 @@ describe('Exchange wrappers', () => {
|
|||||||
|
|
||||||
describe('batchFillOrders', () => {
|
describe('batchFillOrders', () => {
|
||||||
const reentrancyTest = (functionNames: string[]) => {
|
const reentrancyTest = (functionNames: string[]) => {
|
||||||
_.forEach(functionNames, async (functionName: string, functionId: number) => {
|
for (const [functionId, functionName] of functionNames.entries()) {
|
||||||
const description = `should not allow batchFillOrders to reenter the Exchange contract via ${functionName}`;
|
const description = `should not allow batchFillOrders to reenter the Exchange contract via ${functionName}`;
|
||||||
it(description, async () => {
|
it(description, async () => {
|
||||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||||
@@ -554,14 +657,17 @@ describe('Exchange wrappers', () => {
|
|||||||
const tx = exchangeWrapper.batchFillOrdersAsync([signedOrder], takerAddress);
|
const tx = exchangeWrapper.batchFillOrdersAsync([signedOrder], takerAddress);
|
||||||
return expect(tx).to.revertWith(RevertReason.ReentrancyIllegal);
|
return expect(tx).to.revertWith(RevertReason.ReentrancyIllegal);
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
describe('batchFillOrders reentrancy tests', () => reentrancyTest(exchangeConstants.FUNCTIONS_WITH_MUTEX));
|
describe('batchFillOrders reentrancy tests', () => reentrancyTest(exchangeConstants.FUNCTIONS_WITH_MUTEX));
|
||||||
|
|
||||||
it('should transfer the correct amounts', async () => {
|
it('should transfer the correct amounts', async () => {
|
||||||
const takerAssetFillAmounts: BigNumber[] = [];
|
|
||||||
const makerAssetAddress = erc20TokenA.address;
|
const makerAssetAddress = erc20TokenA.address;
|
||||||
const takerAssetAddress = erc20TokenB.address;
|
const takerAssetAddress = erc20TokenB.address;
|
||||||
|
|
||||||
|
const takerAssetFillAmounts: BigNumber[] = [];
|
||||||
|
const expectedFillResults: FillResults[] = [];
|
||||||
|
|
||||||
_.forEach(signedOrders, signedOrder => {
|
_.forEach(signedOrders, signedOrder => {
|
||||||
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
||||||
const makerAssetFilledAmount = takerAssetFillAmount
|
const makerAssetFilledAmount = takerAssetFillAmount
|
||||||
@@ -573,7 +679,15 @@ describe('Exchange wrappers', () => {
|
|||||||
const takerFee = signedOrder.takerFee
|
const takerFee = signedOrder.takerFee
|
||||||
.times(makerAssetFilledAmount)
|
.times(makerAssetFilledAmount)
|
||||||
.dividedToIntegerBy(signedOrder.makerAssetAmount);
|
.dividedToIntegerBy(signedOrder.makerAssetAmount);
|
||||||
|
|
||||||
takerAssetFillAmounts.push(takerAssetFillAmount);
|
takerAssetFillAmounts.push(takerAssetFillAmount);
|
||||||
|
expectedFillResults.push({
|
||||||
|
takerAssetFilledAmount: takerAssetFillAmount,
|
||||||
|
makerAssetFilledAmount,
|
||||||
|
makerFeePaid: makerFee,
|
||||||
|
takerFeePaid: takerFee,
|
||||||
|
});
|
||||||
|
|
||||||
erc20Balances[makerAddress][makerAssetAddress] = erc20Balances[makerAddress][
|
erc20Balances[makerAddress][makerAssetAddress] = erc20Balances[makerAddress][
|
||||||
makerAssetAddress
|
makerAssetAddress
|
||||||
].minus(makerAssetFilledAmount);
|
].minus(makerAssetFilledAmount);
|
||||||
@@ -597,18 +711,25 @@ describe('Exchange wrappers', () => {
|
|||||||
].plus(makerFee.plus(takerFee));
|
].plus(makerFee.plus(takerFee));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const fillResults = await exchange.batchFillOrders.callAsync(
|
||||||
|
signedOrders,
|
||||||
|
takerAssetFillAmounts,
|
||||||
|
signedOrders.map(signedOrder => signedOrder.signature),
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.batchFillOrdersAsync(signedOrders, takerAddress, {
|
await exchangeWrapper.batchFillOrdersAsync(signedOrders, takerAddress, {
|
||||||
takerAssetFillAmounts,
|
takerAssetFillAmounts,
|
||||||
});
|
});
|
||||||
|
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
|
expect(fillResults).to.deep.equal(expectedFillResults);
|
||||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('batchFillOrKillOrders', () => {
|
describe('batchFillOrKillOrders', () => {
|
||||||
const reentrancyTest = (functionNames: string[]) => {
|
const reentrancyTest = (functionNames: string[]) => {
|
||||||
_.forEach(functionNames, async (functionName: string, functionId: number) => {
|
for (const [functionId, functionName] of functionNames.entries()) {
|
||||||
const description = `should not allow batchFillOrKillOrders to reenter the Exchange contract via ${functionName}`;
|
const description = `should not allow batchFillOrKillOrders to reenter the Exchange contract via ${functionName}`;
|
||||||
it(description, async () => {
|
it(description, async () => {
|
||||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||||
@@ -621,15 +742,18 @@ describe('Exchange wrappers', () => {
|
|||||||
const tx = exchangeWrapper.batchFillOrKillOrdersAsync([signedOrder], takerAddress);
|
const tx = exchangeWrapper.batchFillOrKillOrdersAsync([signedOrder], takerAddress);
|
||||||
return expect(tx).to.revertWith(RevertReason.ReentrancyIllegal);
|
return expect(tx).to.revertWith(RevertReason.ReentrancyIllegal);
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
describe('batchFillOrKillOrders reentrancy tests', () =>
|
describe('batchFillOrKillOrders reentrancy tests', () =>
|
||||||
reentrancyTest(exchangeConstants.FUNCTIONS_WITH_MUTEX));
|
reentrancyTest(exchangeConstants.FUNCTIONS_WITH_MUTEX));
|
||||||
|
|
||||||
it('should transfer the correct amounts', async () => {
|
it('should transfer the correct amounts', async () => {
|
||||||
const takerAssetFillAmounts: BigNumber[] = [];
|
|
||||||
const makerAssetAddress = erc20TokenA.address;
|
const makerAssetAddress = erc20TokenA.address;
|
||||||
const takerAssetAddress = erc20TokenB.address;
|
const takerAssetAddress = erc20TokenB.address;
|
||||||
|
|
||||||
|
const takerAssetFillAmounts: BigNumber[] = [];
|
||||||
|
const expectedFillResults: FillResults[] = [];
|
||||||
|
|
||||||
_.forEach(signedOrders, signedOrder => {
|
_.forEach(signedOrders, signedOrder => {
|
||||||
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
||||||
const makerAssetFilledAmount = takerAssetFillAmount
|
const makerAssetFilledAmount = takerAssetFillAmount
|
||||||
@@ -641,7 +765,15 @@ describe('Exchange wrappers', () => {
|
|||||||
const takerFee = signedOrder.takerFee
|
const takerFee = signedOrder.takerFee
|
||||||
.times(makerAssetFilledAmount)
|
.times(makerAssetFilledAmount)
|
||||||
.dividedToIntegerBy(signedOrder.makerAssetAmount);
|
.dividedToIntegerBy(signedOrder.makerAssetAmount);
|
||||||
|
|
||||||
takerAssetFillAmounts.push(takerAssetFillAmount);
|
takerAssetFillAmounts.push(takerAssetFillAmount);
|
||||||
|
expectedFillResults.push({
|
||||||
|
takerAssetFilledAmount: takerAssetFillAmount,
|
||||||
|
makerAssetFilledAmount,
|
||||||
|
makerFeePaid: makerFee,
|
||||||
|
takerFeePaid: takerFee,
|
||||||
|
});
|
||||||
|
|
||||||
erc20Balances[makerAddress][makerAssetAddress] = erc20Balances[makerAddress][
|
erc20Balances[makerAddress][makerAssetAddress] = erc20Balances[makerAddress][
|
||||||
makerAssetAddress
|
makerAssetAddress
|
||||||
].minus(makerAssetFilledAmount);
|
].minus(makerAssetFilledAmount);
|
||||||
@@ -665,11 +797,18 @@ describe('Exchange wrappers', () => {
|
|||||||
].plus(makerFee.plus(takerFee));
|
].plus(makerFee.plus(takerFee));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const fillResults = await exchange.batchFillOrKillOrders.callAsync(
|
||||||
|
signedOrders,
|
||||||
|
takerAssetFillAmounts,
|
||||||
|
signedOrders.map(signedOrder => signedOrder.signature),
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.batchFillOrKillOrdersAsync(signedOrders, takerAddress, {
|
await exchangeWrapper.batchFillOrKillOrdersAsync(signedOrders, takerAddress, {
|
||||||
takerAssetFillAmounts,
|
takerAssetFillAmounts,
|
||||||
});
|
});
|
||||||
|
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
|
expect(fillResults).to.deep.equal(expectedFillResults);
|
||||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -692,7 +831,7 @@ describe('Exchange wrappers', () => {
|
|||||||
|
|
||||||
describe('batchFillOrdersNoThrow', async () => {
|
describe('batchFillOrdersNoThrow', async () => {
|
||||||
const reentrancyTest = (functionNames: string[]) => {
|
const reentrancyTest = (functionNames: string[]) => {
|
||||||
_.forEach(functionNames, async (functionName: string, functionId: number) => {
|
for (const [functionId, functionName] of functionNames.entries()) {
|
||||||
const description = `should not allow batchFillOrdersNoThrow to reenter the Exchange contract via ${functionName}`;
|
const description = `should not allow batchFillOrdersNoThrow to reenter the Exchange contract via ${functionName}`;
|
||||||
it(description, async () => {
|
it(description, async () => {
|
||||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||||
@@ -706,15 +845,18 @@ describe('Exchange wrappers', () => {
|
|||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
expect(erc20Balances).to.deep.equal(newBalances);
|
expect(erc20Balances).to.deep.equal(newBalances);
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
describe('batchFillOrdersNoThrow reentrancy tests', () =>
|
describe('batchFillOrdersNoThrow reentrancy tests', () =>
|
||||||
reentrancyTest(exchangeConstants.FUNCTIONS_WITH_MUTEX));
|
reentrancyTest(exchangeConstants.FUNCTIONS_WITH_MUTEX));
|
||||||
|
|
||||||
it('should transfer the correct amounts', async () => {
|
it('should transfer the correct amounts', async () => {
|
||||||
const takerAssetFillAmounts: BigNumber[] = [];
|
|
||||||
const makerAssetAddress = erc20TokenA.address;
|
const makerAssetAddress = erc20TokenA.address;
|
||||||
const takerAssetAddress = erc20TokenB.address;
|
const takerAssetAddress = erc20TokenB.address;
|
||||||
|
|
||||||
|
const takerAssetFillAmounts: BigNumber[] = [];
|
||||||
|
const expectedFillResults: FillResults[] = [];
|
||||||
|
|
||||||
_.forEach(signedOrders, signedOrder => {
|
_.forEach(signedOrders, signedOrder => {
|
||||||
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
||||||
const makerAssetFilledAmount = takerAssetFillAmount
|
const makerAssetFilledAmount = takerAssetFillAmount
|
||||||
@@ -726,7 +868,15 @@ describe('Exchange wrappers', () => {
|
|||||||
const takerFee = signedOrder.takerFee
|
const takerFee = signedOrder.takerFee
|
||||||
.times(makerAssetFilledAmount)
|
.times(makerAssetFilledAmount)
|
||||||
.dividedToIntegerBy(signedOrder.makerAssetAmount);
|
.dividedToIntegerBy(signedOrder.makerAssetAmount);
|
||||||
|
|
||||||
takerAssetFillAmounts.push(takerAssetFillAmount);
|
takerAssetFillAmounts.push(takerAssetFillAmount);
|
||||||
|
expectedFillResults.push({
|
||||||
|
takerAssetFilledAmount: takerAssetFillAmount,
|
||||||
|
makerAssetFilledAmount,
|
||||||
|
makerFeePaid: makerFee,
|
||||||
|
takerFeePaid: takerFee,
|
||||||
|
});
|
||||||
|
|
||||||
erc20Balances[makerAddress][makerAssetAddress] = erc20Balances[makerAddress][
|
erc20Balances[makerAddress][makerAssetAddress] = erc20Balances[makerAddress][
|
||||||
makerAssetAddress
|
makerAssetAddress
|
||||||
].minus(makerAssetFilledAmount);
|
].minus(makerAssetFilledAmount);
|
||||||
@@ -750,6 +900,12 @@ describe('Exchange wrappers', () => {
|
|||||||
].plus(makerFee.plus(takerFee));
|
].plus(makerFee.plus(takerFee));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const fillResults = await exchange.batchFillOrdersNoThrow.callAsync(
|
||||||
|
signedOrders,
|
||||||
|
takerAssetFillAmounts,
|
||||||
|
signedOrders.map(signedOrder => signedOrder.signature),
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.batchFillOrdersNoThrowAsync(signedOrders, takerAddress, {
|
await exchangeWrapper.batchFillOrdersNoThrowAsync(signedOrders, takerAddress, {
|
||||||
takerAssetFillAmounts,
|
takerAssetFillAmounts,
|
||||||
// HACK(albrow): We need to hardcode the gas estimate here because
|
// HACK(albrow): We need to hardcode the gas estimate here because
|
||||||
@@ -757,13 +913,13 @@ describe('Exchange wrappers', () => {
|
|||||||
// delegatecall and swallow errors.
|
// delegatecall and swallow errors.
|
||||||
gas: 600000,
|
gas: 600000,
|
||||||
});
|
});
|
||||||
|
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
|
expect(fillResults).to.deep.equal(expectedFillResults);
|
||||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not throw if an order is invalid and fill the remaining orders', async () => {
|
it('should not throw if an order is invalid and fill the remaining orders', async () => {
|
||||||
const takerAssetFillAmounts: BigNumber[] = [];
|
|
||||||
const makerAssetAddress = erc20TokenA.address;
|
const makerAssetAddress = erc20TokenA.address;
|
||||||
const takerAssetAddress = erc20TokenB.address;
|
const takerAssetAddress = erc20TokenB.address;
|
||||||
|
|
||||||
@@ -772,8 +928,9 @@ describe('Exchange wrappers', () => {
|
|||||||
signature: '0x00',
|
signature: '0x00',
|
||||||
};
|
};
|
||||||
const validOrders = signedOrders.slice(1);
|
const validOrders = signedOrders.slice(1);
|
||||||
|
const takerAssetFillAmounts: BigNumber[] = [invalidOrder.takerAssetAmount.div(2)];
|
||||||
|
const expectedFillResults = [nullFillResults];
|
||||||
|
|
||||||
takerAssetFillAmounts.push(invalidOrder.takerAssetAmount.div(2));
|
|
||||||
_.forEach(validOrders, signedOrder => {
|
_.forEach(validOrders, signedOrder => {
|
||||||
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
||||||
const makerAssetFilledAmount = takerAssetFillAmount
|
const makerAssetFilledAmount = takerAssetFillAmount
|
||||||
@@ -785,7 +942,15 @@ describe('Exchange wrappers', () => {
|
|||||||
const takerFee = signedOrder.takerFee
|
const takerFee = signedOrder.takerFee
|
||||||
.times(makerAssetFilledAmount)
|
.times(makerAssetFilledAmount)
|
||||||
.dividedToIntegerBy(signedOrder.makerAssetAmount);
|
.dividedToIntegerBy(signedOrder.makerAssetAmount);
|
||||||
|
|
||||||
takerAssetFillAmounts.push(takerAssetFillAmount);
|
takerAssetFillAmounts.push(takerAssetFillAmount);
|
||||||
|
expectedFillResults.push({
|
||||||
|
takerAssetFilledAmount: takerAssetFillAmount,
|
||||||
|
makerAssetFilledAmount,
|
||||||
|
makerFeePaid: makerFee,
|
||||||
|
takerFeePaid: takerFee,
|
||||||
|
});
|
||||||
|
|
||||||
erc20Balances[makerAddress][makerAssetAddress] = erc20Balances[makerAddress][
|
erc20Balances[makerAddress][makerAssetAddress] = erc20Balances[makerAddress][
|
||||||
makerAssetAddress
|
makerAssetAddress
|
||||||
].minus(makerAssetFilledAmount);
|
].minus(makerAssetFilledAmount);
|
||||||
@@ -810,6 +975,12 @@ describe('Exchange wrappers', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const newOrders = [invalidOrder, ...validOrders];
|
const newOrders = [invalidOrder, ...validOrders];
|
||||||
|
const fillResults = await exchange.batchFillOrdersNoThrow.callAsync(
|
||||||
|
newOrders,
|
||||||
|
takerAssetFillAmounts,
|
||||||
|
newOrders.map(signedOrder => signedOrder.signature),
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.batchFillOrdersNoThrowAsync(newOrders, takerAddress, {
|
await exchangeWrapper.batchFillOrdersNoThrowAsync(newOrders, takerAddress, {
|
||||||
takerAssetFillAmounts,
|
takerAssetFillAmounts,
|
||||||
// HACK(albrow): We need to hardcode the gas estimate here because
|
// HACK(albrow): We need to hardcode the gas estimate here because
|
||||||
@@ -817,15 +988,16 @@ describe('Exchange wrappers', () => {
|
|||||||
// delegatecall and swallow errors.
|
// delegatecall and swallow errors.
|
||||||
gas: 450000,
|
gas: 450000,
|
||||||
});
|
});
|
||||||
|
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
|
expect(fillResults).to.deep.equal(expectedFillResults);
|
||||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('marketSellOrders', () => {
|
describe('marketSellOrders', () => {
|
||||||
const reentrancyTest = (functionNames: string[]) => {
|
const reentrancyTest = (functionNames: string[]) => {
|
||||||
_.forEach(functionNames, async (functionName: string, functionId: number) => {
|
for (const [functionId, functionName] of functionNames.entries()) {
|
||||||
const description = `should not allow marketSellOrders to reenter the Exchange contract via ${functionName}`;
|
const description = `should not allow marketSellOrders to reenter the Exchange contract via ${functionName}`;
|
||||||
it(description, async () => {
|
it(description, async () => {
|
||||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||||
@@ -840,7 +1012,7 @@ describe('Exchange wrappers', () => {
|
|||||||
});
|
});
|
||||||
return expect(tx).to.revertWith(RevertReason.ReentrancyIllegal);
|
return expect(tx).to.revertWith(RevertReason.ReentrancyIllegal);
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
describe('marketSellOrders reentrancy tests', () => reentrancyTest(exchangeConstants.FUNCTIONS_WITH_MUTEX));
|
describe('marketSellOrders reentrancy tests', () => reentrancyTest(exchangeConstants.FUNCTIONS_WITH_MUTEX));
|
||||||
|
|
||||||
@@ -848,10 +1020,16 @@ describe('Exchange wrappers', () => {
|
|||||||
const takerAssetFillAmount = signedOrders[0].takerAssetAmount.plus(
|
const takerAssetFillAmount = signedOrders[0].takerAssetAmount.plus(
|
||||||
signedOrders[1].takerAssetAmount.div(2),
|
signedOrders[1].takerAssetAmount.div(2),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const fillResults = await exchange.marketSellOrders.callAsync(
|
||||||
|
signedOrders,
|
||||||
|
takerAssetFillAmount,
|
||||||
|
signedOrders.map(signedOrder => signedOrder.signature),
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.marketSellOrdersAsync(signedOrders, takerAddress, {
|
await exchangeWrapper.marketSellOrdersAsync(signedOrders, takerAddress, {
|
||||||
takerAssetFillAmount,
|
takerAssetFillAmount,
|
||||||
});
|
});
|
||||||
|
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
const makerAssetFilledAmount = signedOrders[0].makerAssetAmount.plus(
|
const makerAssetFilledAmount = signedOrders[0].makerAssetAmount.plus(
|
||||||
@@ -859,6 +1037,12 @@ describe('Exchange wrappers', () => {
|
|||||||
);
|
);
|
||||||
const makerFee = signedOrders[0].makerFee.plus(signedOrders[1].makerFee.dividedToIntegerBy(2));
|
const makerFee = signedOrders[0].makerFee.plus(signedOrders[1].makerFee.dividedToIntegerBy(2));
|
||||||
const takerFee = signedOrders[0].takerFee.plus(signedOrders[1].takerFee.dividedToIntegerBy(2));
|
const takerFee = signedOrders[0].takerFee.plus(signedOrders[1].takerFee.dividedToIntegerBy(2));
|
||||||
|
|
||||||
|
expect(fillResults.makerAssetFilledAmount).to.bignumber.equal(makerAssetFilledAmount);
|
||||||
|
expect(fillResults.takerAssetFilledAmount).to.bignumber.equal(takerAssetFillAmount);
|
||||||
|
expect(fillResults.makerFeePaid).to.bignumber.equal(makerFee);
|
||||||
|
expect(fillResults.takerFeePaid).to.bignumber.equal(takerFee);
|
||||||
|
|
||||||
expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
|
expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
|
||||||
erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFilledAmount),
|
erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFilledAmount),
|
||||||
);
|
);
|
||||||
@@ -907,11 +1091,40 @@ describe('Exchange wrappers', () => {
|
|||||||
feeToken.address
|
feeToken.address
|
||||||
].plus(signedOrder.makerFee.plus(signedOrder.takerFee));
|
].plus(signedOrder.makerFee.plus(signedOrder.takerFee));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const fillResults = await exchange.marketSellOrders.callAsync(
|
||||||
|
signedOrders,
|
||||||
|
takerAssetFillAmount,
|
||||||
|
signedOrders.map(signedOrder => signedOrder.signature),
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.marketSellOrdersAsync(signedOrders, takerAddress, {
|
await exchangeWrapper.marketSellOrdersAsync(signedOrders, takerAddress, {
|
||||||
takerAssetFillAmount,
|
takerAssetFillAmount,
|
||||||
});
|
});
|
||||||
|
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
|
const expectedFillResults = signedOrders
|
||||||
|
.map(signedOrder => ({
|
||||||
|
makerAssetFilledAmount: signedOrder.makerAssetAmount,
|
||||||
|
takerAssetFilledAmount: signedOrder.takerAssetAmount,
|
||||||
|
makerFeePaid: signedOrder.makerFee,
|
||||||
|
takerFeePaid: signedOrder.takerFee,
|
||||||
|
}))
|
||||||
|
.reduce(
|
||||||
|
(totalFillResults, currentFillResults) => ({
|
||||||
|
makerAssetFilledAmount: totalFillResults.makerAssetFilledAmount.plus(
|
||||||
|
currentFillResults.makerAssetFilledAmount,
|
||||||
|
),
|
||||||
|
takerAssetFilledAmount: totalFillResults.takerAssetFilledAmount.plus(
|
||||||
|
currentFillResults.takerAssetFilledAmount,
|
||||||
|
),
|
||||||
|
makerFeePaid: totalFillResults.makerFeePaid.plus(currentFillResults.makerFeePaid),
|
||||||
|
takerFeePaid: totalFillResults.takerFeePaid.plus(currentFillResults.takerFeePaid),
|
||||||
|
}),
|
||||||
|
nullFillResults,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(fillResults).to.deep.equal(expectedFillResults);
|
||||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -943,7 +1156,7 @@ describe('Exchange wrappers', () => {
|
|||||||
|
|
||||||
describe('marketSellOrdersNoThrow', () => {
|
describe('marketSellOrdersNoThrow', () => {
|
||||||
const reentrancyTest = (functionNames: string[]) => {
|
const reentrancyTest = (functionNames: string[]) => {
|
||||||
_.forEach(functionNames, async (functionName: string, functionId: number) => {
|
for (const [functionId, functionName] of functionNames.entries()) {
|
||||||
const description = `should not allow marketSellOrdersNoThrow to reenter the Exchange contract via ${functionName}`;
|
const description = `should not allow marketSellOrdersNoThrow to reenter the Exchange contract via ${functionName}`;
|
||||||
it(description, async () => {
|
it(description, async () => {
|
||||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||||
@@ -959,7 +1172,7 @@ describe('Exchange wrappers', () => {
|
|||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
expect(erc20Balances).to.deep.equal(newBalances);
|
expect(erc20Balances).to.deep.equal(newBalances);
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
describe('marketSellOrdersNoThrow reentrancy tests', () =>
|
describe('marketSellOrdersNoThrow reentrancy tests', () =>
|
||||||
reentrancyTest(exchangeConstants.FUNCTIONS_WITH_MUTEX));
|
reentrancyTest(exchangeConstants.FUNCTIONS_WITH_MUTEX));
|
||||||
@@ -968,6 +1181,13 @@ describe('Exchange wrappers', () => {
|
|||||||
const takerAssetFillAmount = signedOrders[0].takerAssetAmount.plus(
|
const takerAssetFillAmount = signedOrders[0].takerAssetAmount.plus(
|
||||||
signedOrders[1].takerAssetAmount.div(2),
|
signedOrders[1].takerAssetAmount.div(2),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const fillResults = await exchange.marketSellOrdersNoThrow.callAsync(
|
||||||
|
signedOrders,
|
||||||
|
takerAssetFillAmount,
|
||||||
|
signedOrders.map(signedOrder => signedOrder.signature),
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.marketSellOrdersNoThrowAsync(signedOrders, takerAddress, {
|
await exchangeWrapper.marketSellOrdersNoThrowAsync(signedOrders, takerAddress, {
|
||||||
takerAssetFillAmount,
|
takerAssetFillAmount,
|
||||||
// HACK(albrow): We need to hardcode the gas estimate here because
|
// HACK(albrow): We need to hardcode the gas estimate here because
|
||||||
@@ -975,7 +1195,6 @@ describe('Exchange wrappers', () => {
|
|||||||
// delegatecall and swallow errors.
|
// delegatecall and swallow errors.
|
||||||
gas: 6000000,
|
gas: 6000000,
|
||||||
});
|
});
|
||||||
|
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
const makerAssetFilledAmount = signedOrders[0].makerAssetAmount.plus(
|
const makerAssetFilledAmount = signedOrders[0].makerAssetAmount.plus(
|
||||||
@@ -983,6 +1202,12 @@ describe('Exchange wrappers', () => {
|
|||||||
);
|
);
|
||||||
const makerFee = signedOrders[0].makerFee.plus(signedOrders[1].makerFee.dividedToIntegerBy(2));
|
const makerFee = signedOrders[0].makerFee.plus(signedOrders[1].makerFee.dividedToIntegerBy(2));
|
||||||
const takerFee = signedOrders[0].takerFee.plus(signedOrders[1].takerFee.dividedToIntegerBy(2));
|
const takerFee = signedOrders[0].takerFee.plus(signedOrders[1].takerFee.dividedToIntegerBy(2));
|
||||||
|
|
||||||
|
expect(fillResults.makerAssetFilledAmount).to.bignumber.equal(makerAssetFilledAmount);
|
||||||
|
expect(fillResults.takerAssetFilledAmount).to.bignumber.equal(takerAssetFillAmount);
|
||||||
|
expect(fillResults.makerFeePaid).to.bignumber.equal(makerFee);
|
||||||
|
expect(fillResults.takerFeePaid).to.bignumber.equal(takerFee);
|
||||||
|
|
||||||
expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
|
expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
|
||||||
erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFilledAmount),
|
erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFilledAmount),
|
||||||
);
|
);
|
||||||
@@ -1031,6 +1256,13 @@ describe('Exchange wrappers', () => {
|
|||||||
feeToken.address
|
feeToken.address
|
||||||
].plus(signedOrder.makerFee.plus(signedOrder.takerFee));
|
].plus(signedOrder.makerFee.plus(signedOrder.takerFee));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const fillResults = await exchange.marketSellOrdersNoThrow.callAsync(
|
||||||
|
signedOrders,
|
||||||
|
takerAssetFillAmount,
|
||||||
|
signedOrders.map(signedOrder => signedOrder.signature),
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.marketSellOrdersNoThrowAsync(signedOrders, takerAddress, {
|
await exchangeWrapper.marketSellOrdersNoThrowAsync(signedOrders, takerAddress, {
|
||||||
takerAssetFillAmount,
|
takerAssetFillAmount,
|
||||||
// HACK(albrow): We need to hardcode the gas estimate here because
|
// HACK(albrow): We need to hardcode the gas estimate here because
|
||||||
@@ -1038,8 +1270,30 @@ describe('Exchange wrappers', () => {
|
|||||||
// delegatecall and swallow errors.
|
// delegatecall and swallow errors.
|
||||||
gas: 600000,
|
gas: 600000,
|
||||||
});
|
});
|
||||||
|
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
|
const expectedFillResults = signedOrders
|
||||||
|
.map(signedOrder => ({
|
||||||
|
makerAssetFilledAmount: signedOrder.makerAssetAmount,
|
||||||
|
takerAssetFilledAmount: signedOrder.takerAssetAmount,
|
||||||
|
makerFeePaid: signedOrder.makerFee,
|
||||||
|
takerFeePaid: signedOrder.takerFee,
|
||||||
|
}))
|
||||||
|
.reduce(
|
||||||
|
(totalFillResults, currentFillResults) => ({
|
||||||
|
makerAssetFilledAmount: totalFillResults.makerAssetFilledAmount.plus(
|
||||||
|
currentFillResults.makerAssetFilledAmount,
|
||||||
|
),
|
||||||
|
takerAssetFilledAmount: totalFillResults.takerAssetFilledAmount.plus(
|
||||||
|
currentFillResults.takerAssetFilledAmount,
|
||||||
|
),
|
||||||
|
makerFeePaid: totalFillResults.makerFeePaid.plus(currentFillResults.makerFeePaid),
|
||||||
|
takerFeePaid: totalFillResults.takerFeePaid.plus(currentFillResults.takerFeePaid),
|
||||||
|
}),
|
||||||
|
nullFillResults,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(fillResults).to.deep.equal(expectedFillResults);
|
||||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1076,6 +1330,13 @@ describe('Exchange wrappers', () => {
|
|||||||
feeToken.address
|
feeToken.address
|
||||||
].plus(signedOrder.makerFee.plus(signedOrder.takerFee));
|
].plus(signedOrder.makerFee.plus(signedOrder.takerFee));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const fillResults = await exchange.marketSellOrdersNoThrow.callAsync(
|
||||||
|
signedOrders,
|
||||||
|
takerAssetFillAmount,
|
||||||
|
signedOrders.map(signedOrder => signedOrder.signature),
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.marketSellOrdersNoThrowAsync(signedOrders, takerAddress, {
|
await exchangeWrapper.marketSellOrdersNoThrowAsync(signedOrders, takerAddress, {
|
||||||
takerAssetFillAmount,
|
takerAssetFillAmount,
|
||||||
// HACK(albrow): We need to hardcode the gas estimate here because
|
// HACK(albrow): We need to hardcode the gas estimate here because
|
||||||
@@ -1083,15 +1344,37 @@ describe('Exchange wrappers', () => {
|
|||||||
// delegatecall and swallow errors.
|
// delegatecall and swallow errors.
|
||||||
gas: 600000,
|
gas: 600000,
|
||||||
});
|
});
|
||||||
|
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
|
const expectedFillResults = filledSignedOrders
|
||||||
|
.map(signedOrder => ({
|
||||||
|
makerAssetFilledAmount: signedOrder.makerAssetAmount,
|
||||||
|
takerAssetFilledAmount: signedOrder.takerAssetAmount,
|
||||||
|
makerFeePaid: signedOrder.makerFee,
|
||||||
|
takerFeePaid: signedOrder.takerFee,
|
||||||
|
}))
|
||||||
|
.reduce(
|
||||||
|
(totalFillResults, currentFillResults) => ({
|
||||||
|
makerAssetFilledAmount: totalFillResults.makerAssetFilledAmount.plus(
|
||||||
|
currentFillResults.makerAssetFilledAmount,
|
||||||
|
),
|
||||||
|
takerAssetFilledAmount: totalFillResults.takerAssetFilledAmount.plus(
|
||||||
|
currentFillResults.takerAssetFilledAmount,
|
||||||
|
),
|
||||||
|
makerFeePaid: totalFillResults.makerFeePaid.plus(currentFillResults.makerFeePaid),
|
||||||
|
takerFeePaid: totalFillResults.takerFeePaid.plus(currentFillResults.takerFeePaid),
|
||||||
|
}),
|
||||||
|
nullFillResults,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(fillResults).to.deep.equal(expectedFillResults);
|
||||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('marketBuyOrders', () => {
|
describe('marketBuyOrders', () => {
|
||||||
const reentrancyTest = (functionNames: string[]) => {
|
const reentrancyTest = (functionNames: string[]) => {
|
||||||
_.forEach(functionNames, async (functionName: string, functionId: number) => {
|
for (const [functionId, functionName] of functionNames.entries()) {
|
||||||
const description = `should not allow marketBuyOrders to reenter the Exchange contract via ${functionName}`;
|
const description = `should not allow marketBuyOrders to reenter the Exchange contract via ${functionName}`;
|
||||||
it(description, async () => {
|
it(description, async () => {
|
||||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||||
@@ -1106,7 +1389,7 @@ describe('Exchange wrappers', () => {
|
|||||||
});
|
});
|
||||||
return expect(tx).to.revertWith(RevertReason.ReentrancyIllegal);
|
return expect(tx).to.revertWith(RevertReason.ReentrancyIllegal);
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
describe('marketBuyOrders reentrancy tests', () => reentrancyTest(exchangeConstants.FUNCTIONS_WITH_MUTEX));
|
describe('marketBuyOrders reentrancy tests', () => reentrancyTest(exchangeConstants.FUNCTIONS_WITH_MUTEX));
|
||||||
|
|
||||||
@@ -1114,10 +1397,16 @@ describe('Exchange wrappers', () => {
|
|||||||
const makerAssetFillAmount = signedOrders[0].makerAssetAmount.plus(
|
const makerAssetFillAmount = signedOrders[0].makerAssetAmount.plus(
|
||||||
signedOrders[1].makerAssetAmount.div(2),
|
signedOrders[1].makerAssetAmount.div(2),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const fillResults = await exchange.marketBuyOrders.callAsync(
|
||||||
|
signedOrders,
|
||||||
|
makerAssetFillAmount,
|
||||||
|
signedOrders.map(signedOrder => signedOrder.signature),
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.marketBuyOrdersAsync(signedOrders, takerAddress, {
|
await exchangeWrapper.marketBuyOrdersAsync(signedOrders, takerAddress, {
|
||||||
makerAssetFillAmount,
|
makerAssetFillAmount,
|
||||||
});
|
});
|
||||||
|
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
const makerAmountBought = signedOrders[0].takerAssetAmount.plus(
|
const makerAmountBought = signedOrders[0].takerAssetAmount.plus(
|
||||||
@@ -1125,6 +1414,12 @@ describe('Exchange wrappers', () => {
|
|||||||
);
|
);
|
||||||
const makerFee = signedOrders[0].makerFee.plus(signedOrders[1].makerFee.dividedToIntegerBy(2));
|
const makerFee = signedOrders[0].makerFee.plus(signedOrders[1].makerFee.dividedToIntegerBy(2));
|
||||||
const takerFee = signedOrders[0].takerFee.plus(signedOrders[1].takerFee.dividedToIntegerBy(2));
|
const takerFee = signedOrders[0].takerFee.plus(signedOrders[1].takerFee.dividedToIntegerBy(2));
|
||||||
|
|
||||||
|
expect(fillResults.makerAssetFilledAmount).to.bignumber.equal(makerAssetFillAmount);
|
||||||
|
expect(fillResults.takerAssetFilledAmount).to.bignumber.equal(makerAmountBought);
|
||||||
|
expect(fillResults.makerFeePaid).to.bignumber.equal(makerFee);
|
||||||
|
expect(fillResults.takerFeePaid).to.bignumber.equal(takerFee);
|
||||||
|
|
||||||
expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
|
expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
|
||||||
erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
|
erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
|
||||||
);
|
);
|
||||||
@@ -1173,11 +1468,40 @@ describe('Exchange wrappers', () => {
|
|||||||
feeToken.address
|
feeToken.address
|
||||||
].plus(signedOrder.makerFee.plus(signedOrder.takerFee));
|
].plus(signedOrder.makerFee.plus(signedOrder.takerFee));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const fillResults = await exchange.marketBuyOrders.callAsync(
|
||||||
|
signedOrders,
|
||||||
|
makerAssetFillAmount,
|
||||||
|
signedOrders.map(signedOrder => signedOrder.signature),
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.marketBuyOrdersAsync(signedOrders, takerAddress, {
|
await exchangeWrapper.marketBuyOrdersAsync(signedOrders, takerAddress, {
|
||||||
makerAssetFillAmount,
|
makerAssetFillAmount,
|
||||||
});
|
});
|
||||||
|
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
|
const expectedFillResults = signedOrders
|
||||||
|
.map(signedOrder => ({
|
||||||
|
makerAssetFilledAmount: signedOrder.makerAssetAmount,
|
||||||
|
takerAssetFilledAmount: signedOrder.takerAssetAmount,
|
||||||
|
makerFeePaid: signedOrder.makerFee,
|
||||||
|
takerFeePaid: signedOrder.takerFee,
|
||||||
|
}))
|
||||||
|
.reduce(
|
||||||
|
(totalFillResults, currentFillResults) => ({
|
||||||
|
makerAssetFilledAmount: totalFillResults.makerAssetFilledAmount.plus(
|
||||||
|
currentFillResults.makerAssetFilledAmount,
|
||||||
|
),
|
||||||
|
takerAssetFilledAmount: totalFillResults.takerAssetFilledAmount.plus(
|
||||||
|
currentFillResults.takerAssetFilledAmount,
|
||||||
|
),
|
||||||
|
makerFeePaid: totalFillResults.makerFeePaid.plus(currentFillResults.makerFeePaid),
|
||||||
|
takerFeePaid: totalFillResults.takerFeePaid.plus(currentFillResults.takerFeePaid),
|
||||||
|
}),
|
||||||
|
nullFillResults,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(fillResults).to.deep.equal(expectedFillResults);
|
||||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1209,7 +1533,7 @@ describe('Exchange wrappers', () => {
|
|||||||
|
|
||||||
describe('marketBuyOrdersNoThrow', () => {
|
describe('marketBuyOrdersNoThrow', () => {
|
||||||
const reentrancyTest = (functionNames: string[]) => {
|
const reentrancyTest = (functionNames: string[]) => {
|
||||||
_.forEach(functionNames, async (functionName: string, functionId: number) => {
|
for (const [functionId, functionName] of functionNames.entries()) {
|
||||||
const description = `should not allow marketBuyOrdersNoThrow to reenter the Exchange contract via ${functionName}`;
|
const description = `should not allow marketBuyOrdersNoThrow to reenter the Exchange contract via ${functionName}`;
|
||||||
it(description, async () => {
|
it(description, async () => {
|
||||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||||
@@ -1225,7 +1549,7 @@ describe('Exchange wrappers', () => {
|
|||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
expect(erc20Balances).to.deep.equal(newBalances);
|
expect(erc20Balances).to.deep.equal(newBalances);
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
describe('marketBuyOrdersNoThrow reentrancy tests', () =>
|
describe('marketBuyOrdersNoThrow reentrancy tests', () =>
|
||||||
reentrancyTest(exchangeConstants.FUNCTIONS_WITH_MUTEX));
|
reentrancyTest(exchangeConstants.FUNCTIONS_WITH_MUTEX));
|
||||||
@@ -1234,6 +1558,13 @@ describe('Exchange wrappers', () => {
|
|||||||
const makerAssetFillAmount = signedOrders[0].makerAssetAmount.plus(
|
const makerAssetFillAmount = signedOrders[0].makerAssetAmount.plus(
|
||||||
signedOrders[1].makerAssetAmount.div(2),
|
signedOrders[1].makerAssetAmount.div(2),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const fillResults = await exchange.marketBuyOrdersNoThrow.callAsync(
|
||||||
|
signedOrders,
|
||||||
|
makerAssetFillAmount,
|
||||||
|
signedOrders.map(signedOrder => signedOrder.signature),
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.marketBuyOrdersNoThrowAsync(signedOrders, takerAddress, {
|
await exchangeWrapper.marketBuyOrdersNoThrowAsync(signedOrders, takerAddress, {
|
||||||
makerAssetFillAmount,
|
makerAssetFillAmount,
|
||||||
// HACK(albrow): We need to hardcode the gas estimate here because
|
// HACK(albrow): We need to hardcode the gas estimate here because
|
||||||
@@ -1241,7 +1572,6 @@ describe('Exchange wrappers', () => {
|
|||||||
// delegatecall and swallow errors.
|
// delegatecall and swallow errors.
|
||||||
gas: 600000,
|
gas: 600000,
|
||||||
});
|
});
|
||||||
|
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
const makerAmountBought = signedOrders[0].takerAssetAmount.plus(
|
const makerAmountBought = signedOrders[0].takerAssetAmount.plus(
|
||||||
@@ -1249,6 +1579,12 @@ describe('Exchange wrappers', () => {
|
|||||||
);
|
);
|
||||||
const makerFee = signedOrders[0].makerFee.plus(signedOrders[1].makerFee.dividedToIntegerBy(2));
|
const makerFee = signedOrders[0].makerFee.plus(signedOrders[1].makerFee.dividedToIntegerBy(2));
|
||||||
const takerFee = signedOrders[0].takerFee.plus(signedOrders[1].takerFee.dividedToIntegerBy(2));
|
const takerFee = signedOrders[0].takerFee.plus(signedOrders[1].takerFee.dividedToIntegerBy(2));
|
||||||
|
|
||||||
|
expect(fillResults.makerAssetFilledAmount).to.bignumber.equal(makerAssetFillAmount);
|
||||||
|
expect(fillResults.takerAssetFilledAmount).to.bignumber.equal(makerAmountBought);
|
||||||
|
expect(fillResults.makerFeePaid).to.bignumber.equal(makerFee);
|
||||||
|
expect(fillResults.takerFeePaid).to.bignumber.equal(takerFee);
|
||||||
|
|
||||||
expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
|
expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
|
||||||
erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
|
erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
|
||||||
);
|
);
|
||||||
@@ -1297,6 +1633,13 @@ describe('Exchange wrappers', () => {
|
|||||||
feeToken.address
|
feeToken.address
|
||||||
].plus(signedOrder.makerFee.plus(signedOrder.takerFee));
|
].plus(signedOrder.makerFee.plus(signedOrder.takerFee));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const fillResults = await exchange.marketBuyOrdersNoThrow.callAsync(
|
||||||
|
signedOrders,
|
||||||
|
makerAssetFillAmount,
|
||||||
|
signedOrders.map(signedOrder => signedOrder.signature),
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.marketBuyOrdersNoThrowAsync(signedOrders, takerAddress, {
|
await exchangeWrapper.marketBuyOrdersNoThrowAsync(signedOrders, takerAddress, {
|
||||||
makerAssetFillAmount,
|
makerAssetFillAmount,
|
||||||
// HACK(albrow): We need to hardcode the gas estimate here because
|
// HACK(albrow): We need to hardcode the gas estimate here because
|
||||||
@@ -1304,8 +1647,30 @@ describe('Exchange wrappers', () => {
|
|||||||
// delegatecall and swallow errors.
|
// delegatecall and swallow errors.
|
||||||
gas: 600000,
|
gas: 600000,
|
||||||
});
|
});
|
||||||
|
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
|
const expectedFillResults = signedOrders
|
||||||
|
.map(signedOrder => ({
|
||||||
|
makerAssetFilledAmount: signedOrder.makerAssetAmount,
|
||||||
|
takerAssetFilledAmount: signedOrder.takerAssetAmount,
|
||||||
|
makerFeePaid: signedOrder.makerFee,
|
||||||
|
takerFeePaid: signedOrder.takerFee,
|
||||||
|
}))
|
||||||
|
.reduce(
|
||||||
|
(totalFillResults, currentFillResults) => ({
|
||||||
|
makerAssetFilledAmount: totalFillResults.makerAssetFilledAmount.plus(
|
||||||
|
currentFillResults.makerAssetFilledAmount,
|
||||||
|
),
|
||||||
|
takerAssetFilledAmount: totalFillResults.takerAssetFilledAmount.plus(
|
||||||
|
currentFillResults.takerAssetFilledAmount,
|
||||||
|
),
|
||||||
|
makerFeePaid: totalFillResults.makerFeePaid.plus(currentFillResults.makerFeePaid),
|
||||||
|
takerFeePaid: totalFillResults.takerFeePaid.plus(currentFillResults.takerFeePaid),
|
||||||
|
}),
|
||||||
|
nullFillResults,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(fillResults).to.deep.equal(expectedFillResults);
|
||||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1343,6 +1708,13 @@ describe('Exchange wrappers', () => {
|
|||||||
feeToken.address
|
feeToken.address
|
||||||
].plus(signedOrder.makerFee.plus(signedOrder.takerFee));
|
].plus(signedOrder.makerFee.plus(signedOrder.takerFee));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const fillResults = await exchange.marketBuyOrdersNoThrow.callAsync(
|
||||||
|
signedOrders,
|
||||||
|
makerAssetFillAmount,
|
||||||
|
signedOrders.map(signedOrder => signedOrder.signature),
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
await exchangeWrapper.marketBuyOrdersNoThrowAsync(signedOrders, takerAddress, {
|
await exchangeWrapper.marketBuyOrdersNoThrowAsync(signedOrders, takerAddress, {
|
||||||
makerAssetFillAmount,
|
makerAssetFillAmount,
|
||||||
// HACK(albrow): We need to hardcode the gas estimate here because
|
// HACK(albrow): We need to hardcode the gas estimate here because
|
||||||
@@ -1350,8 +1722,30 @@ describe('Exchange wrappers', () => {
|
|||||||
// delegatecall and swallow errors.
|
// delegatecall and swallow errors.
|
||||||
gas: 600000,
|
gas: 600000,
|
||||||
});
|
});
|
||||||
|
|
||||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||||
|
|
||||||
|
const expectedFillResults = filledSignedOrders
|
||||||
|
.map(signedOrder => ({
|
||||||
|
makerAssetFilledAmount: signedOrder.makerAssetAmount,
|
||||||
|
takerAssetFilledAmount: signedOrder.takerAssetAmount,
|
||||||
|
makerFeePaid: signedOrder.makerFee,
|
||||||
|
takerFeePaid: signedOrder.takerFee,
|
||||||
|
}))
|
||||||
|
.reduce(
|
||||||
|
(totalFillResults, currentFillResults) => ({
|
||||||
|
makerAssetFilledAmount: totalFillResults.makerAssetFilledAmount.plus(
|
||||||
|
currentFillResults.makerAssetFilledAmount,
|
||||||
|
),
|
||||||
|
takerAssetFilledAmount: totalFillResults.takerAssetFilledAmount.plus(
|
||||||
|
currentFillResults.takerAssetFilledAmount,
|
||||||
|
),
|
||||||
|
makerFeePaid: totalFillResults.makerFeePaid.plus(currentFillResults.makerFeePaid),
|
||||||
|
takerFeePaid: totalFillResults.takerFeePaid.plus(currentFillResults.takerFeePaid),
|
||||||
|
}),
|
||||||
|
nullFillResults,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(fillResults).to.deep.equal(expectedFillResults);
|
||||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user