In @0x/contracts-exchange
: Update tests for rich reverts
This commit is contained in:
parent
06499f2155
commit
20d8c1b51a
@ -22,12 +22,14 @@ pragma experimental ABIEncoderV2;
|
|||||||
import "@0x/contracts-exchange-libs/contracts/src/LibEIP712ExchangeDomain.sol";
|
import "@0x/contracts-exchange-libs/contracts/src/LibEIP712ExchangeDomain.sol";
|
||||||
import "../src/MixinSignatureValidator.sol";
|
import "../src/MixinSignatureValidator.sol";
|
||||||
import "../src/MixinTransactions.sol";
|
import "../src/MixinTransactions.sol";
|
||||||
|
import "../src/MixinExchangeRichErrors.sol";
|
||||||
|
|
||||||
|
|
||||||
contract TestSignatureValidator is
|
contract TestSignatureValidator is
|
||||||
LibEIP712ExchangeDomain,
|
LibEIP712ExchangeDomain,
|
||||||
MixinSignatureValidator,
|
MixinSignatureValidator,
|
||||||
MixinTransactions
|
MixinTransactions,
|
||||||
|
MixinExchangeRichErrors
|
||||||
{
|
{
|
||||||
|
|
||||||
// solhint-disable no-empty-blocks
|
// solhint-disable no-empty-blocks
|
||||||
|
@ -21,7 +21,6 @@ import {
|
|||||||
chaiSetup,
|
chaiSetup,
|
||||||
constants,
|
constants,
|
||||||
ERC20BalancesByOwner,
|
ERC20BalancesByOwner,
|
||||||
expectTransactionFailedAsync,
|
|
||||||
getLatestBlockTimestampAsync,
|
getLatestBlockTimestampAsync,
|
||||||
increaseTimeAndMineBlockAsync,
|
increaseTimeAndMineBlockAsync,
|
||||||
OrderFactory,
|
OrderFactory,
|
||||||
@ -56,7 +55,6 @@ const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
|||||||
|
|
||||||
// tslint:disable:no-unnecessary-type-assertion
|
// tslint:disable:no-unnecessary-type-assertion
|
||||||
describe('Exchange core', () => {
|
describe('Exchange core', () => {
|
||||||
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
||||||
let chainId: number;
|
let chainId: number;
|
||||||
let makerAddress: string;
|
let makerAddress: string;
|
||||||
let owner: string;
|
let owner: string;
|
||||||
@ -266,7 +264,7 @@ describe('Exchange core', () => {
|
|||||||
signedOrder.signature = invalidSigHex;
|
signedOrder.signature = invalidSigHex;
|
||||||
const expectedError = new ExchangeRevertErrors.SignatureError(
|
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||||
orderHashHex,
|
orderHashHex,
|
||||||
ExchangeRevertErrors.SignatureErrorCodes.BadSignature,
|
ExchangeRevertErrors.SignatureErrorCode.BadSignature,
|
||||||
);
|
);
|
||||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
||||||
return expect(tx).to.revertWith(expectedError);
|
return expect(tx).to.revertWith(expectedError);
|
||||||
@ -276,10 +274,7 @@ describe('Exchange core', () => {
|
|||||||
signedOrder = await orderFactory.newSignedOrderAsync();
|
signedOrder = await orderFactory.newSignedOrderAsync();
|
||||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
||||||
const expectedError = new ExchangeRevertErrors.OrderStatusError(
|
const expectedError = new ExchangeRevertErrors.OrderStatusError(orderHashHex, OrderStatus.FullyFilled);
|
||||||
orderHashHex,
|
|
||||||
OrderStatus.FullyFilled,
|
|
||||||
);
|
|
||||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
||||||
return expect(tx).to.revertWith(expectedError);
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
@ -303,7 +298,7 @@ describe('Exchange core', () => {
|
|||||||
signedOrder.signature = `0x0${SignatureType.Wallet}`;
|
signedOrder.signature = `0x0${SignatureType.Wallet}`;
|
||||||
const expectedError = new ExchangeRevertErrors.SignatureError(
|
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||||
orderHashHex,
|
orderHashHex,
|
||||||
ExchangeRevertErrors.SignatureErrorCodes.WalletError,
|
ExchangeRevertErrors.SignatureErrorCode.WalletError,
|
||||||
);
|
);
|
||||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
||||||
return expect(tx).to.revertWith(expectedError);
|
return expect(tx).to.revertWith(expectedError);
|
||||||
@ -320,7 +315,7 @@ describe('Exchange core', () => {
|
|||||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
const expectedError = new ExchangeRevertErrors.SignatureError(
|
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||||
orderHashHex,
|
orderHashHex,
|
||||||
ExchangeRevertErrors.SignatureErrorCodes.ValidatorError,
|
ExchangeRevertErrors.SignatureErrorCode.ValidatorError,
|
||||||
);
|
);
|
||||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
||||||
return expect(tx).to.revertWith(expectedError);
|
return expect(tx).to.revertWith(expectedError);
|
||||||
@ -497,10 +492,7 @@ describe('Exchange core', () => {
|
|||||||
|
|
||||||
it('should throw if not sent by maker', async () => {
|
it('should throw if not sent by maker', async () => {
|
||||||
const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
const expectedError = new ExchangeRevertErrors.InvalidMakerError(
|
const expectedError = new ExchangeRevertErrors.InvalidMakerError(orderHash, takerAddress);
|
||||||
orderHash,
|
|
||||||
takerAddress,
|
|
||||||
);
|
|
||||||
const tx = exchangeWrapper.cancelOrderAsync(signedOrder, takerAddress);
|
const tx = exchangeWrapper.cancelOrderAsync(signedOrder, takerAddress);
|
||||||
return expect(tx).to.revertWith(expectedError);
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
@ -534,10 +526,7 @@ describe('Exchange core', () => {
|
|||||||
it('should be able to cancel an order', async () => {
|
it('should be able to cancel an order', async () => {
|
||||||
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||||
const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
const expectedError = new ExchangeRevertErrors.OrderStatusError(
|
const expectedError = new ExchangeRevertErrors.OrderStatusError(orderHash, OrderStatus.Cancelled);
|
||||||
orderHash,
|
|
||||||
OrderStatus.Cancelled,
|
|
||||||
);
|
|
||||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
||||||
takerAssetFillAmount: signedOrder.takerAssetAmount.div(2),
|
takerAssetFillAmount: signedOrder.takerAssetAmount.div(2),
|
||||||
});
|
});
|
||||||
@ -562,10 +551,7 @@ describe('Exchange core', () => {
|
|||||||
it('should throw if already cancelled', async () => {
|
it('should throw if already cancelled', async () => {
|
||||||
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||||
const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
const expectedError = new ExchangeRevertErrors.OrderStatusError(
|
const expectedError = new ExchangeRevertErrors.OrderStatusError(orderHash, OrderStatus.Cancelled);
|
||||||
orderHash,
|
|
||||||
OrderStatus.Cancelled,
|
|
||||||
);
|
|
||||||
const tx = exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
const tx = exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||||
return expect(tx).to.revertWith(expectedError);
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
@ -576,10 +562,7 @@ describe('Exchange core', () => {
|
|||||||
expirationTimeSeconds: new BigNumber(currentTimestamp).minus(10),
|
expirationTimeSeconds: new BigNumber(currentTimestamp).minus(10),
|
||||||
});
|
});
|
||||||
const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
const expectedError = new ExchangeRevertErrors.OrderStatusError(
|
const expectedError = new ExchangeRevertErrors.OrderStatusError(orderHash, OrderStatus.Expired);
|
||||||
orderHash,
|
|
||||||
OrderStatus.Expired,
|
|
||||||
);
|
|
||||||
const tx = exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
const tx = exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||||
return expect(tx).to.revertWith(expectedError);
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
@ -610,7 +593,7 @@ describe('Exchange core', () => {
|
|||||||
const lesserOrderEpoch = new BigNumber(0);
|
const lesserOrderEpoch = new BigNumber(0);
|
||||||
const expectedError = new ExchangeRevertErrors.OrderEpochError(
|
const expectedError = new ExchangeRevertErrors.OrderEpochError(
|
||||||
makerAddress,
|
makerAddress,
|
||||||
ZERO_ADDRESS,
|
constants.NULL_ADDRESS,
|
||||||
orderEpoch.plus(1),
|
orderEpoch.plus(1),
|
||||||
);
|
);
|
||||||
const tx = exchangeWrapper.cancelOrdersUpToAsync(lesserOrderEpoch, makerAddress);
|
const tx = exchangeWrapper.cancelOrdersUpToAsync(lesserOrderEpoch, makerAddress);
|
||||||
@ -622,7 +605,7 @@ describe('Exchange core', () => {
|
|||||||
await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
|
await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
|
||||||
const expectedError = new ExchangeRevertErrors.OrderEpochError(
|
const expectedError = new ExchangeRevertErrors.OrderEpochError(
|
||||||
makerAddress,
|
makerAddress,
|
||||||
ZERO_ADDRESS,
|
constants.NULL_ADDRESS,
|
||||||
orderEpoch.plus(1),
|
orderEpoch.plus(1),
|
||||||
);
|
);
|
||||||
const tx = exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
|
const tx = exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
|
||||||
|
@ -9,7 +9,6 @@ import { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
|||||||
import {
|
import {
|
||||||
chaiSetup,
|
chaiSetup,
|
||||||
constants,
|
constants,
|
||||||
expectTransactionFailedAsync,
|
|
||||||
LogDecoder,
|
LogDecoder,
|
||||||
orderUtils,
|
orderUtils,
|
||||||
provider,
|
provider,
|
||||||
@ -137,18 +136,16 @@ describe('AssetProxyDispatcher', () => {
|
|||||||
txDefaults,
|
txDefaults,
|
||||||
);
|
);
|
||||||
const expectedError = new ExchangeRevertErrors.AssetProxyExistsError(proxyAddress);
|
const expectedError = new ExchangeRevertErrors.AssetProxyExistsError(proxyAddress);
|
||||||
const tx = assetProxyDispatcher.registerAssetProxy.sendTransactionAsync(
|
const tx = assetProxyDispatcher.registerAssetProxy.sendTransactionAsync(newErc20TransferProxy.address, {
|
||||||
newErc20TransferProxy.address,
|
from: owner,
|
||||||
{ from: owner },
|
});
|
||||||
);
|
|
||||||
return expect(tx).to.revertWith(expectedError);
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if requesting address is not owner', async () => {
|
it('should throw if requesting address is not owner', async () => {
|
||||||
const tx = assetProxyDispatcher.registerAssetProxy.sendTransactionAsync(
|
const tx = assetProxyDispatcher.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, {
|
||||||
erc20Proxy.address,
|
from: notOwner,
|
||||||
{ from: notOwner },
|
});
|
||||||
);
|
|
||||||
return expect(tx).to.revertWith(RevertReason.OnlyContractOwner);
|
return expect(tx).to.revertWith(RevertReason.OnlyContractOwner);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -279,7 +276,7 @@ describe('AssetProxyDispatcher', () => {
|
|||||||
const expectedError = new ExchangeRevertErrors.AssetProxyDispatchError(
|
const expectedError = new ExchangeRevertErrors.AssetProxyDispatchError(
|
||||||
orderHash,
|
orderHash,
|
||||||
encodedAssetData,
|
encodedAssetData,
|
||||||
ExchangeRevertErrors.AssetProxyDispatchErrorCodes.UnknownAssetProxy,
|
ExchangeRevertErrors.AssetProxyDispatchErrorCode.UnknownAssetProxy,
|
||||||
);
|
);
|
||||||
const tx = assetProxyDispatcher.publicDispatchTransferFrom.sendTransactionAsync(
|
const tx = assetProxyDispatcher.publicDispatchTransferFrom.sendTransactionAsync(
|
||||||
orderHash,
|
orderHash,
|
||||||
|
@ -6,7 +6,6 @@ import {
|
|||||||
constants,
|
constants,
|
||||||
ERC20BalancesByOwner,
|
ERC20BalancesByOwner,
|
||||||
ERC721TokenIdsByOwner,
|
ERC721TokenIdsByOwner,
|
||||||
expectTransactionFailedAsync,
|
|
||||||
OrderFactory,
|
OrderFactory,
|
||||||
provider,
|
provider,
|
||||||
txDefaults,
|
txDefaults,
|
||||||
@ -588,10 +587,12 @@ describe('matchOrders', () => {
|
|||||||
await reentrantErc20Token.setReentrantFunction.sendTransactionAsync(functionId),
|
await reentrantErc20Token.setReentrantFunction.sendTransactionAsync(functionId),
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
await expectTransactionFailedAsync(
|
const tx = exchangeWrapper.matchOrdersAsync(
|
||||||
exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress),
|
signedOrderLeft,
|
||||||
RevertReason.ReentrancyIllegal,
|
signedOrderRight,
|
||||||
|
takerAddress,
|
||||||
);
|
);
|
||||||
|
return expect(tx).to.revertWith(RevertReason.ReentrancyIllegal);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -1129,10 +1130,7 @@ describe('matchOrders', () => {
|
|||||||
// Cancel left order
|
// Cancel left order
|
||||||
await exchangeWrapper.cancelOrderAsync(signedOrderLeft, signedOrderLeft.makerAddress);
|
await exchangeWrapper.cancelOrderAsync(signedOrderLeft, signedOrderLeft.makerAddress);
|
||||||
// Match orders
|
// Match orders
|
||||||
const expectedError = new ExchangeRevertErrors.OrderStatusError(
|
const expectedError = new ExchangeRevertErrors.OrderStatusError(orderHashHexLeft, OrderStatus.Cancelled);
|
||||||
orderHashHexLeft,
|
|
||||||
OrderStatus.Cancelled,
|
|
||||||
);
|
|
||||||
const tx = exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress);
|
const tx = exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress);
|
||||||
return expect(tx).to.revertWith(expectedError);
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
@ -1151,10 +1149,7 @@ describe('matchOrders', () => {
|
|||||||
// Cancel right order
|
// Cancel right order
|
||||||
await exchangeWrapper.cancelOrderAsync(signedOrderRight, signedOrderRight.makerAddress);
|
await exchangeWrapper.cancelOrderAsync(signedOrderRight, signedOrderRight.makerAddress);
|
||||||
// Match orders
|
// Match orders
|
||||||
const expectedError = new ExchangeRevertErrors.OrderStatusError(
|
const expectedError = new ExchangeRevertErrors.OrderStatusError(orderHashHexRight, OrderStatus.Cancelled);
|
||||||
orderHashHexRight,
|
|
||||||
OrderStatus.Cancelled,
|
|
||||||
);
|
|
||||||
const tx = exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress);
|
const tx = exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress);
|
||||||
return expect(tx).to.revertWith(expectedError);
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
@ -1172,10 +1167,7 @@ describe('matchOrders', () => {
|
|||||||
const orderHashHexLeft = orderHashUtils.getOrderHashHex(signedOrderLeft);
|
const orderHashHexLeft = orderHashUtils.getOrderHashHex(signedOrderLeft);
|
||||||
const orderHashHexRight = orderHashUtils.getOrderHashHex(signedOrderRight);
|
const orderHashHexRight = orderHashUtils.getOrderHashHex(signedOrderRight);
|
||||||
// Match orders
|
// Match orders
|
||||||
const expectedError = new ExchangeRevertErrors.NegativeSpreadError(
|
const expectedError = new ExchangeRevertErrors.NegativeSpreadError(orderHashHexLeft, orderHashHexRight);
|
||||||
orderHashHexLeft,
|
|
||||||
orderHashHexRight,
|
|
||||||
);
|
|
||||||
const tx = exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress);
|
const tx = exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress);
|
||||||
return expect(tx).to.revertWith(expectedError);
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
@ -1202,7 +1194,7 @@ describe('matchOrders', () => {
|
|||||||
const orderHashHex = orderHashUtils.getOrderHashHex(reconstructedOrderRight);
|
const orderHashHex = orderHashUtils.getOrderHashHex(reconstructedOrderRight);
|
||||||
const expectedError = new ExchangeRevertErrors.SignatureError(
|
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||||
orderHashHex,
|
orderHashHex,
|
||||||
ExchangeRevertErrors.SignatureErrorCodes.BadSignature,
|
ExchangeRevertErrors.SignatureErrorCode.BadSignature,
|
||||||
);
|
);
|
||||||
// Match orders
|
// Match orders
|
||||||
const tx = exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress);
|
const tx = exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress);
|
||||||
@ -1227,7 +1219,7 @@ describe('matchOrders', () => {
|
|||||||
const orderHashHex = orderHashUtils.getOrderHashHex(reconstructedOrderRight);
|
const orderHashHex = orderHashUtils.getOrderHashHex(reconstructedOrderRight);
|
||||||
const expectedError = new ExchangeRevertErrors.SignatureError(
|
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||||
orderHashHex,
|
orderHashHex,
|
||||||
ExchangeRevertErrors.SignatureErrorCodes.BadSignature,
|
ExchangeRevertErrors.SignatureErrorCode.BadSignature,
|
||||||
);
|
);
|
||||||
// Match orders
|
// Match orders
|
||||||
const tx = exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress);
|
const tx = exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress);
|
||||||
|
@ -2,7 +2,6 @@ import {
|
|||||||
addressUtils,
|
addressUtils,
|
||||||
chaiSetup,
|
chaiSetup,
|
||||||
constants,
|
constants,
|
||||||
expectContractCallFailedAsync,
|
|
||||||
LogDecoder,
|
LogDecoder,
|
||||||
OrderFactory,
|
OrderFactory,
|
||||||
provider,
|
provider,
|
||||||
@ -10,7 +9,12 @@ import {
|
|||||||
web3Wrapper,
|
web3Wrapper,
|
||||||
} from '@0x/contracts-test-utils';
|
} from '@0x/contracts-test-utils';
|
||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||||
import { assetDataUtils, orderHashUtils, signatureUtils } from '@0x/order-utils';
|
import {
|
||||||
|
assetDataUtils,
|
||||||
|
ExchangeRevertErrors,
|
||||||
|
orderHashUtils,
|
||||||
|
signatureUtils
|
||||||
|
} from '@0x/order-utils';
|
||||||
import { RevertReason, SignatureType, SignedOrder } from '@0x/types';
|
import { RevertReason, SignatureType, SignedOrder } from '@0x/types';
|
||||||
import { BigNumber, providerUtils } from '@0x/utils';
|
import { BigNumber, providerUtils } from '@0x/utils';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
@ -130,41 +134,47 @@ describe('MixinSignatureValidator', () => {
|
|||||||
it('should revert when signature is empty', async () => {
|
it('should revert when signature is empty', async () => {
|
||||||
const emptySignature = '0x';
|
const emptySignature = '0x';
|
||||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
return expectContractCallFailedAsync(
|
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||||
signatureValidator.publicIsValidSignature.callAsync(
|
orderHashHex,
|
||||||
orderHashHex,
|
ExchangeRevertErrors.SignatureErrorCode.InvalidLength,
|
||||||
signedOrder.makerAddress,
|
|
||||||
emptySignature,
|
|
||||||
),
|
|
||||||
RevertReason.LengthGreaterThan0Required,
|
|
||||||
);
|
);
|
||||||
|
const tx = signatureValidator.publicIsValidSignature.callAsync(
|
||||||
|
orderHashHex,
|
||||||
|
signedOrder.makerAddress,
|
||||||
|
emptySignature,
|
||||||
|
);
|
||||||
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should revert when signature type is unsupported', async () => {
|
it('should revert when signature type is unsupported', async () => {
|
||||||
const unsupportedSignatureType = SignatureType.NSignatureTypes;
|
const unsupportedSignatureType = SignatureType.NSignatureTypes;
|
||||||
const unsupportedSignatureHex = `0x${Buffer.from([unsupportedSignatureType]).toString('hex')}`;
|
const unsupportedSignatureHex = `0x${Buffer.from([unsupportedSignatureType]).toString('hex')}`;
|
||||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
return expectContractCallFailedAsync(
|
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||||
signatureValidator.publicIsValidSignature.callAsync(
|
orderHashHex,
|
||||||
orderHashHex,
|
ExchangeRevertErrors.SignatureErrorCode.Unsupported,
|
||||||
signedOrder.makerAddress,
|
|
||||||
unsupportedSignatureHex,
|
|
||||||
),
|
|
||||||
RevertReason.SignatureUnsupported,
|
|
||||||
);
|
);
|
||||||
|
const tx = signatureValidator.publicIsValidSignature.callAsync(
|
||||||
|
orderHashHex,
|
||||||
|
signedOrder.makerAddress,
|
||||||
|
unsupportedSignatureHex,
|
||||||
|
);
|
||||||
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should revert when SignatureType=Illegal', async () => {
|
it('should revert when SignatureType=Illegal', async () => {
|
||||||
const unsupportedSignatureHex = `0x${Buffer.from([SignatureType.Illegal]).toString('hex')}`;
|
const unsupportedSignatureHex = `0x${Buffer.from([SignatureType.Illegal]).toString('hex')}`;
|
||||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
return expectContractCallFailedAsync(
|
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||||
signatureValidator.publicIsValidSignature.callAsync(
|
orderHashHex,
|
||||||
orderHashHex,
|
ExchangeRevertErrors.SignatureErrorCode.Illegal,
|
||||||
signedOrder.makerAddress,
|
|
||||||
unsupportedSignatureHex,
|
|
||||||
),
|
|
||||||
RevertReason.SignatureIllegal,
|
|
||||||
);
|
);
|
||||||
|
const tx = signatureValidator.publicIsValidSignature.callAsync(
|
||||||
|
orderHashHex,
|
||||||
|
signedOrder.makerAddress,
|
||||||
|
unsupportedSignatureHex,
|
||||||
|
);
|
||||||
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false when SignatureType=Invalid and signature has a length of zero', async () => {
|
it('should return false when SignatureType=Invalid and signature has a length of zero', async () => {
|
||||||
@ -184,14 +194,16 @@ describe('MixinSignatureValidator', () => {
|
|||||||
const signatureBuffer = Buffer.concat([fillerData, signatureType]);
|
const signatureBuffer = Buffer.concat([fillerData, signatureType]);
|
||||||
const signatureHex = ethUtil.bufferToHex(signatureBuffer);
|
const signatureHex = ethUtil.bufferToHex(signatureBuffer);
|
||||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
return expectContractCallFailedAsync(
|
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||||
signatureValidator.publicIsValidSignature.callAsync(
|
orderHashHex,
|
||||||
orderHashHex,
|
ExchangeRevertErrors.SignatureErrorCode.InvalidLength,
|
||||||
signedOrder.makerAddress,
|
|
||||||
signatureHex,
|
|
||||||
),
|
|
||||||
RevertReason.Length0Required,
|
|
||||||
);
|
);
|
||||||
|
const tx = signatureValidator.publicIsValidSignature.callAsync(
|
||||||
|
orderHashHex,
|
||||||
|
signedOrder.makerAddress,
|
||||||
|
signatureHex,
|
||||||
|
);
|
||||||
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true when SignatureType=EIP712 and signature is valid', async () => {
|
it('should return true when SignatureType=EIP712 and signature is valid', async () => {
|
||||||
@ -344,14 +356,16 @@ describe('MixinSignatureValidator', () => {
|
|||||||
ethUtil.toBuffer(`0x${SignatureType.Wallet}`),
|
ethUtil.toBuffer(`0x${SignatureType.Wallet}`),
|
||||||
]);
|
]);
|
||||||
const signatureHex = ethUtil.bufferToHex(signature);
|
const signatureHex = ethUtil.bufferToHex(signature);
|
||||||
await expectContractCallFailedAsync(
|
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||||
signatureValidator.publicIsValidSignature.callAsync(
|
orderHashHex,
|
||||||
orderHashHex,
|
ExchangeRevertErrors.SignatureErrorCode.WalletError,
|
||||||
maliciousWallet.address,
|
|
||||||
signatureHex,
|
|
||||||
),
|
|
||||||
RevertReason.WalletError,
|
|
||||||
);
|
);
|
||||||
|
const tx = signatureValidator.publicIsValidSignature.callAsync(
|
||||||
|
orderHashHex,
|
||||||
|
maliciousWallet.address,
|
||||||
|
signatureHex,
|
||||||
|
);
|
||||||
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true when SignatureType=Validator, signature is valid and validator is approved', async () => {
|
it('should return true when SignatureType=Validator, signature is valid and validator is approved', async () => {
|
||||||
@ -390,10 +404,16 @@ describe('MixinSignatureValidator', () => {
|
|||||||
const signature = Buffer.concat([validatorAddress, signatureType]);
|
const signature = Buffer.concat([validatorAddress, signatureType]);
|
||||||
const signatureHex = ethUtil.bufferToHex(signature);
|
const signatureHex = ethUtil.bufferToHex(signature);
|
||||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
await expectContractCallFailedAsync(
|
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||||
signatureValidator.publicIsValidSignature.callAsync(orderHashHex, signerAddress, signatureHex),
|
orderHashHex,
|
||||||
RevertReason.ValidatorError,
|
ExchangeRevertErrors.SignatureErrorCode.ValidatorError,
|
||||||
);
|
);
|
||||||
|
const tx = signatureValidator.publicIsValidSignature.callAsync(
|
||||||
|
orderHashHex,
|
||||||
|
signerAddress,
|
||||||
|
signatureHex,
|
||||||
|
);
|
||||||
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
it('should return false when SignatureType=Validator, signature is valid and validator is not approved', async () => {
|
it('should return false when SignatureType=Validator, signature is valid and validator is not approved', async () => {
|
||||||
// Set approval of signature validator to false
|
// Set approval of signature validator to false
|
||||||
|
@ -4,7 +4,6 @@ import {
|
|||||||
chaiSetup,
|
chaiSetup,
|
||||||
constants,
|
constants,
|
||||||
ERC20BalancesByOwner,
|
ERC20BalancesByOwner,
|
||||||
expectTransactionFailedAsync,
|
|
||||||
OrderFactory,
|
OrderFactory,
|
||||||
orderUtils,
|
orderUtils,
|
||||||
provider,
|
provider,
|
||||||
@ -17,10 +16,12 @@ import {
|
|||||||
assetDataUtils,
|
assetDataUtils,
|
||||||
ExchangeRevertErrors,
|
ExchangeRevertErrors,
|
||||||
generatePseudoRandomSalt,
|
generatePseudoRandomSalt,
|
||||||
|
orderHashUtils,
|
||||||
transactionHashUtils,
|
transactionHashUtils,
|
||||||
} from '@0x/order-utils';
|
} from '@0x/order-utils';
|
||||||
import {
|
import {
|
||||||
EIP712DomainWithDefaultSchema,
|
EIP712DomainWithDefaultSchema,
|
||||||
|
OrderStatus,
|
||||||
OrderWithoutDomain,
|
OrderWithoutDomain,
|
||||||
RevertReason,
|
RevertReason,
|
||||||
SignedOrder,
|
SignedOrder,
|
||||||
@ -36,7 +37,7 @@ chaiSetup.configure();
|
|||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
||||||
|
|
||||||
describe.only('Exchange transactions', () => {
|
describe('Exchange transactions', () => {
|
||||||
let chainId: number;
|
let chainId: number;
|
||||||
let senderAddress: string;
|
let senderAddress: string;
|
||||||
let owner: string;
|
let owner: string;
|
||||||
@ -153,9 +154,11 @@ describe.only('Exchange transactions', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if not called by specified sender', async () => {
|
it('should throw if not called by specified sender', async () => {
|
||||||
|
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
const transactionHashHex = transactionHashUtils.getTransactionHashHex(signedTx);
|
const transactionHashHex = transactionHashUtils.getTransactionHashHex(signedTx);
|
||||||
const expectedError = new ExchangeRevertErrors.TransactionExecutionError(
|
const expectedError = new ExchangeRevertErrors.TransactionExecutionError(
|
||||||
transactionHashHex,
|
transactionHashHex,
|
||||||
|
new ExchangeRevertErrors.InvalidSenderError(orderHashHex, takerAddress).encode(),
|
||||||
);
|
);
|
||||||
const tx = exchangeWrapper.executeTransactionAsync(signedTx, takerAddress);
|
const tx = exchangeWrapper.executeTransactionAsync(signedTx, takerAddress);
|
||||||
return expect(tx).to.revertWith(expectedError);
|
return expect(tx).to.revertWith(expectedError);
|
||||||
@ -198,10 +201,13 @@ describe.only('Exchange transactions', () => {
|
|||||||
|
|
||||||
it('should throw if the a 0x transaction with the same transactionHash has already been executed', async () => {
|
it('should throw if the a 0x transaction with the same transactionHash has already been executed', async () => {
|
||||||
await exchangeWrapper.executeTransactionAsync(signedTx, senderAddress);
|
await exchangeWrapper.executeTransactionAsync(signedTx, senderAddress);
|
||||||
return expectTransactionFailedAsync(
|
const transactionHashHex = transactionHashUtils.getTransactionHashHex(signedTx);
|
||||||
exchangeWrapper.executeTransactionAsync(signedTx, senderAddress),
|
const expectedError = new ExchangeRevertErrors.TransactionError(
|
||||||
RevertReason.InvalidTxHash,
|
transactionHashHex,
|
||||||
|
ExchangeRevertErrors.TransactionErrorCode.AlreadyExecuted,
|
||||||
);
|
);
|
||||||
|
const tx = exchangeWrapper.executeTransactionAsync(signedTx, senderAddress);
|
||||||
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should reset the currentContextAddress', async () => {
|
it('should reset the currentContextAddress', async () => {
|
||||||
@ -218,18 +224,25 @@ describe.only('Exchange transactions', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if not called by specified sender', async () => {
|
it('should throw if not called by specified sender', async () => {
|
||||||
return expectTransactionFailedAsync(
|
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
exchangeWrapper.executeTransactionAsync(signedTx, makerAddress),
|
const transactionHashHex = transactionHashUtils.getTransactionHashHex(signedTx);
|
||||||
RevertReason.FailedExecution,
|
const expectedError = new ExchangeRevertErrors.TransactionExecutionError(
|
||||||
|
transactionHashHex,
|
||||||
|
new ExchangeRevertErrors.InvalidSenderError(orderHashHex, makerAddress).encode(),
|
||||||
);
|
);
|
||||||
|
const tx = exchangeWrapper.executeTransactionAsync(signedTx, makerAddress);
|
||||||
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should cancel the order when signed by maker and called by sender', async () => {
|
it('should cancel the order when signed by maker and called by sender', async () => {
|
||||||
await exchangeWrapper.executeTransactionAsync(signedTx, senderAddress);
|
await exchangeWrapper.executeTransactionAsync(signedTx, senderAddress);
|
||||||
return expectTransactionFailedAsync(
|
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
exchangeWrapper.fillOrderAsync(signedOrder, senderAddress),
|
const expectedError = new ExchangeRevertErrors.OrderStatusError(
|
||||||
RevertReason.OrderUnfillable,
|
orderHashHex,
|
||||||
|
OrderStatus.Cancelled,
|
||||||
);
|
);
|
||||||
|
const tx = exchangeWrapper.fillOrderAsync(signedOrder, senderAddress);
|
||||||
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -271,17 +284,21 @@ describe.only('Exchange transactions', () => {
|
|||||||
signedOrder.signature,
|
signedOrder.signature,
|
||||||
);
|
);
|
||||||
const signedFillTx = takerTransactionFactory.newSignedTransaction(fillData);
|
const signedFillTx = takerTransactionFactory.newSignedTransaction(fillData);
|
||||||
return expectTransactionFailedAsync(
|
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
exchangeWrapperContract.fillOrder.sendTransactionAsync(
|
const transactionHashHex = transactionHashUtils.getTransactionHashHex(signedFillTx);
|
||||||
orderWithoutDomain,
|
const expectedError = new ExchangeRevertErrors.TransactionExecutionError(
|
||||||
takerAssetFillAmount,
|
transactionHashHex,
|
||||||
signedFillTx.salt,
|
new ExchangeRevertErrors.OrderStatusError(orderHashHex, OrderStatus.Cancelled).encode(),
|
||||||
signedOrder.signature,
|
|
||||||
signedFillTx.signature,
|
|
||||||
{ from: takerAddress },
|
|
||||||
),
|
|
||||||
RevertReason.FailedExecution,
|
|
||||||
);
|
);
|
||||||
|
const tx = exchangeWrapperContract.fillOrder.sendTransactionAsync(
|
||||||
|
orderWithoutDomain,
|
||||||
|
takerAssetFillAmount,
|
||||||
|
signedFillTx.salt,
|
||||||
|
signedOrder.signature,
|
||||||
|
signedFillTx.signature,
|
||||||
|
{ from: takerAddress },
|
||||||
|
);
|
||||||
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not cancel an order if not called from the order's sender", async () => {
|
it("should not cancel an order if not called from the order's sender", async () => {
|
||||||
@ -391,16 +408,14 @@ describe.only('Exchange transactions', () => {
|
|||||||
orderWithoutDomain = orderUtils.getOrderWithoutDomain(signedOrder);
|
orderWithoutDomain = orderUtils.getOrderWithoutDomain(signedOrder);
|
||||||
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
||||||
const salt = generatePseudoRandomSalt();
|
const salt = generatePseudoRandomSalt();
|
||||||
return expectTransactionFailedAsync(
|
const tx = whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
|
||||||
whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
|
orderWithoutDomain,
|
||||||
orderWithoutDomain,
|
takerAssetFillAmount,
|
||||||
takerAssetFillAmount,
|
salt,
|
||||||
salt,
|
signedOrder.signature,
|
||||||
signedOrder.signature,
|
{ from: takerAddress },
|
||||||
{ from: takerAddress },
|
|
||||||
),
|
|
||||||
RevertReason.MakerNotWhitelisted,
|
|
||||||
);
|
);
|
||||||
|
return expect(tx).to.revertWith(RevertReason.MakerNotWhitelisted);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should revert if taker has not been whitelisted', async () => {
|
it('should revert if taker has not been whitelisted', async () => {
|
||||||
@ -413,16 +428,14 @@ describe.only('Exchange transactions', () => {
|
|||||||
orderWithoutDomain = orderUtils.getOrderWithoutDomain(signedOrder);
|
orderWithoutDomain = orderUtils.getOrderWithoutDomain(signedOrder);
|
||||||
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
||||||
const salt = generatePseudoRandomSalt();
|
const salt = generatePseudoRandomSalt();
|
||||||
return expectTransactionFailedAsync(
|
const tx = whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
|
||||||
whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
|
orderWithoutDomain,
|
||||||
orderWithoutDomain,
|
takerAssetFillAmount,
|
||||||
takerAssetFillAmount,
|
salt,
|
||||||
salt,
|
signedOrder.signature,
|
||||||
signedOrder.signature,
|
{ from: takerAddress },
|
||||||
{ from: takerAddress },
|
|
||||||
),
|
|
||||||
RevertReason.TakerNotWhitelisted,
|
|
||||||
);
|
);
|
||||||
|
return expect(tx).to.revertWith(RevertReason.TakerNotWhitelisted);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fill the order if maker and taker have been whitelisted', async () => {
|
it('should fill the order if maker and taker have been whitelisted', async () => {
|
||||||
|
@ -6,7 +6,6 @@ import {
|
|||||||
BalanceAmountScenario,
|
BalanceAmountScenario,
|
||||||
chaiSetup,
|
chaiSetup,
|
||||||
constants,
|
constants,
|
||||||
expectTransactionFailedAsync,
|
|
||||||
ExpirationTimeSecondsScenario,
|
ExpirationTimeSecondsScenario,
|
||||||
FeeRecipientAddressScenario,
|
FeeRecipientAddressScenario,
|
||||||
FillScenario,
|
FillScenario,
|
||||||
@ -441,7 +440,11 @@ export class FillOrderCombinatorialUtils {
|
|||||||
lazyStore: BalanceAndProxyAllowanceLazyStore,
|
lazyStore: BalanceAndProxyAllowanceLazyStore,
|
||||||
fillRevertReasonIfExists: RevertReason | RevertError | undefined,
|
fillRevertReasonIfExists: RevertReason | RevertError | undefined,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
<<<<<<< HEAD
|
||||||
if (fillRevertReasonIfExists !== undefined) {
|
if (fillRevertReasonIfExists !== undefined) {
|
||||||
|
=======
|
||||||
|
if (!_.isUndefined(fillRevertReasonIfExists)) {
|
||||||
|
>>>>>>> In `@0x/contracts-exchange`: Update tests for rich reverts
|
||||||
const tx = this.exchangeWrapper.fillOrderAsync(signedOrder, this.takerAddress, { takerAssetFillAmount });
|
const tx = this.exchangeWrapper.fillOrderAsync(signedOrder, this.takerAddress, { takerAssetFillAmount });
|
||||||
return expect(tx).to.revertWith(fillRevertReasonIfExists);
|
return expect(tx).to.revertWith(fillRevertReasonIfExists);
|
||||||
}
|
}
|
||||||
@ -945,14 +948,14 @@ function validationErrorToRevertError(order: Order, reason: RevertReason): Rever
|
|||||||
case RevertReason.InvalidTakerAmount:
|
case RevertReason.InvalidTakerAmount:
|
||||||
return new ExchangeRevertErrors.FillError(
|
return new ExchangeRevertErrors.FillError(
|
||||||
orderHash,
|
orderHash,
|
||||||
ExchangeRevertErrors.FillErrorCodes.InvalidTakerAmount,
|
ExchangeRevertErrors.FillErrorCode.InvalidTakerAmount,
|
||||||
);
|
);
|
||||||
case RevertReason.TakerOverpay:
|
case RevertReason.TakerOverpay:
|
||||||
return new ExchangeRevertErrors.FillError(orderHash, ExchangeRevertErrors.FillErrorCodes.TakerOverpay);
|
return new ExchangeRevertErrors.FillError(orderHash, ExchangeRevertErrors.FillErrorCode.TakerOverpay);
|
||||||
case RevertReason.OrderOverfill:
|
case RevertReason.OrderOverfill:
|
||||||
return new ExchangeRevertErrors.FillError(orderHash, ExchangeRevertErrors.FillErrorCodes.Overfill);
|
return new ExchangeRevertErrors.FillError(orderHash, ExchangeRevertErrors.FillErrorCode.Overfill);
|
||||||
case RevertReason.InvalidFillPrice:
|
case RevertReason.InvalidFillPrice:
|
||||||
return new ExchangeRevertErrors.FillError(orderHash, ExchangeRevertErrors.FillErrorCodes.InvalidFillPrice);
|
return new ExchangeRevertErrors.FillError(orderHash, ExchangeRevertErrors.FillErrorCode.InvalidFillPrice);
|
||||||
case RevertReason.TransferFailed:
|
case RevertReason.TransferFailed:
|
||||||
return new ExchangeRevertErrors.AssetProxyTransferError(orderHash, undefined, 'TRANSFER_FAILED');
|
return new ExchangeRevertErrors.AssetProxyTransferError(orderHash, undefined, 'TRANSFER_FAILED');
|
||||||
default:
|
default:
|
||||||
|
@ -5,18 +5,16 @@ import {
|
|||||||
chaiSetup,
|
chaiSetup,
|
||||||
constants,
|
constants,
|
||||||
ERC20BalancesByOwner,
|
ERC20BalancesByOwner,
|
||||||
expectTransactionFailedAsync,
|
|
||||||
getLatestBlockTimestampAsync,
|
getLatestBlockTimestampAsync,
|
||||||
increaseTimeAndMineBlockAsync,
|
increaseTimeAndMineBlockAsync,
|
||||||
OrderFactory,
|
OrderFactory,
|
||||||
OrderStatus,
|
|
||||||
provider,
|
provider,
|
||||||
txDefaults,
|
txDefaults,
|
||||||
web3Wrapper,
|
web3Wrapper,
|
||||||
} from '@0x/contracts-test-utils';
|
} from '@0x/contracts-test-utils';
|
||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||||
import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
|
import { assetDataUtils, ExchangeRevertErrors, orderHashUtils } from '@0x/order-utils';
|
||||||
import { RevertReason, SignedOrder } from '@0x/types';
|
import { OrderStatus, RevertReason, SignedOrder } from '@0x/types';
|
||||||
import { BigNumber, providerUtils } from '@0x/utils';
|
import { BigNumber, providerUtils } from '@0x/utils';
|
||||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
@ -152,10 +150,8 @@ describe('Exchange wrappers', () => {
|
|||||||
await reentrantErc20Token.setReentrantFunction.sendTransactionAsync(functionId),
|
await reentrantErc20Token.setReentrantFunction.sendTransactionAsync(functionId),
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
await expectTransactionFailedAsync(
|
const tx = exchangeWrapper.fillOrKillOrderAsync(signedOrder, takerAddress);
|
||||||
exchangeWrapper.fillOrKillOrderAsync(signedOrder, takerAddress),
|
return expect(tx).to.revertWith(RevertReason.ReentrancyIllegal);
|
||||||
RevertReason.ReentrancyIllegal,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -210,11 +206,13 @@ describe('Exchange wrappers', () => {
|
|||||||
const signedOrder = await orderFactory.newSignedOrderAsync({
|
const signedOrder = await orderFactory.newSignedOrderAsync({
|
||||||
expirationTimeSeconds: new BigNumber(currentTimestamp).minus(10),
|
expirationTimeSeconds: new BigNumber(currentTimestamp).minus(10),
|
||||||
});
|
});
|
||||||
|
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
return expectTransactionFailedAsync(
|
const expectedError = new ExchangeRevertErrors.OrderStatusError(
|
||||||
exchangeWrapper.fillOrKillOrderAsync(signedOrder, takerAddress),
|
orderHashHex,
|
||||||
RevertReason.OrderUnfillable,
|
OrderStatus.Expired,
|
||||||
);
|
);
|
||||||
|
const tx = exchangeWrapper.fillOrKillOrderAsync(signedOrder, takerAddress);
|
||||||
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if entire takerAssetFillAmount not filled', async () => {
|
it('should throw if entire takerAssetFillAmount not filled', async () => {
|
||||||
@ -224,10 +222,12 @@ describe('Exchange wrappers', () => {
|
|||||||
takerAssetFillAmount: signedOrder.takerAssetAmount.div(2),
|
takerAssetFillAmount: signedOrder.takerAssetAmount.div(2),
|
||||||
});
|
});
|
||||||
|
|
||||||
return expectTransactionFailedAsync(
|
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||||
exchangeWrapper.fillOrKillOrderAsync(signedOrder, takerAddress),
|
const expectedError = new ExchangeRevertErrors.IncompleteFillError(
|
||||||
RevertReason.CompleteFillFailed,
|
orderHashHex,
|
||||||
);
|
);
|
||||||
|
const tx = exchangeWrapper.fillOrKillOrderAsync(signedOrder, takerAddress);
|
||||||
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -462,10 +462,8 @@ describe('Exchange wrappers', () => {
|
|||||||
await reentrantErc20Token.setReentrantFunction.sendTransactionAsync(functionId),
|
await reentrantErc20Token.setReentrantFunction.sendTransactionAsync(functionId),
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
await expectTransactionFailedAsync(
|
const tx = exchangeWrapper.batchFillOrdersAsync([signedOrder], takerAddress);
|
||||||
exchangeWrapper.batchFillOrdersAsync([signedOrder], takerAddress),
|
return expect(tx).to.revertWith(RevertReason.ReentrancyIllegal);
|
||||||
RevertReason.ReentrancyIllegal,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -531,10 +529,8 @@ describe('Exchange wrappers', () => {
|
|||||||
await reentrantErc20Token.setReentrantFunction.sendTransactionAsync(functionId),
|
await reentrantErc20Token.setReentrantFunction.sendTransactionAsync(functionId),
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
await expectTransactionFailedAsync(
|
const tx = exchangeWrapper.batchFillOrKillOrdersAsync([signedOrder], takerAddress);
|
||||||
exchangeWrapper.batchFillOrKillOrdersAsync([signedOrder], takerAddress),
|
return expect(tx).to.revertWith(RevertReason.ReentrancyIllegal);
|
||||||
RevertReason.ReentrancyIllegal,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -595,13 +591,17 @@ describe('Exchange wrappers', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await exchangeWrapper.fillOrKillOrderAsync(signedOrders[0], takerAddress);
|
await exchangeWrapper.fillOrKillOrderAsync(signedOrders[0], takerAddress);
|
||||||
|
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrders[0]);
|
||||||
return expectTransactionFailedAsync(
|
const expectedError = new ExchangeRevertErrors.OrderStatusError(
|
||||||
exchangeWrapper.batchFillOrKillOrdersAsync(signedOrders, takerAddress, {
|
orderHashHex,
|
||||||
takerAssetFillAmounts,
|
OrderStatus.FullyFilled,
|
||||||
}),
|
|
||||||
RevertReason.OrderUnfillable,
|
|
||||||
);
|
);
|
||||||
|
const tx = exchangeWrapper.batchFillOrKillOrdersAsync(
|
||||||
|
signedOrders,
|
||||||
|
takerAddress,
|
||||||
|
{ takerAssetFillAmounts },
|
||||||
|
);
|
||||||
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -749,12 +749,12 @@ describe('Exchange wrappers', () => {
|
|||||||
await reentrantErc20Token.setReentrantFunction.sendTransactionAsync(functionId),
|
await reentrantErc20Token.setReentrantFunction.sendTransactionAsync(functionId),
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
await expectTransactionFailedAsync(
|
const tx = exchangeWrapper.marketSellOrdersAsync(
|
||||||
exchangeWrapper.marketSellOrdersAsync([signedOrder], takerAddress, {
|
[signedOrder],
|
||||||
takerAssetFillAmount: signedOrder.takerAssetAmount,
|
takerAddress,
|
||||||
}),
|
{ takerAssetFillAmount: signedOrder.takerAssetAmount},
|
||||||
RevertReason.ReentrancyIllegal,
|
|
||||||
);
|
);
|
||||||
|
return expect(tx).to.revertWith(RevertReason.ReentrancyIllegal);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -839,15 +839,21 @@ describe('Exchange wrappers', () => {
|
|||||||
}),
|
}),
|
||||||
await orderFactory.newSignedOrderAsync(),
|
await orderFactory.newSignedOrderAsync(),
|
||||||
];
|
];
|
||||||
|
const reconstructedOrder = {
|
||||||
return expectTransactionFailedAsync(
|
...signedOrders[1],
|
||||||
exchangeWrapper.marketSellOrdersAsync(signedOrders, takerAddress, {
|
takerAssetData: signedOrders[0].takerAssetData,
|
||||||
takerAssetFillAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1000), 18),
|
};
|
||||||
}),
|
const orderHashHex = orderHashUtils.getOrderHashHex(reconstructedOrder);
|
||||||
// We simply use the takerAssetData from the first order for all orders.
|
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||||
// If they are not the same, the contract throws when validating the order signature
|
orderHashHex,
|
||||||
RevertReason.InvalidOrderSignature,
|
ExchangeRevertErrors.SignatureErrorCode.BadSignature,
|
||||||
);
|
);
|
||||||
|
const tx = exchangeWrapper.marketSellOrdersAsync(
|
||||||
|
signedOrders,
|
||||||
|
takerAddress,
|
||||||
|
{ takerAssetFillAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1000), 18) },
|
||||||
|
);
|
||||||
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1010,12 +1016,12 @@ describe('Exchange wrappers', () => {
|
|||||||
await reentrantErc20Token.setReentrantFunction.sendTransactionAsync(functionId),
|
await reentrantErc20Token.setReentrantFunction.sendTransactionAsync(functionId),
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
await expectTransactionFailedAsync(
|
const tx = exchangeWrapper.marketBuyOrdersAsync(
|
||||||
exchangeWrapper.marketBuyOrdersAsync([signedOrder], takerAddress, {
|
[signedOrder],
|
||||||
makerAssetFillAmount: signedOrder.makerAssetAmount,
|
takerAddress,
|
||||||
}),
|
{ makerAssetFillAmount: signedOrder.makerAssetAmount },
|
||||||
RevertReason.ReentrancyIllegal,
|
|
||||||
);
|
);
|
||||||
|
return expect(tx).to.revertWith(RevertReason.ReentrancyIllegal);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -1100,13 +1106,21 @@ describe('Exchange wrappers', () => {
|
|||||||
}),
|
}),
|
||||||
await orderFactory.newSignedOrderAsync(),
|
await orderFactory.newSignedOrderAsync(),
|
||||||
];
|
];
|
||||||
|
const reconstructedOrder = {
|
||||||
return expectTransactionFailedAsync(
|
...signedOrders[1],
|
||||||
exchangeWrapper.marketBuyOrdersAsync(signedOrders, takerAddress, {
|
makerAssetData: signedOrders[0].makerAssetData,
|
||||||
makerAssetFillAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1000), 18),
|
};
|
||||||
}),
|
const orderHashHex = orderHashUtils.getOrderHashHex(reconstructedOrder);
|
||||||
RevertReason.InvalidOrderSignature,
|
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||||
|
orderHashHex,
|
||||||
|
ExchangeRevertErrors.SignatureErrorCode.BadSignature,
|
||||||
);
|
);
|
||||||
|
const tx = exchangeWrapper.marketBuyOrdersAsync(
|
||||||
|
signedOrders,
|
||||||
|
takerAddress,
|
||||||
|
{ makerAssetFillAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1000), 18) },
|
||||||
|
);
|
||||||
|
return expect(tx).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user