@0x:contracts-exchange
Addressed review feedback
This commit is contained in:
@@ -8,6 +8,7 @@ import { artifacts as erc20Artifacts } from '@0x/contracts-erc20';
|
||||
import { artifacts as erc721Artifacts } from '@0x/contracts-erc721';
|
||||
import { ReferenceFunctions as LibReferenceFunctions } from '@0x/contracts-exchange-libs';
|
||||
import {
|
||||
constants,
|
||||
expect,
|
||||
FillEventArgs,
|
||||
filterLogsToArguments,
|
||||
@@ -58,7 +59,13 @@ export class FillOrderWrapper {
|
||||
const balanceStore = LocalBalanceStore.create(initBalanceStore);
|
||||
const takerAssetFillAmount =
|
||||
opts.takerAssetFillAmount !== undefined ? opts.takerAssetFillAmount : signedOrder.takerAssetAmount;
|
||||
const fillResults = LibReferenceFunctions.calculateFillResults(signedOrder, takerAssetFillAmount);
|
||||
// TODO(jalextowle): Change this if the integration tests take protocol fees into account.
|
||||
const fillResults = LibReferenceFunctions.calculateFillResults(
|
||||
signedOrder,
|
||||
takerAssetFillAmount,
|
||||
constants.ZERO_AMOUNT,
|
||||
constants.ZERO_AMOUNT,
|
||||
);
|
||||
const fillEvent = FillOrderWrapper.simulateFillEvent(signedOrder, takerAddress, fillResults);
|
||||
// Taker -> Maker
|
||||
balanceStore.transferAsset(
|
||||
|
18
contracts/exchange/test/codesize.ts
Normal file
18
contracts/exchange/test/codesize.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { chaiSetup, getCodesizeFromArtifact } from '@0x/contracts-test-utils';
|
||||
import * as chai from 'chai';
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
|
||||
import { artifacts } from '../src';
|
||||
|
||||
describe('Contract Size Checks', () => {
|
||||
const MAX_CODE_SIZE = 24576;
|
||||
|
||||
describe('Exchange', () => {
|
||||
it('should have a codesize less than the maximum', async () => {
|
||||
const actualSize = getCodesizeFromArtifact(artifacts.Exchange);
|
||||
expect(actualSize).to.be.lt(MAX_CODE_SIZE);
|
||||
});
|
||||
});
|
||||
});
|
@@ -23,6 +23,8 @@ blockchainTests('Exchange core internal functions', env => {
|
||||
let testExchange: TestExchangeInternalsContract;
|
||||
let logDecoder: LogDecoder;
|
||||
let senderAddress: string;
|
||||
const DEFAULT_PROTOCOL_MULTIPLIER = new BigNumber(150000);
|
||||
const DEFAULT_GAS_PRICE = new BigNumber(200000);
|
||||
|
||||
before(async () => {
|
||||
const accounts = await env.getAccountAddressesAsync();
|
||||
@@ -169,12 +171,16 @@ blockchainTests('Exchange core internal functions', env => {
|
||||
orderTakerAssetFilledAmount: BigNumber,
|
||||
takerAddress: string,
|
||||
takerAssetFillAmount: BigNumber,
|
||||
// protocolFeeMultiplier: BigNumber,
|
||||
// gasPrice: BigNumber,
|
||||
// isProtocolFeePaidInEth: boolean,
|
||||
protocolFeeMultiplier: BigNumber,
|
||||
gasPrice: BigNumber,
|
||||
): Promise<void> {
|
||||
const orderHash = randomHash();
|
||||
const fillResults = LibReferenceFunctions.calculateFillResults(order, takerAssetFillAmount);
|
||||
const fillResults = LibReferenceFunctions.calculateFillResults(
|
||||
order,
|
||||
takerAssetFillAmount,
|
||||
protocolFeeMultiplier,
|
||||
gasPrice,
|
||||
);
|
||||
const expectedFilledState = orderTakerAssetFilledAmount.plus(takerAssetFillAmount);
|
||||
// const opts = isProtocolFeePaidInEth
|
||||
// ? { value: fillResults.protocolFeePaid }
|
||||
@@ -189,7 +195,6 @@ blockchainTests('Exchange core internal functions', env => {
|
||||
orderHash,
|
||||
orderTakerAssetFilledAmount,
|
||||
fillResults,
|
||||
// opts,
|
||||
),
|
||||
);
|
||||
// Grab the new `filled` state for this order.
|
||||
@@ -209,31 +214,22 @@ blockchainTests('Exchange core internal functions', env => {
|
||||
expect(fillEvent.args.takerAssetFilledAmount).to.bignumber.eq(fillResults.takerAssetFilledAmount);
|
||||
expect(fillEvent.args.makerFeePaid).to.bignumber.eq(fillResults.makerFeePaid);
|
||||
expect(fillEvent.args.takerFeePaid).to.bignumber.eq(fillResults.takerFeePaid);
|
||||
// expect(fillEvent.args.protocolFeePaid).to.bignumber.eq(fillResults.protocolFeePaid);
|
||||
// expect(fillEvent.args.isProtocolFeePaidInEth).to.eq(isProtocolFeePaidInEth);
|
||||
expect(fillEvent.args.makerAssetData).to.eq(order.makerAssetData);
|
||||
expect(fillEvent.args.takerAssetData).to.eq(order.takerAssetData);
|
||||
expect(fillEvent.args.makerFeeAssetData).to.eq(order.makerFeeAssetData);
|
||||
expect(fillEvent.args.takerFeeAssetData).to.eq(order.takerFeeAssetData);
|
||||
expect(fillEvent.args.protocolFeePaid).to.bignumber.eq(fillResults.protocolFeePaid);
|
||||
}
|
||||
|
||||
it('emits a `Fill` event and updates `filled` state correctly if protocol fee is paid in ETH', async () => {
|
||||
const order = makeOrder();
|
||||
return testUpdateFilledStateAsync(
|
||||
order,
|
||||
order.takerAssetAmount.times(0.1),
|
||||
randomAddress(),
|
||||
order.takerAssetAmount.times(0.25),
|
||||
);
|
||||
});
|
||||
|
||||
it('emits a `Fill` event and updates `filled` state correctly if protocol fee is paid in WETH', async () => {
|
||||
it('emits a `Fill` event and updates `filled` state correctly', async () => {
|
||||
const order = makeOrder();
|
||||
return testUpdateFilledStateAsync(
|
||||
order,
|
||||
order.takerAssetAmount.times(0.1),
|
||||
randomAddress(),
|
||||
order.takerAssetAmount.times(0.25),
|
||||
DEFAULT_PROTOCOL_MULTIPLIER,
|
||||
DEFAULT_GAS_PRICE,
|
||||
);
|
||||
});
|
||||
|
||||
|
@@ -37,6 +37,8 @@ blockchainTests('Isolated fillOrder() tests', env => {
|
||||
makerFeeAssetData: createGoodAssetData(),
|
||||
takerFeeAssetData: createGoodAssetData(),
|
||||
};
|
||||
const DEFAULT_GAS_PRICE = new BigNumber(20000);
|
||||
const DEFAULT_PROTOCOL_FEE_MULTIPLIER = new BigNumber(15000);
|
||||
let takerAddress: string;
|
||||
let notTakerAddress: string;
|
||||
let exchange: IsolatedExchangeWrapper;
|
||||
@@ -69,7 +71,13 @@ blockchainTests('Isolated fillOrder() tests', env => {
|
||||
signature?: string,
|
||||
): Promise<FillOrderAndAssertResultsResults> {
|
||||
const orderInfo = await exchange.getOrderInfoAsync(order);
|
||||
const efr = calculateExpectedFillResults(order, orderInfo, takerAssetFillAmount);
|
||||
const efr = calculateExpectedFillResults(
|
||||
order,
|
||||
orderInfo,
|
||||
takerAssetFillAmount,
|
||||
DEFAULT_PROTOCOL_FEE_MULTIPLIER,
|
||||
DEFAULT_GAS_PRICE,
|
||||
);
|
||||
const eoi = calculateExpectedOrderInfo(order, orderInfo, efr);
|
||||
const efb = calculateExpectedFillBalances(order, efr);
|
||||
// Fill the order.
|
||||
@@ -106,11 +114,15 @@ blockchainTests('Isolated fillOrder() tests', env => {
|
||||
order: Order,
|
||||
orderInfo: OrderInfo,
|
||||
takerAssetFillAmount: BigNumber,
|
||||
protocolFeeMultiplier: BigNumber,
|
||||
gasPrice: BigNumber,
|
||||
): FillResults {
|
||||
const remainingTakerAssetAmount = order.takerAssetAmount.minus(orderInfo.orderTakerAssetFilledAmount);
|
||||
return LibReferenceFunctions.calculateFillResults(
|
||||
order,
|
||||
BigNumber.min(takerAssetFillAmount, remainingTakerAssetAmount),
|
||||
protocolFeeMultiplier,
|
||||
gasPrice,
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -42,7 +42,7 @@ blockchainTests('Protocol Fee Payments', env => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should pay protocol fee in WETH when too little value is sent', async () => {
|
||||
it('should not forward ETH when too little value is sent', async () => {
|
||||
await testProtocolFeesReceiver.testFillOrderProtocolFees.awaitTransactionSuccessAsync(
|
||||
testProtocolFees.address,
|
||||
DEFAULT_PROTOCOL_FEE_MULTIPLIER,
|
||||
@@ -92,7 +92,7 @@ blockchainTests('Protocol Fee Payments', env => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should pay protocol fee in WETH twice when too little value is sent', async () => {
|
||||
it('should not forward ETH twice when too little value is sent', async () => {
|
||||
await testProtocolFeesReceiver.testMatchOrdersProtocolFees.awaitTransactionSuccessAsync(
|
||||
testProtocolFees.address,
|
||||
DEFAULT_PROTOCOL_FEE_MULTIPLIER,
|
||||
@@ -104,7 +104,7 @@ blockchainTests('Protocol Fee Payments', env => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should pay protocol fee in ETH and then WETH when the correct value is sent', async () => {
|
||||
it('should pay protocol fee in ETH and then not forward ETH when exactly one protocol fee is sent', async () => {
|
||||
await testProtocolFeesReceiver.testMatchOrdersProtocolFees.awaitTransactionSuccessAsync(
|
||||
testProtocolFees.address,
|
||||
DEFAULT_PROTOCOL_FEE_MULTIPLIER,
|
||||
@@ -116,7 +116,7 @@ blockchainTests('Protocol Fee Payments', env => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should pay protocol fee in ETH when extra value is sent and then pay in WETH', async () => {
|
||||
it('should pay protocol fee in ETH and then not forward ETH when a bit more than one protocol fee is sent', async () => {
|
||||
await testProtocolFeesReceiver.testMatchOrdersProtocolFees.awaitTransactionSuccessAsync(
|
||||
testProtocolFees.address,
|
||||
DEFAULT_PROTOCOL_FEE_MULTIPLIER,
|
||||
@@ -167,7 +167,7 @@ blockchainTests('Protocol Fee Payments', env => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should pay one protocol fee in WETH when too little ETH is sent and only one order is in the batch', async () => {
|
||||
it('should not forward ETH when less than one protocol fee is sent and only one order is in the batch', async () => {
|
||||
await testProtocolFeesReceiver.testBatchFillOrdersProtocolFees.awaitTransactionSuccessAsync(
|
||||
testProtocolFees.address,
|
||||
DEFAULT_PROTOCOL_FEE_MULTIPLIER,
|
||||
@@ -206,7 +206,7 @@ blockchainTests('Protocol Fee Payments', env => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should pay both protocol fees in WETH when an insuffiecent amount of ETH for one protocol fee is sent', async () => {
|
||||
it('should not forward ETH twice when an insuffiecent amount of ETH for one protocol fee is sent', async () => {
|
||||
await testProtocolFeesReceiver.testBatchFillOrdersProtocolFees.awaitTransactionSuccessAsync(
|
||||
testProtocolFees.address,
|
||||
DEFAULT_PROTOCOL_FEE_MULTIPLIER,
|
||||
@@ -219,7 +219,7 @@ blockchainTests('Protocol Fee Payments', env => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should pay a protocol in ETH and then a fee in WETH when exactly one protocol fee in ETH is sent', async () => {
|
||||
it('should pay a protocol in ETH and not forward ETH for the second when exactly one protocol fee in ETH is sent', async () => {
|
||||
await testProtocolFeesReceiver.testBatchFillOrdersProtocolFees.awaitTransactionSuccessAsync(
|
||||
testProtocolFees.address,
|
||||
DEFAULT_PROTOCOL_FEE_MULTIPLIER,
|
||||
@@ -245,7 +245,7 @@ blockchainTests('Protocol Fee Payments', env => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should pay two protocol fees in ETH and one in WETH when exactly two protocol fees in ETH is sent', async () => {
|
||||
it('should pay two protocol fees in ETH and then not forward ETH for a third when exactly two protocol fees in ETH is sent', async () => {
|
||||
await testProtocolFeesReceiver.testBatchFillOrdersProtocolFees.awaitTransactionSuccessAsync(
|
||||
testProtocolFees.address,
|
||||
DEFAULT_PROTOCOL_FEE_MULTIPLIER,
|
||||
|
@@ -1,18 +1,17 @@
|
||||
import { blockchainTests, constants, expect, LogDecoder } from '@0x/contracts-test-utils';
|
||||
import { blockchainTests, constants, expect } from '@0x/contracts-test-utils';
|
||||
import { BigNumber, OwnableRevertErrors } from '@0x/utils';
|
||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
||||
|
||||
import {
|
||||
artifacts,
|
||||
ExchangeContract,
|
||||
ExchangeUpdatedProtocolFeeCollectorAddressEventArgs,
|
||||
ExchangeUpdatedProtocolFeeMultiplierEventArgs,
|
||||
ExchangeProtocolFeeCollectorAddressEventArgs,
|
||||
ExchangeProtocolFeeMultiplierEventArgs,
|
||||
} from '../src';
|
||||
|
||||
blockchainTests.resets('MixinProtocolFees', env => {
|
||||
let accounts: string[];
|
||||
let exchange: ExchangeContract;
|
||||
let logDecoder: LogDecoder;
|
||||
let nonOwner: string;
|
||||
let owner: string;
|
||||
let protocolFeeCollector: string;
|
||||
@@ -37,60 +36,59 @@ blockchainTests.resets('MixinProtocolFees', env => {
|
||||
{},
|
||||
new BigNumber(1337),
|
||||
);
|
||||
|
||||
// Configure the log decoder
|
||||
logDecoder = new LogDecoder(env.web3Wrapper, artifacts);
|
||||
});
|
||||
|
||||
blockchainTests.resets('updateProtocolFeeMultiplier', () => {
|
||||
blockchainTests.resets('setProtocolFeeMultiplier', () => {
|
||||
it('should revert if msg.sender != owner', async () => {
|
||||
const expectedError = new OwnableRevertErrors.OnlyOwnerError(nonOwner, owner);
|
||||
|
||||
// Ensure that the transaction reverts with the expected rich error.
|
||||
const tx = exchange.updateProtocolFeeCollectorAddress.sendTransactionAsync(protocolFeeCollector, {
|
||||
const tx = exchange.setProtocolFeeCollectorAddress.sendTransactionAsync(protocolFeeCollector, {
|
||||
from: nonOwner,
|
||||
});
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('should succeed and emit an UpdatedProtocolFeeMultiplier event if msg.sender == owner', async () => {
|
||||
// Call the `updateProtocolFeeMultiplier()` function and get the receipt.
|
||||
const receipt = await logDecoder.getTxWithDecodedLogsAsync(
|
||||
await exchange.updateProtocolFeeMultiplier.sendTransactionAsync(protocolFeeMultiplier, {
|
||||
it('should succeed and emit an ProtocolFeeMultiplier event if msg.sender == owner', async () => {
|
||||
// Call the `setProtocolFeeMultiplier()` function and get the receipt.
|
||||
const receipt = await exchange.setProtocolFeeMultiplier.awaitTransactionSuccessAsync(
|
||||
protocolFeeMultiplier,
|
||||
{
|
||||
from: owner,
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
// Verify that the protocolFeeCollector address was actually updated to the correct address.
|
||||
const updated = await exchange.protocolFeeMultiplier.callAsync();
|
||||
expect(updated).bignumber.to.be.eq(protocolFeeMultiplier);
|
||||
|
||||
// Ensure that the correct `UpdatedProtocolFeeCollectorAddress` event was logged.
|
||||
// Ensure that the correct `ProtocolFeeCollectorAddress` event was logged.
|
||||
// tslint:disable:no-unnecessary-type-assertion
|
||||
const updatedEvent = receipt.logs[0] as LogWithDecodedArgs<ExchangeUpdatedProtocolFeeMultiplierEventArgs>;
|
||||
expect(updatedEvent.event).to.be.eq('UpdatedProtocolFeeMultiplier');
|
||||
const updatedEvent = receipt.logs[0] as LogWithDecodedArgs<ExchangeProtocolFeeMultiplierEventArgs>;
|
||||
expect(updatedEvent.event).to.be.eq('ProtocolFeeMultiplier');
|
||||
expect(updatedEvent.args.oldProtocolFeeMultiplier).bignumber.to.be.eq(constants.ZERO_AMOUNT);
|
||||
expect(updatedEvent.args.updatedProtocolFeeMultiplier).bignumber.to.be.eq(protocolFeeMultiplier);
|
||||
});
|
||||
});
|
||||
|
||||
blockchainTests.resets('updateProtocolFeeCollectorAddress', () => {
|
||||
blockchainTests.resets('setProtocolFeeCollectorAddress', () => {
|
||||
it('should revert if msg.sender != owner', async () => {
|
||||
const expectedError = new OwnableRevertErrors.OnlyOwnerError(nonOwner, owner);
|
||||
|
||||
// Ensure that the transaction reverts with the expected rich error.
|
||||
const tx = exchange.updateProtocolFeeCollectorAddress.sendTransactionAsync(protocolFeeCollector, {
|
||||
const tx = exchange.setProtocolFeeCollectorAddress.sendTransactionAsync(protocolFeeCollector, {
|
||||
from: nonOwner,
|
||||
});
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('should succeed and emit an UpdatedProtocolFeeCollectorAddress event if msg.sender == owner', async () => {
|
||||
// Call the `updateProtocolFeeCollectorAddress()` function and get the receipt.
|
||||
const receipt = await logDecoder.getTxWithDecodedLogsAsync(
|
||||
await exchange.updateProtocolFeeCollectorAddress.sendTransactionAsync(protocolFeeCollector, {
|
||||
it('should succeed and emit an ProtocolFeeCollectorAddress event if msg.sender == owner', async () => {
|
||||
// Call the `setProtocolFeeCollectorAddress()` function and get the receipt.
|
||||
const receipt = await exchange.setProtocolFeeCollectorAddress.awaitTransactionSuccessAsync(
|
||||
protocolFeeCollector,
|
||||
{
|
||||
from: owner,
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
// Verify that the protocolFeeCollector address was actually updated to the correct address.
|
||||
@@ -99,10 +97,8 @@ blockchainTests.resets('MixinProtocolFees', env => {
|
||||
|
||||
// Ensure that the correct `UpdatedProtocolFeeCollectorAddress` event was logged.
|
||||
// tslint:disable:no-unnecessary-type-assertion
|
||||
const updatedEvent = receipt.logs[0] as LogWithDecodedArgs<
|
||||
ExchangeUpdatedProtocolFeeCollectorAddressEventArgs
|
||||
>;
|
||||
expect(updatedEvent.event).to.be.eq('UpdatedProtocolFeeCollectorAddress');
|
||||
const updatedEvent = receipt.logs[0] as LogWithDecodedArgs<ExchangeProtocolFeeCollectorAddressEventArgs>;
|
||||
expect(updatedEvent.event).to.be.eq('ProtocolFeeCollectorAddress');
|
||||
expect(updatedEvent.args.oldProtocolFeeCollector).to.be.eq(constants.NULL_ADDRESS);
|
||||
expect(updatedEvent.args.updatedProtocolFeeCollector).to.be.eq(protocolFeeCollector);
|
||||
});
|
||||
|
@@ -7,6 +7,8 @@ import * as _ from 'lodash';
|
||||
|
||||
describe('Reference functions', () => {
|
||||
const ONE_ETHER = constants.ONE_ETHER;
|
||||
const DEFAULT_GAS_PRICE = new BigNumber(2);
|
||||
const DEFAULT_PROTOCOL_FEE_MULTIPLIER = new BigNumber(150);
|
||||
const EMPTY_ORDER: Order = {
|
||||
senderAddress: constants.NULL_ADDRESS,
|
||||
makerAddress: constants.NULL_ADDRESS,
|
||||
@@ -42,9 +44,14 @@ describe('Reference functions', () => {
|
||||
takerAssetFilledAmount,
|
||||
order.makerAssetAmount,
|
||||
);
|
||||
return expect(() => LibReferenceFunctions.calculateFillResults(order, takerAssetFilledAmount)).to.throw(
|
||||
expectedError.message,
|
||||
);
|
||||
return expect(() =>
|
||||
LibReferenceFunctions.calculateFillResults(
|
||||
order,
|
||||
takerAssetFilledAmount,
|
||||
DEFAULT_PROTOCOL_FEE_MULTIPLIER,
|
||||
DEFAULT_GAS_PRICE,
|
||||
),
|
||||
).to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if computing `fillResults.makerFeePaid` overflows', () => {
|
||||
@@ -65,9 +72,14 @@ describe('Reference functions', () => {
|
||||
makerAssetFilledAmount,
|
||||
order.makerFee,
|
||||
);
|
||||
return expect(() => LibReferenceFunctions.calculateFillResults(order, takerAssetFilledAmount)).to.throw(
|
||||
expectedError.message,
|
||||
);
|
||||
return expect(() =>
|
||||
LibReferenceFunctions.calculateFillResults(
|
||||
order,
|
||||
takerAssetFilledAmount,
|
||||
DEFAULT_PROTOCOL_FEE_MULTIPLIER,
|
||||
DEFAULT_GAS_PRICE,
|
||||
),
|
||||
).to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if computing `fillResults.takerFeePaid` overflows', () => {
|
||||
@@ -83,9 +95,14 @@ describe('Reference functions', () => {
|
||||
takerAssetFilledAmount,
|
||||
order.takerFee,
|
||||
);
|
||||
return expect(() => LibReferenceFunctions.calculateFillResults(order, takerAssetFilledAmount)).to.throw(
|
||||
expectedError.message,
|
||||
);
|
||||
return expect(() =>
|
||||
LibReferenceFunctions.calculateFillResults(
|
||||
order,
|
||||
takerAssetFilledAmount,
|
||||
DEFAULT_PROTOCOL_FEE_MULTIPLIER,
|
||||
DEFAULT_GAS_PRICE,
|
||||
),
|
||||
).to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if `order.makerAssetAmount` is 0', () => {
|
||||
@@ -95,9 +112,14 @@ describe('Reference functions', () => {
|
||||
});
|
||||
const takerAssetFilledAmount = ONE_ETHER;
|
||||
const expectedError = new LibMathRevertErrors.DivisionByZeroError();
|
||||
return expect(() => LibReferenceFunctions.calculateFillResults(order, takerAssetFilledAmount)).to.throw(
|
||||
expectedError.message,
|
||||
);
|
||||
return expect(() =>
|
||||
LibReferenceFunctions.calculateFillResults(
|
||||
order,
|
||||
takerAssetFilledAmount,
|
||||
DEFAULT_PROTOCOL_FEE_MULTIPLIER,
|
||||
DEFAULT_GAS_PRICE,
|
||||
),
|
||||
).to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if `order.takerAssetAmount` is 0', () => {
|
||||
@@ -107,9 +129,14 @@ describe('Reference functions', () => {
|
||||
});
|
||||
const takerAssetFilledAmount = ONE_ETHER;
|
||||
const expectedError = new LibMathRevertErrors.DivisionByZeroError();
|
||||
return expect(() => LibReferenceFunctions.calculateFillResults(order, takerAssetFilledAmount)).to.throw(
|
||||
expectedError.message,
|
||||
);
|
||||
return expect(() =>
|
||||
LibReferenceFunctions.calculateFillResults(
|
||||
order,
|
||||
takerAssetFilledAmount,
|
||||
DEFAULT_PROTOCOL_FEE_MULTIPLIER,
|
||||
DEFAULT_GAS_PRICE,
|
||||
),
|
||||
).to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if there is a rounding error computing `makerAsssetFilledAmount`', () => {
|
||||
@@ -123,9 +150,14 @@ describe('Reference functions', () => {
|
||||
order.takerAssetAmount,
|
||||
order.makerAssetAmount,
|
||||
);
|
||||
return expect(() => LibReferenceFunctions.calculateFillResults(order, takerAssetFilledAmount)).to.throw(
|
||||
expectedError.message,
|
||||
);
|
||||
return expect(() =>
|
||||
LibReferenceFunctions.calculateFillResults(
|
||||
order,
|
||||
takerAssetFilledAmount,
|
||||
DEFAULT_PROTOCOL_FEE_MULTIPLIER,
|
||||
DEFAULT_GAS_PRICE,
|
||||
),
|
||||
).to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if there is a rounding error computing `makerFeePaid`', () => {
|
||||
@@ -145,9 +177,14 @@ describe('Reference functions', () => {
|
||||
order.makerAssetAmount,
|
||||
order.makerFee,
|
||||
);
|
||||
return expect(() => LibReferenceFunctions.calculateFillResults(order, takerAssetFilledAmount)).to.throw(
|
||||
expectedError.message,
|
||||
);
|
||||
return expect(() =>
|
||||
LibReferenceFunctions.calculateFillResults(
|
||||
order,
|
||||
takerAssetFilledAmount,
|
||||
DEFAULT_PROTOCOL_FEE_MULTIPLIER,
|
||||
DEFAULT_GAS_PRICE,
|
||||
),
|
||||
).to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if there is a rounding error computing `takerFeePaid`', () => {
|
||||
@@ -167,9 +204,36 @@ describe('Reference functions', () => {
|
||||
order.makerAssetAmount,
|
||||
order.takerFee,
|
||||
);
|
||||
return expect(() => LibReferenceFunctions.calculateFillResults(order, takerAssetFilledAmount)).to.throw(
|
||||
expectedError.message,
|
||||
return expect(() =>
|
||||
LibReferenceFunctions.calculateFillResults(
|
||||
order,
|
||||
takerAssetFilledAmount,
|
||||
DEFAULT_PROTOCOL_FEE_MULTIPLIER,
|
||||
DEFAULT_GAS_PRICE,
|
||||
),
|
||||
).to.throw(expectedError.message);
|
||||
});
|
||||
|
||||
it('reverts if there is an overflow computing `protocolFeePaid`', () => {
|
||||
const order = makeOrder({
|
||||
makerAssetAmount: ONE_ETHER,
|
||||
takerAssetAmount: ONE_ETHER,
|
||||
takerFee: constants.ZERO_AMOUNT,
|
||||
});
|
||||
const takerAssetFilledAmount = order.takerAssetAmount.dividedToIntegerBy(3);
|
||||
const expectedError = new SafeMathRevertErrors.Uint256BinOpError(
|
||||
SafeMathRevertErrors.BinOpErrorCodes.MultiplicationOverflow,
|
||||
MAX_UINT256_ROOT,
|
||||
MAX_UINT256_ROOT,
|
||||
);
|
||||
return expect(() =>
|
||||
LibReferenceFunctions.calculateFillResults(
|
||||
order,
|
||||
takerAssetFilledAmount,
|
||||
MAX_UINT256_ROOT,
|
||||
MAX_UINT256_ROOT,
|
||||
),
|
||||
).to.throw(expectedError.message);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -9,8 +9,8 @@ export const constants = {
|
||||
ExchangeFunctionName.RegisterAssetProxy,
|
||||
ExchangeFunctionName.SimulateDispatchTransferFromCalls,
|
||||
ExchangeFunctionName.TransferOwnership,
|
||||
ExchangeFunctionName.UpdateProtocolFeeMultiplier,
|
||||
ExchangeFunctionName.UpdateProtocolFeeCollectorAddress,
|
||||
ExchangeFunctionName.SetProtocolFeeMultiplier,
|
||||
ExchangeFunctionName.SetProtocolFeeCollectorAddress,
|
||||
],
|
||||
SINGLE_FILL_FN_NAMES: [
|
||||
ExchangeFunctionName.FillOrder,
|
||||
|
@@ -32,6 +32,6 @@ export enum ExchangeFunctionName {
|
||||
SetSignatureValidatorApproval = 'setSignatureValidatorApproval',
|
||||
SimulateDispatchTransferFromCalls = 'simulateDispatchTransferFromCalls',
|
||||
TransferOwnership = 'transferOwnership',
|
||||
UpdateProtocolFeeMultiplier = 'updateProtocolFeeMultiplier',
|
||||
UpdateProtocolFeeCollectorAddress = 'updateProtocolFeeCollectorAddress',
|
||||
SetProtocolFeeMultiplier = 'setProtocolFeeMultiplier',
|
||||
SetProtocolFeeCollectorAddress = 'setProtocolFeeCollectorAddress',
|
||||
}
|
||||
|
@@ -91,7 +91,7 @@ blockchainTests.resets('Exchange wrappers', env => {
|
||||
);
|
||||
|
||||
// Set the protocol fee multiplier of the exchange
|
||||
await exchange.updateProtocolFeeMultiplier.awaitTransactionSuccessAsync(PROTOCOL_FEE_MULTIPLIER, {
|
||||
await exchange.setProtocolFeeMultiplier.awaitTransactionSuccessAsync(PROTOCOL_FEE_MULTIPLIER, {
|
||||
from: owner,
|
||||
});
|
||||
|
||||
|
@@ -62,7 +62,7 @@ blockchainTests('Exchange wrapper functions unit tests.', env => {
|
||||
);
|
||||
|
||||
// Set the protocol fee multiplier.
|
||||
await testContract.updateProtocolFeeMultiplier.awaitTransactionSuccessAsync(protocolFeeMultiplier, {
|
||||
await testContract.setProtocolFeeMultiplier.awaitTransactionSuccessAsync(protocolFeeMultiplier, {
|
||||
from: owner,
|
||||
});
|
||||
});
|
||||
@@ -1320,50 +1320,50 @@ blockchainTests('Exchange wrapper functions unit tests.', env => {
|
||||
const tx = txHelper.getResultAndReceiptAsync(testContract.batchCancelOrders, orders);
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOrdersInfo', () => {
|
||||
// Computes the expected (fake) order info generated by the `TestWrapperFunctions` contract.
|
||||
function getExpectedOrderInfo(order: Order): OrderInfo {
|
||||
const MAX_ORDER_STATUS = OrderStatus.Cancelled as number;
|
||||
return {
|
||||
orderHash: getExpectedOrderHash(order),
|
||||
// Lower uint128 of `order.salt` is the `orderTakerAssetFilledAmount`.
|
||||
orderTakerAssetFilledAmount: order.salt.mod(new BigNumber(2).pow(128)),
|
||||
// High byte of `order.salt` is the `orderStatus`.
|
||||
orderStatus:
|
||||
order.salt.dividedToIntegerBy(new BigNumber(2).pow(248)).toNumber() % (MAX_ORDER_STATUS + 1),
|
||||
};
|
||||
}
|
||||
describe('getOrdersInfo', () => {
|
||||
// Computes the expected (fake) order info generated by the `TestWrapperFunctions` contract.
|
||||
function getExpectedOrderInfo(order: Order): OrderInfo {
|
||||
const MAX_ORDER_STATUS = OrderStatus.Cancelled as number;
|
||||
return {
|
||||
orderHash: getExpectedOrderHash(order),
|
||||
// Lower uint128 of `order.salt` is the `orderTakerAssetFilledAmount`.
|
||||
orderTakerAssetFilledAmount: order.salt.mod(new BigNumber(2).pow(128)),
|
||||
// High byte of `order.salt` is the `orderStatus`.
|
||||
orderStatus:
|
||||
order.salt.dividedToIntegerBy(new BigNumber(2).pow(248)).toNumber() % (MAX_ORDER_STATUS + 1),
|
||||
};
|
||||
}
|
||||
|
||||
it('works with no orders', async () => {
|
||||
const infos = await testContract.getOrdersInfo.callAsync([]);
|
||||
expect(infos.length).to.eq(0);
|
||||
});
|
||||
it('works with no orders', async () => {
|
||||
const infos = await testContract.getOrdersInfo.callAsync([]);
|
||||
expect(infos.length).to.eq(0);
|
||||
});
|
||||
|
||||
it('works with one order', async () => {
|
||||
const orders = [randomOrder()];
|
||||
const expectedResult = orders.map(getExpectedOrderInfo);
|
||||
const actualResult = await testContract.getOrdersInfo.callAsync(orders);
|
||||
expect(actualResult).to.deep.eq(expectedResult);
|
||||
});
|
||||
it('works with one order', async () => {
|
||||
const orders = [randomOrder()];
|
||||
const expectedResult = orders.map(getExpectedOrderInfo);
|
||||
const actualResult = await testContract.getOrdersInfo.callAsync(orders);
|
||||
expect(actualResult).to.deep.eq(expectedResult);
|
||||
});
|
||||
|
||||
it('works with many orders', async () => {
|
||||
const NUM_ORDERS = 16;
|
||||
const orders = _.times(NUM_ORDERS, () => randomOrder());
|
||||
const expectedResult = orders.map(getExpectedOrderInfo);
|
||||
const actualResult = await testContract.getOrdersInfo.callAsync(orders);
|
||||
expect(actualResult).to.deep.eq(expectedResult);
|
||||
});
|
||||
it('works with many orders', async () => {
|
||||
const NUM_ORDERS = 16;
|
||||
const orders = _.times(NUM_ORDERS, () => randomOrder());
|
||||
const expectedResult = orders.map(getExpectedOrderInfo);
|
||||
const actualResult = await testContract.getOrdersInfo.callAsync(orders);
|
||||
expect(actualResult).to.deep.eq(expectedResult);
|
||||
});
|
||||
|
||||
it('works with duplicate orders', async () => {
|
||||
const NUM_UNIQUE_ORDERS = 4;
|
||||
const CLONE_COUNT = 2;
|
||||
const uniqueOrders = _.times(NUM_UNIQUE_ORDERS, () => randomOrder());
|
||||
const orders = _.shuffle(_.flatten(_.times(CLONE_COUNT, () => uniqueOrders)));
|
||||
const expectedResult = orders.map(getExpectedOrderInfo);
|
||||
const actualResult = await testContract.getOrdersInfo.callAsync(orders);
|
||||
expect(actualResult).to.deep.eq(expectedResult);
|
||||
});
|
||||
it('works with duplicate orders', async () => {
|
||||
const NUM_UNIQUE_ORDERS = 4;
|
||||
const CLONE_COUNT = 2;
|
||||
const uniqueOrders = _.times(NUM_UNIQUE_ORDERS, () => randomOrder());
|
||||
const orders = _.shuffle(_.flatten(_.times(CLONE_COUNT, () => uniqueOrders)));
|
||||
const expectedResult = orders.map(getExpectedOrderInfo);
|
||||
const actualResult = await testContract.getOrdersInfo.callAsync(orders);
|
||||
expect(actualResult).to.deep.eq(expectedResult);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user