merge check-revert-reasons
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
"build": "wsrun build $PKG --fast-exit -r --stages",
|
||||
"build:monorepo_scripts": "PKG=@0xproject/monorepo-scripts yarn build",
|
||||
"clean": "wsrun clean $PKG --fast-exit -r --parallel",
|
||||
"remove_node_modules": "lerna clean --yes; rm -rf node_modules",
|
||||
"rebuild": "run-s clean build",
|
||||
"test": "wsrun test $PKG --fast-exit --serial --exclude-missing",
|
||||
"stage_docs": "wsrun docs:stage $PKG --fast-exit --parallel --exclude-missing",
|
||||
|
||||
@@ -23,13 +23,13 @@ import "../../protocol/Exchange/interfaces/IExchange.sol";
|
||||
import "../../protocol/Exchange/libs/LibOrder.sol";
|
||||
import "../../utils/Ownable/Ownable.sol";
|
||||
|
||||
contract Whitelist is
|
||||
contract Whitelist is
|
||||
Ownable
|
||||
{
|
||||
// Revert reasons
|
||||
string constant MAKER_NOT_WHITELISTED = "Maker address not whitelisted.";
|
||||
string constant TAKER_NOT_WHITELISTED = "Taker address not whitelisted.";
|
||||
string constant INVALID_SENDER = "Sender must equal transaction origin.";
|
||||
string constant MAKER_NOT_WHITELISTED = "MAKER_NOT_WHITELISTED"; // Maker address not whitelisted.
|
||||
string constant TAKER_NOT_WHITELISTED = "TAKER_NOT_WHITELISTED"; // Taker address not whitelisted.
|
||||
string constant INVALID_SENDER = "INVALID_SENDER"; // Sender must equal transaction origin.
|
||||
|
||||
// Mapping of address => whitelist status.
|
||||
mapping (address => bool) public isWhitelisted;
|
||||
@@ -77,7 +77,7 @@ contract Whitelist is
|
||||
public
|
||||
{
|
||||
address takerAddress = msg.sender;
|
||||
|
||||
|
||||
// This contract must be the entry point for the transaction.
|
||||
require(
|
||||
takerAddress == tx.origin,
|
||||
|
||||
@@ -23,8 +23,8 @@ import "./IERC20Token.sol";
|
||||
|
||||
contract ERC20Token is IERC20Token {
|
||||
|
||||
string constant INSUFFICIENT_BALANCE = "Insufficient balance to complete transfer.";
|
||||
string constant INSUFFICIENT_ALLOWANCE = "Insufficient allowance to complete transfer.";
|
||||
string constant INSUFFICIENT_BALANCE = "ERC20_INSUFFICIENT_BALANCE";
|
||||
string constant INSUFFICIENT_ALLOWANCE = "ERC20_INSUFFICIENT_ALLOWANCE";
|
||||
string constant OVERFLOW = "Transfer would result in an overflow.";
|
||||
|
||||
mapping (address => uint256) balances;
|
||||
@@ -97,4 +97,3 @@ contract ERC20Token is IERC20Token {
|
||||
return allowed[_owner][_spender];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,18 @@ export function expectRevertOrAlwaysFailingTransactionAsync<T>(p: Promise<T>): P
|
||||
return expectRevertOrOtherErrorAsync(p, 'always failing transaction');
|
||||
}
|
||||
|
||||
/**
|
||||
* Rejects if the given Promise does not reject with the given revert reason or "always
|
||||
* failing transaction" error.
|
||||
* @param p the Promise which is expected to reject
|
||||
* @param reason a specific revert reason
|
||||
* @returns a new Promise which will reject if the conditions are not met and
|
||||
* otherwise resolve with no value.
|
||||
*/
|
||||
export function expectRevertReasonOrAlwaysFailingTransactionAsync<T>(p: Promise<T>, reason: string): PromiseLike<void> {
|
||||
return _expectEitherErrorAsync(p, 'always failing transaction', reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rejects if the given Promise does not reject with a "revert" or "Contract
|
||||
* call failed" error.
|
||||
|
||||
@@ -19,21 +19,8 @@ const TESTRPC_PRIVATE_KEYS_STRINGS = [
|
||||
export const constants = {
|
||||
INVALID_OPCODE: 'invalid opcode',
|
||||
REVERT: 'revert',
|
||||
LIB_BYTES_GREATER_THAN_ZERO_LENGTH_REQUIRED: 'GREATER_THAN_ZERO_LENGTH_REQUIRED',
|
||||
LIB_BYTES_GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED: 'GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED',
|
||||
LIB_BYTES_GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED: 'GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED',
|
||||
LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED: 'GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED',
|
||||
LIB_BYTES_GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED: 'GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED',
|
||||
LIB_BYTES_GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED: 'GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED',
|
||||
ERC20_INSUFFICIENT_BALANCE: 'Insufficient balance to complete transfer.',
|
||||
ERC20_INSUFFICIENT_ALLOWANCE: 'Insufficient allowance to complete transfer.',
|
||||
ERC20_PROXY_ID: 1,
|
||||
ERC721_PROXY_ID: 2,
|
||||
EXCHANGE_LENGTH_GREATER_THAN_0_REQUIRED: 'LENGTH_GREATER_THAN_0_REQUIRED',
|
||||
EXCHANGE_SIGNATURE_UNSUPPORTED: 'SIGNATURE_UNSUPPORTED',
|
||||
EXCHANGE_SIGNATURE_ILLEGAL: 'SIGNATURE_ILLEGAL',
|
||||
EXCHANGE_LENGTH_0_REQUIRED: 'LENGTH_0_REQUIRED',
|
||||
EXCHANGE_LENGTH_65_REQUIRED: 'LENGTH_65_REQUIRED',
|
||||
TESTRPC_NETWORK_ID: 50,
|
||||
// Note(albrow): In practice V8 and most other engines limit the minimum
|
||||
// interval for setInterval to 10ms. We still set it to 0 here in order to
|
||||
|
||||
@@ -227,3 +227,47 @@ export interface FillScenario {
|
||||
makerStateScenario: TraderStateScenario;
|
||||
takerStateScenario: TraderStateScenario;
|
||||
}
|
||||
|
||||
export enum RevertReasons {
|
||||
OrderUnfillable = 'ORDER_UNFILLABLE',
|
||||
InvalidMaker = 'INVALID_MAKER',
|
||||
InvalidTaker = 'INVALID_TAKER',
|
||||
InvalidSender = 'INVALID_SENDER',
|
||||
InvalidOrderSignature = 'INVALID_ORDER_SIGNATURE',
|
||||
InvalidTakerAmount = 'INVALID_TAKER_AMOUNT',
|
||||
RoundingError = 'ROUNDING_ERROR',
|
||||
InvalidSignature = 'INVALID_SIGNATURE',
|
||||
SignatureIllegal = 'SIGNATURE_ILLEGAL',
|
||||
SignatureUnsupported = 'SIGNATURE_UNSUPPORTED',
|
||||
InvalidNewOrderEpoch = 'INVALID_NEW_ORDER_EPOCH',
|
||||
CompleteFillFailed = 'COMPLETE_FILL_FAILED',
|
||||
NegativeSpreadRequired = 'NEGATIVE_SPREAD_REQUIRED',
|
||||
ReentrancyIllegal = 'REENTRANCY_ILLEGAL',
|
||||
InvalidTxHash = 'INVALID_TX_HASH',
|
||||
InvalidTxSignature = 'INVALID_TX_SIGNATURE',
|
||||
FailedExecution = 'FAILED_EXECUTION',
|
||||
AssetProxyMismatch = 'ASSET_PROXY_MISMATCH',
|
||||
AssetProxyIdMismatch = 'ASSET_PROXY_ID_MISMATCH',
|
||||
LengthGreaterThan0Required = 'LENGTH_GREATER_THAN_0_REQUIRED',
|
||||
Length0Required = 'LENGTH_0_REQUIRED',
|
||||
Length65Required = 'LENGTH_65_REQUIRED',
|
||||
InvalidAmount = 'INVALID_AMOUNT',
|
||||
TransferFailed = 'TRANSFER_FAILED',
|
||||
SenderNotAuthorized = 'SENDER_NOT_AUTHORIZED',
|
||||
TargetNotAuthorized = 'TARGET_NOT_AUTHORIZED',
|
||||
TargetAlreadyAuthorized = 'TARGET_ALREADY_AUTHORIZED',
|
||||
IndexOutOfBounds = 'INDEX_OUT_OF_BOUNDS',
|
||||
AuthorizedAddressMismatch = 'AUTHORIZED_ADDRESS_MISMATCH',
|
||||
OnlyContractOwner = 'ONLY_CONTRACT_OWNER',
|
||||
MakerNotWhitelisted = 'MAKER_NOT_WHITELISTED',
|
||||
TakerNotWhitelisted = 'TAKER_NOT_WHITELISTED',
|
||||
AssetProxyDoesNotExist = 'ASSET_PROXY_DOES_NOT_EXIST',
|
||||
LibBytesGreaterThanZeroLengthRequired = 'GREATER_THAN_ZERO_LENGTH_REQUIRED',
|
||||
LibBytesGreaterOrEqualTo4LengthRequired = 'GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED',
|
||||
LibBytesGreaterOrEqualTo20LengthRequired = 'GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED',
|
||||
LibBytesGreaterOrEqualTo32LengthRequired = 'GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED',
|
||||
LibBytesGreaterOrEqualToNestedBytesLengthRequired = 'GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED',
|
||||
LibBytesGreaterOrEqualToSourceBytesLengthRequired = 'GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED',
|
||||
Erc20InsufficientBalance = 'ERC20_INSUFFICIENT_BALANCE',
|
||||
Erc20InsufficientAllowance = 'ERC20_INSUFFICIENT_ALLOWANCE',
|
||||
}
|
||||
|
||||
@@ -4,9 +4,10 @@ import * as chai from 'chai';
|
||||
|
||||
import { MixinAuthorizableContract } from '../../src/generated_contract_wrappers/mixin_authorizable';
|
||||
import { artifacts } from '../../src/utils/artifacts';
|
||||
import { expectRevertOrAlwaysFailingTransactionAsync } from '../../src/utils/assertions';
|
||||
import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../../src/utils/assertions';
|
||||
import { chaiSetup } from '../../src/utils/chai_setup';
|
||||
import { constants } from '../../src/utils/constants';
|
||||
import { RevertReasons } from '../../src/utils/types';
|
||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -43,8 +44,9 @@ describe('Authorizable', () => {
|
||||
});
|
||||
describe('addAuthorizedAddress', () => {
|
||||
it('should throw if not called by owner', async () => {
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
authorizable.addAuthorizedAddress.sendTransactionAsync(notOwner, { from: notOwner }),
|
||||
RevertReasons.OnlyContractOwner,
|
||||
);
|
||||
});
|
||||
it('should allow owner to add an authorized address', async () => {
|
||||
@@ -60,8 +62,9 @@ describe('Authorizable', () => {
|
||||
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
|
||||
RevertReasons.TargetAlreadyAuthorized,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -72,10 +75,11 @@ describe('Authorizable', () => {
|
||||
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
authorizable.removeAuthorizedAddress.sendTransactionAsync(address, {
|
||||
from: notOwner,
|
||||
}),
|
||||
RevertReasons.OnlyContractOwner,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -95,10 +99,11 @@ describe('Authorizable', () => {
|
||||
});
|
||||
|
||||
it('should throw if owner attempts to remove an address that is not authorized', async () => {
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
authorizable.removeAuthorizedAddress.sendTransactionAsync(address, {
|
||||
from: owner,
|
||||
}),
|
||||
RevertReasons.TargetNotAuthorized,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,12 +15,16 @@ import { DummyERC721TokenContract } from '../../src/generated_contract_wrappers/
|
||||
import { ERC20ProxyContract } from '../../src/generated_contract_wrappers/e_r_c20_proxy';
|
||||
import { ERC721ProxyContract } from '../../src/generated_contract_wrappers/e_r_c721_proxy';
|
||||
import { artifacts } from '../../src/utils/artifacts';
|
||||
import { expectRevertOrAlwaysFailingTransactionAsync } from '../../src/utils/assertions';
|
||||
import {
|
||||
expectRevertOrAlwaysFailingTransactionAsync,
|
||||
expectRevertReasonOrAlwaysFailingTransactionAsync,
|
||||
} from '../../src/utils/assertions';
|
||||
import { chaiSetup } from '../../src/utils/chai_setup';
|
||||
import { constants } from '../../src/utils/constants';
|
||||
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
|
||||
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
|
||||
import { LogDecoder } from '../../src/utils/log_decoder';
|
||||
import { RevertReasons } from '../../src/utils/types';
|
||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -163,14 +167,15 @@ describe('Asset Transfer Proxies', () => {
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
// Perform a transfer; expect this to fail.
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
erc20Proxy.transferFrom.sendTransactionAsync(
|
||||
encodedAssetData,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
transferAmount,
|
||||
{ from: notAuthorized },
|
||||
{ from: exchangeAddress },
|
||||
),
|
||||
RevertReasons.TransferFailed,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -180,7 +185,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2);
|
||||
// Perform a transfer from makerAddress to takerAddress
|
||||
const amount = new BigNumber(10);
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
erc20Proxy.transferFrom.sendTransactionAsync(
|
||||
encodedAssetDataWithoutProxyId,
|
||||
makerAddress,
|
||||
@@ -190,6 +195,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
from: notAuthorized,
|
||||
},
|
||||
),
|
||||
RevertReasons.SenderNotAuthorized,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -239,10 +245,11 @@ describe('Asset Transfer Proxies', () => {
|
||||
const toAddresses = _.times(numTransfers, () => takerAddress);
|
||||
const amounts = _.times(numTransfers, () => amount);
|
||||
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
erc20Proxy.batchTransferFrom.sendTransactionAsync(assetData, fromAddresses, toAddresses, amounts, {
|
||||
from: notAuthorized,
|
||||
}),
|
||||
RevertReasons.SenderNotAuthorized,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -380,7 +387,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress);
|
||||
// Perform a transfer from makerAddress to takerAddress
|
||||
const amount = new BigNumber(0);
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
erc721Proxy.transferFrom.sendTransactionAsync(
|
||||
encodedAssetDataWithoutProxyId,
|
||||
makerAddress,
|
||||
@@ -388,6 +395,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
amount,
|
||||
{ from: exchangeAddress },
|
||||
),
|
||||
RevertReasons.InvalidAmount,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -400,7 +408,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress);
|
||||
// Perform a transfer from makerAddress to takerAddress
|
||||
const amount = new BigNumber(500);
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
erc721Proxy.transferFrom.sendTransactionAsync(
|
||||
encodedAssetDataWithoutProxyId,
|
||||
makerAddress,
|
||||
@@ -408,6 +416,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
amount,
|
||||
{ from: exchangeAddress },
|
||||
),
|
||||
RevertReasons.InvalidAmount,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -424,16 +433,17 @@ describe('Asset Transfer Proxies', () => {
|
||||
);
|
||||
// Perform a transfer; expect this to fail.
|
||||
const amount = new BigNumber(1);
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
erc20Proxy.transferFrom.sendTransactionAsync(
|
||||
encodedAssetDataWithoutProxyId,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
amount,
|
||||
{
|
||||
from: notAuthorized,
|
||||
from: exchangeAddress,
|
||||
},
|
||||
),
|
||||
RevertReasons.TransferFailed,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -443,7 +453,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2);
|
||||
// Perform a transfer from makerAddress to takerAddress
|
||||
const amount = new BigNumber(1);
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
erc721Proxy.transferFrom.sendTransactionAsync(
|
||||
encodedAssetDataWithoutProxyId,
|
||||
makerAddress,
|
||||
@@ -451,6 +461,7 @@ describe('Asset Transfer Proxies', () => {
|
||||
amount,
|
||||
{ from: notAuthorized },
|
||||
),
|
||||
RevertReasons.SenderNotAuthorized,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -502,10 +513,11 @@ describe('Asset Transfer Proxies', () => {
|
||||
const toAddresses = _.times(numTransfers, () => takerAddress);
|
||||
const amounts = _.times(numTransfers, () => new BigNumber(1));
|
||||
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
erc721Proxy.batchTransferFrom.sendTransactionAsync(assetData, fromAddresses, toAddresses, amounts, {
|
||||
from: notAuthorized,
|
||||
}),
|
||||
RevertReasons.SenderNotAuthorized,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -17,14 +17,17 @@ import {
|
||||
FillContractEventArgs,
|
||||
} from '../../src/generated_contract_wrappers/exchange';
|
||||
import { artifacts } from '../../src/utils/artifacts';
|
||||
import { expectRevertOrAlwaysFailingTransactionAsync } from '../../src/utils/assertions';
|
||||
import {
|
||||
expectRevertOrAlwaysFailingTransactionAsync,
|
||||
expectRevertReasonOrAlwaysFailingTransactionAsync,
|
||||
} from '../../src/utils/assertions';
|
||||
import { chaiSetup } from '../../src/utils/chai_setup';
|
||||
import { constants } from '../../src/utils/constants';
|
||||
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
|
||||
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
|
||||
import { ExchangeWrapper } from '../../src/utils/exchange_wrapper';
|
||||
import { OrderFactory } from '../../src/utils/order_factory';
|
||||
import { ERC20BalancesByOwner } from '../../src/utils/types';
|
||||
import { ERC20BalancesByOwner, RevertReasons } from '../../src/utils/types';
|
||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -146,16 +149,18 @@ describe('Exchange core', () => {
|
||||
const invalidSigBuff = Buffer.concat([v, invalidR, invalidS, signatureType]);
|
||||
const invalidSigHex = `0x${invalidSigBuff.toString('hex')}`;
|
||||
signedOrder.signature = invalidSigHex;
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress),
|
||||
RevertReasons.InvalidOrderSignature,
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw if no value is filled', async () => {
|
||||
signedOrder = orderFactory.newSignedOrder();
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress),
|
||||
RevertReasons.OrderUnfillable,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -167,8 +172,9 @@ describe('Exchange core', () => {
|
||||
});
|
||||
|
||||
it('should throw if not sent by maker', async () => {
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.cancelOrderAsync(signedOrder, takerAddress),
|
||||
RevertReasons.InvalidMaker,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -177,8 +183,9 @@ describe('Exchange core', () => {
|
||||
makerAssetAmount: new BigNumber(0),
|
||||
});
|
||||
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress),
|
||||
RevertReasons.OrderUnfillable,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -187,17 +194,19 @@ describe('Exchange core', () => {
|
||||
takerAssetAmount: new BigNumber(0),
|
||||
});
|
||||
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress),
|
||||
RevertReasons.OrderUnfillable,
|
||||
);
|
||||
});
|
||||
|
||||
it('should be able to cancel a full order', async () => {
|
||||
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
||||
takerAssetFillAmount: signedOrder.takerAssetAmount.div(2),
|
||||
}),
|
||||
RevertReasons.OrderUnfillable,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -218,8 +227,9 @@ describe('Exchange core', () => {
|
||||
|
||||
it('should throw if already cancelled', async () => {
|
||||
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress),
|
||||
RevertReasons.OrderUnfillable,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -227,8 +237,9 @@ describe('Exchange core', () => {
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
expirationTimeSeconds: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
|
||||
});
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress),
|
||||
RevertReasons.OrderUnfillable,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -244,10 +255,11 @@ describe('Exchange core', () => {
|
||||
});
|
||||
|
||||
const fillTakerAssetAmount2 = new BigNumber(1);
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
||||
takerAssetFillAmount: fillTakerAssetAmount2,
|
||||
}),
|
||||
RevertReasons.RoundingError,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -257,16 +269,18 @@ describe('Exchange core', () => {
|
||||
const orderEpoch = new BigNumber(1);
|
||||
await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
|
||||
const lesserOrderEpoch = new BigNumber(0);
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.cancelOrdersUpToAsync(lesserOrderEpoch, makerAddress),
|
||||
RevertReasons.InvalidNewOrderEpoch,
|
||||
);
|
||||
});
|
||||
|
||||
it('should fail to set orderEpoch equal to existing orderEpoch', async () => {
|
||||
const orderEpoch = new BigNumber(1);
|
||||
await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress),
|
||||
RevertReasons.InvalidNewOrderEpoch,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -398,8 +412,9 @@ describe('Exchange core', () => {
|
||||
expect(initialOwnerTakerAsset).to.be.bignumber.equal(takerAddress);
|
||||
// Call Exchange
|
||||
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }),
|
||||
RevertReasons.InvalidAmount,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -420,30 +435,26 @@ describe('Exchange core', () => {
|
||||
expect(initialOwnerTakerAsset).to.be.bignumber.equal(takerAddress);
|
||||
// Call Exchange
|
||||
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }),
|
||||
RevertReasons.InvalidAmount,
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw on partial fill', async () => {
|
||||
// Construct Exchange parameters
|
||||
const makerAssetId = erc721MakerAssetIds[0];
|
||||
const takerAssetId = erc721TakerAssetIds[0];
|
||||
signedOrder = orderFactory.newSignedOrder({
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
takerAssetAmount: new BigNumber(0),
|
||||
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
|
||||
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
|
||||
takerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, takerAssetId),
|
||||
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultTakerAssetAddress),
|
||||
});
|
||||
// Verify pre-conditions
|
||||
const initialOwnerMakerAsset = await erc721Token.ownerOf.callAsync(makerAssetId);
|
||||
expect(initialOwnerMakerAsset).to.be.bignumber.equal(makerAddress);
|
||||
const initialOwnerTakerAsset = await erc721Token.ownerOf.callAsync(takerAssetId);
|
||||
expect(initialOwnerTakerAsset).to.be.bignumber.equal(takerAddress);
|
||||
// Call Exchange
|
||||
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }),
|
||||
RevertReasons.RoundingError,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -9,11 +9,12 @@ import { ERC20ProxyContract } from '../../src/generated_contract_wrappers/e_r_c2
|
||||
import { ERC721ProxyContract } from '../../src/generated_contract_wrappers/e_r_c721_proxy';
|
||||
import { TestAssetProxyDispatcherContract } from '../../src/generated_contract_wrappers/test_asset_proxy_dispatcher';
|
||||
import { artifacts } from '../../src/utils/artifacts';
|
||||
import { expectRevertOrAlwaysFailingTransactionAsync } from '../../src/utils/assertions';
|
||||
import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../../src/utils/assertions';
|
||||
import { chaiSetup } from '../../src/utils/chai_setup';
|
||||
import { constants } from '../../src/utils/constants';
|
||||
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
|
||||
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
|
||||
import { RevertReasons } from '../../src/utils/types';
|
||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -178,13 +179,14 @@ describe('AssetProxyDispatcher', () => {
|
||||
const proxyAddress = await assetProxyDispatcher.getAssetProxy.callAsync(AssetProxyId.ERC20);
|
||||
expect(proxyAddress).to.be.equal(erc20Proxy.address);
|
||||
// The following transaction will throw because the currentAddress is no longer constants.NULL_ADDRESS
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
assetProxyDispatcher.registerAssetProxy.sendTransactionAsync(
|
||||
AssetProxyId.ERC20,
|
||||
erc20Proxy.address,
|
||||
constants.NULL_ADDRESS,
|
||||
{ from: owner },
|
||||
),
|
||||
RevertReasons.AssetProxyMismatch,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -219,25 +221,27 @@ describe('AssetProxyDispatcher', () => {
|
||||
|
||||
it('should throw if requesting address is not owner', async () => {
|
||||
const prevProxyAddress = constants.NULL_ADDRESS;
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
assetProxyDispatcher.registerAssetProxy.sendTransactionAsync(
|
||||
AssetProxyId.ERC20,
|
||||
erc20Proxy.address,
|
||||
prevProxyAddress,
|
||||
{ from: notOwner },
|
||||
),
|
||||
RevertReasons.OnlyContractOwner,
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw if attempting to register a proxy to the incorrect id', async () => {
|
||||
const prevProxyAddress = constants.NULL_ADDRESS;
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
assetProxyDispatcher.registerAssetProxy.sendTransactionAsync(
|
||||
AssetProxyId.ERC721,
|
||||
erc20Proxy.address,
|
||||
prevProxyAddress,
|
||||
{ from: owner },
|
||||
),
|
||||
RevertReasons.AssetProxyIdMismatch,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -310,7 +314,7 @@ describe('AssetProxyDispatcher', () => {
|
||||
const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2);
|
||||
// Perform a transfer from makerAddress to takerAddress
|
||||
const amount = new BigNumber(10);
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
assetProxyDispatcher.publicDispatchTransferFrom.sendTransactionAsync(
|
||||
encodedAssetDataWithoutProxyId,
|
||||
AssetProxyId.ERC20,
|
||||
@@ -319,6 +323,7 @@ describe('AssetProxyDispatcher', () => {
|
||||
amount,
|
||||
{ from: owner },
|
||||
),
|
||||
RevertReasons.AssetProxyDoesNotExist,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,7 +12,7 @@ import { ERC20ProxyContract } from '../../src/generated_contract_wrappers/e_r_c2
|
||||
import { ERC721ProxyContract } from '../../src/generated_contract_wrappers/e_r_c721_proxy';
|
||||
import { ExchangeContract } from '../../src/generated_contract_wrappers/exchange';
|
||||
import { artifacts } from '../../src/utils/artifacts';
|
||||
import { expectRevertOrAlwaysFailingTransactionAsync } from '../../src/utils/assertions';
|
||||
import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../../src/utils/assertions';
|
||||
import { chaiSetup } from '../../src/utils/chai_setup';
|
||||
import { constants } from '../../src/utils/constants';
|
||||
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
|
||||
@@ -20,7 +20,13 @@ import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
|
||||
import { ExchangeWrapper } from '../../src/utils/exchange_wrapper';
|
||||
import { MatchOrderTester } from '../../src/utils/match_order_tester';
|
||||
import { OrderFactory } from '../../src/utils/order_factory';
|
||||
import { ERC20BalancesByOwner, ERC721TokenIdsByOwner, OrderInfo, OrderStatus } from '../../src/utils/types';
|
||||
import {
|
||||
ERC20BalancesByOwner,
|
||||
ERC721TokenIdsByOwner,
|
||||
OrderInfo,
|
||||
OrderStatus,
|
||||
RevertReasons,
|
||||
} from '../../src/utils/types';
|
||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -601,8 +607,9 @@ describe('matchOrders', () => {
|
||||
// Cancel left order
|
||||
await exchangeWrapper.cancelOrderAsync(signedOrderLeft, signedOrderLeft.makerAddress);
|
||||
// Match orders
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress),
|
||||
RevertReasons.OrderUnfillable,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -625,8 +632,9 @@ describe('matchOrders', () => {
|
||||
// Cancel right order
|
||||
await exchangeWrapper.cancelOrderAsync(signedOrderRight, signedOrderRight.makerAddress);
|
||||
// Match orders
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress),
|
||||
RevertReasons.OrderUnfillable,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -647,7 +655,7 @@ describe('matchOrders', () => {
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
});
|
||||
// Match orders
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
matchOrderTester.matchOrdersAndVerifyBalancesAsync(
|
||||
signedOrderLeft,
|
||||
signedOrderRight,
|
||||
@@ -655,6 +663,7 @@ describe('matchOrders', () => {
|
||||
erc20BalancesByOwner,
|
||||
erc721TokenIdsByOwner,
|
||||
),
|
||||
RevertReasons.NegativeSpreadRequired,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -675,7 +684,7 @@ describe('matchOrders', () => {
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
});
|
||||
// Match orders
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
matchOrderTester.matchOrdersAndVerifyBalancesAsync(
|
||||
signedOrderLeft,
|
||||
signedOrderRight,
|
||||
@@ -683,6 +692,11 @@ describe('matchOrders', () => {
|
||||
erc20BalancesByOwner,
|
||||
erc721TokenIdsByOwner,
|
||||
),
|
||||
// We are assuming assetData fields of the right order are the
|
||||
// reverse of the left order, rather than checking equality. This
|
||||
// saves a bunch of gas, but as a result if the assetData fields are
|
||||
// off then the failure ends up happening at signature validation
|
||||
RevertReasons.InvalidOrderSignature,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -705,7 +719,7 @@ describe('matchOrders', () => {
|
||||
feeRecipientAddress: feeRecipientAddressRight,
|
||||
});
|
||||
// Match orders
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
matchOrderTester.matchOrdersAndVerifyBalancesAsync(
|
||||
signedOrderLeft,
|
||||
signedOrderRight,
|
||||
@@ -713,6 +727,7 @@ describe('matchOrders', () => {
|
||||
erc20BalancesByOwner,
|
||||
erc721TokenIdsByOwner,
|
||||
),
|
||||
RevertReasons.InvalidOrderSignature,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import { chaiSetup } from '../../src/utils/chai_setup';
|
||||
import { constants } from '../../src/utils/constants';
|
||||
import { LogDecoder } from '../../src/utils/log_decoder';
|
||||
import { OrderFactory } from '../../src/utils/order_factory';
|
||||
import { RevertReasons } from '../../src/utils/types';
|
||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -107,7 +108,7 @@ describe('MixinSignatureValidator', () => {
|
||||
signedOrder.makerAddress,
|
||||
emptySignature,
|
||||
),
|
||||
constants.EXCHANGE_LENGTH_GREATER_THAN_0_REQUIRED,
|
||||
RevertReasons.LengthGreaterThan0Required,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -121,7 +122,7 @@ describe('MixinSignatureValidator', () => {
|
||||
signedOrder.makerAddress,
|
||||
unsupportedSignatureHex,
|
||||
),
|
||||
constants.EXCHANGE_SIGNATURE_UNSUPPORTED,
|
||||
RevertReasons.SignatureUnsupported,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -134,7 +135,7 @@ describe('MixinSignatureValidator', () => {
|
||||
signedOrder.makerAddress,
|
||||
unsupportedSignatureHex,
|
||||
),
|
||||
constants.EXCHANGE_SIGNATURE_ILLEGAL,
|
||||
RevertReasons.SignatureIllegal,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -161,7 +162,7 @@ describe('MixinSignatureValidator', () => {
|
||||
signedOrder.makerAddress,
|
||||
signatureHex,
|
||||
),
|
||||
constants.EXCHANGE_LENGTH_0_REQUIRED,
|
||||
RevertReasons.Length0Required,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import { ExchangeContract } from '../../src/generated_contract_wrappers/exchange
|
||||
import { ExchangeWrapperContract } from '../../src/generated_contract_wrappers/exchange_wrapper';
|
||||
import { WhitelistContract } from '../../src/generated_contract_wrappers/whitelist';
|
||||
import { artifacts } from '../../src/utils/artifacts';
|
||||
import { expectRevertOrAlwaysFailingTransactionAsync } from '../../src/utils/assertions';
|
||||
import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../../src/utils/assertions';
|
||||
import { chaiSetup } from '../../src/utils/chai_setup';
|
||||
import { constants } from '../../src/utils/constants';
|
||||
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
|
||||
@@ -18,7 +18,7 @@ import { ExchangeWrapper } from '../../src/utils/exchange_wrapper';
|
||||
import { OrderFactory } from '../../src/utils/order_factory';
|
||||
import { orderUtils } from '../../src/utils/order_utils';
|
||||
import { TransactionFactory } from '../../src/utils/transaction_factory';
|
||||
import { ERC20BalancesByOwner, SignedTransaction } from '../../src/utils/types';
|
||||
import { ERC20BalancesByOwner, RevertReasons, SignedTransaction } from '../../src/utils/types';
|
||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -59,6 +59,12 @@ describe('Exchange transactions', () => {
|
||||
after(async () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
beforeEach(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
});
|
||||
afterEach(async () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
before(async () => {
|
||||
const accounts = await web3Wrapper.getAvailableAddressesAsync();
|
||||
const usedAddresses = ([owner, senderAddress, makerAddress, takerAddress, feeRecipientAddress] = accounts);
|
||||
@@ -104,13 +110,6 @@ describe('Exchange transactions', () => {
|
||||
makerTransactionFactory = new TransactionFactory(makerPrivateKey, exchange.address);
|
||||
takerTransactionFactory = new TransactionFactory(takerPrivateKey, exchange.address);
|
||||
});
|
||||
beforeEach(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
});
|
||||
afterEach(async () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
|
||||
describe('executeTransaction', () => {
|
||||
describe('fillOrder', () => {
|
||||
let takerAssetFillAmount: BigNumber;
|
||||
@@ -129,8 +128,9 @@ describe('Exchange transactions', () => {
|
||||
});
|
||||
|
||||
it('should throw if not called by specified sender', async () => {
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.executeTransactionAsync(signedTx, takerAddress),
|
||||
RevertReasons.FailedExecution,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -171,8 +171,9 @@ describe('Exchange transactions', () => {
|
||||
|
||||
it('should throw if the a 0x transaction with the same transactionHash has already been executed', async () => {
|
||||
await exchangeWrapper.executeTransactionAsync(signedTx, senderAddress);
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.executeTransactionAsync(signedTx, senderAddress),
|
||||
RevertReasons.InvalidTxHash,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -190,15 +191,17 @@ describe('Exchange transactions', () => {
|
||||
});
|
||||
|
||||
it('should throw if not called by specified sender', async () => {
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.executeTransactionAsync(signedTx, makerAddress),
|
||||
RevertReasons.FailedExecution,
|
||||
);
|
||||
});
|
||||
|
||||
it('should cancel the order when signed by maker and called by sender', async () => {
|
||||
await exchangeWrapper.executeTransactionAsync(signedTx, senderAddress);
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.fillOrderAsync(signedOrder, senderAddress),
|
||||
RevertReasons.OrderUnfillable,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -241,7 +244,7 @@ describe('Exchange transactions', () => {
|
||||
signedOrder.signature,
|
||||
);
|
||||
const signedFillTx = takerTransactionFactory.newSignedTransaction(fillData);
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapperContract.fillOrder.sendTransactionAsync(
|
||||
orderWithoutExchangeAddress,
|
||||
takerAssetFillAmount,
|
||||
@@ -250,6 +253,7 @@ describe('Exchange transactions', () => {
|
||||
signedFillTx.signature,
|
||||
{ from: takerAddress },
|
||||
),
|
||||
RevertReasons.FailedExecution,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -360,7 +364,7 @@ describe('Exchange transactions', () => {
|
||||
orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
|
||||
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
||||
const salt = generatePseudoRandomSalt();
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
|
||||
orderWithoutExchangeAddress,
|
||||
takerAssetFillAmount,
|
||||
@@ -368,6 +372,7 @@ describe('Exchange transactions', () => {
|
||||
signedOrder.signature,
|
||||
{ from: takerAddress },
|
||||
),
|
||||
RevertReasons.MakerNotWhitelisted,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -381,7 +386,7 @@ describe('Exchange transactions', () => {
|
||||
orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
|
||||
const takerAssetFillAmount = signedOrder.takerAssetAmount;
|
||||
const salt = generatePseudoRandomSalt();
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
|
||||
orderWithoutExchangeAddress,
|
||||
takerAssetFillAmount,
|
||||
@@ -389,6 +394,7 @@ describe('Exchange transactions', () => {
|
||||
signedOrder.signature,
|
||||
{ from: takerAddress },
|
||||
),
|
||||
RevertReasons.TakerNotWhitelisted,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -12,14 +12,14 @@ import { ERC20ProxyContract } from '../../src/generated_contract_wrappers/e_r_c2
|
||||
import { ERC721ProxyContract } from '../../src/generated_contract_wrappers/e_r_c721_proxy';
|
||||
import { ExchangeContract } from '../../src/generated_contract_wrappers/exchange';
|
||||
import { artifacts } from '../../src/utils/artifacts';
|
||||
import { expectRevertOrAlwaysFailingTransactionAsync } from '../../src/utils/assertions';
|
||||
import { expectRevertReasonOrAlwaysFailingTransactionAsync } from '../../src/utils/assertions';
|
||||
import { chaiSetup } from '../../src/utils/chai_setup';
|
||||
import { constants } from '../../src/utils/constants';
|
||||
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
|
||||
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
|
||||
import { ExchangeWrapper } from '../../src/utils/exchange_wrapper';
|
||||
import { OrderFactory } from '../../src/utils/order_factory';
|
||||
import { ERC20BalancesByOwner } from '../../src/utils/types';
|
||||
import { ERC20BalancesByOwner, RevertReasons } from '../../src/utils/types';
|
||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -168,13 +168,14 @@ describe('Exchange wrappers', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw if an signedOrder is expired', async () => {
|
||||
it('should throw if a signedOrder is expired', async () => {
|
||||
const signedOrder = orderFactory.newSignedOrder({
|
||||
expirationTimeSeconds: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
|
||||
});
|
||||
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.fillOrKillOrderAsync(signedOrder, takerAddress),
|
||||
RevertReasons.OrderUnfillable,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -185,8 +186,9 @@ describe('Exchange wrappers', () => {
|
||||
takerAssetFillAmount: signedOrder.takerAssetAmount.div(2),
|
||||
});
|
||||
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.fillOrKillOrderAsync(signedOrder, takerAddress),
|
||||
RevertReasons.CompleteFillFailed,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -497,10 +499,11 @@ describe('Exchange wrappers', () => {
|
||||
|
||||
await exchangeWrapper.fillOrKillOrderAsync(signedOrders[0], takerAddress);
|
||||
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.batchFillOrKillOrdersAsync(signedOrders, takerAddress, {
|
||||
takerAssetFillAmounts,
|
||||
}),
|
||||
RevertReasons.OrderUnfillable,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -690,7 +693,7 @@ describe('Exchange wrappers', () => {
|
||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||
});
|
||||
|
||||
it('should throw when an signedOrder does not use the same takerAssetAddress', async () => {
|
||||
it('should throw when a signedOrder does not use the same takerAssetAddress', async () => {
|
||||
signedOrders = [
|
||||
orderFactory.newSignedOrder(),
|
||||
orderFactory.newSignedOrder({
|
||||
@@ -699,10 +702,13 @@ describe('Exchange wrappers', () => {
|
||||
orderFactory.newSignedOrder(),
|
||||
];
|
||||
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.marketSellOrdersAsync(signedOrders, takerAddress, {
|
||||
takerAssetFillAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1000), 18),
|
||||
}),
|
||||
// We simply use the takerAssetData from the first order for all orders.
|
||||
// If they are not the same, the contract throws when validating the order signature
|
||||
RevertReasons.InvalidOrderSignature,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -905,7 +911,7 @@ describe('Exchange wrappers', () => {
|
||||
expect(newBalances).to.be.deep.equal(erc20Balances);
|
||||
});
|
||||
|
||||
it('should throw when an signedOrder does not use the same makerAssetAddress', async () => {
|
||||
it('should throw when a signedOrder does not use the same makerAssetAddress', async () => {
|
||||
signedOrders = [
|
||||
orderFactory.newSignedOrder(),
|
||||
orderFactory.newSignedOrder({
|
||||
@@ -914,10 +920,11 @@ describe('Exchange wrappers', () => {
|
||||
orderFactory.newSignedOrder(),
|
||||
];
|
||||
|
||||
return expectRevertOrAlwaysFailingTransactionAsync(
|
||||
return expectRevertReasonOrAlwaysFailingTransactionAsync(
|
||||
exchangeWrapper.marketBuyOrdersAsync(signedOrders, takerAddress, {
|
||||
makerAssetFillAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1000), 18),
|
||||
}),
|
||||
RevertReasons.InvalidOrderSignature,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,6 +11,7 @@ import { artifacts } from '../../src/utils/artifacts';
|
||||
import { expectRevertOrOtherErrorAsync } from '../../src/utils/assertions';
|
||||
import { chaiSetup } from '../../src/utils/chai_setup';
|
||||
import { constants } from '../../src/utils/constants';
|
||||
import { RevertReasons } from '../../src/utils/types';
|
||||
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -101,7 +102,7 @@ describe('LibBytes', () => {
|
||||
it('should revert if length is 0', async () => {
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicPopLastByte.callAsync(constants.NULL_BYTES),
|
||||
constants.LIB_BYTES_GREATER_THAN_ZERO_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterThanZeroLengthRequired,
|
||||
);
|
||||
});
|
||||
it('should pop the last byte from the input and return it', async () => {
|
||||
@@ -117,7 +118,7 @@ describe('LibBytes', () => {
|
||||
it('should revert if length is less than 20', async () => {
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicPopLast20Bytes.callAsync(byteArrayShorterThan20Bytes),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualTo20LengthRequired,
|
||||
);
|
||||
});
|
||||
it('should pop the last 20 bytes from the input and return it', async () => {
|
||||
@@ -185,7 +186,7 @@ describe('LibBytes', () => {
|
||||
it('should revert if dest is shorter than source', async () => {
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicDeepCopyBytes.callAsync(byteArrayShorterThan32Bytes, byteArrayLongerThan32Bytes),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualToSourceBytesLengthRequired,
|
||||
);
|
||||
});
|
||||
it('should overwrite dest with source if source and dest have equal length', async () => {
|
||||
@@ -238,7 +239,7 @@ describe('LibBytes', () => {
|
||||
const offset = new BigNumber(0);
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicReadAddress.callAsync(shortByteArray, offset),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualTo20LengthRequired,
|
||||
);
|
||||
});
|
||||
it('should fail if the length between the offset and end of the byte array is too short to hold an address', async () => {
|
||||
@@ -246,7 +247,7 @@ describe('LibBytes', () => {
|
||||
const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength);
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicReadAddress.callAsync(byteArray, badOffset),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualTo20LengthRequired,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -282,7 +283,7 @@ describe('LibBytes', () => {
|
||||
const offset = new BigNumber(0);
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicWriteAddress.callAsync(byteArrayShorterThan20Bytes, offset, testAddress),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualTo20LengthRequired,
|
||||
);
|
||||
});
|
||||
it('should fail if the length between the offset and end of the byte array is too short to hold an address', async () => {
|
||||
@@ -290,7 +291,7 @@ describe('LibBytes', () => {
|
||||
const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength);
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicWriteAddress.callAsync(byteArray, badOffset, testAddress),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualTo20LengthRequired,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -314,14 +315,14 @@ describe('LibBytes', () => {
|
||||
const offset = new BigNumber(0);
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicReadBytes32.callAsync(byteArrayShorterThan32Bytes, offset),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||
);
|
||||
});
|
||||
it('should fail if the length between the offset and end of the byte array is too short to hold a bytes32', async () => {
|
||||
const badOffset = new BigNumber(ethUtil.toBuffer(testBytes32).byteLength);
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicReadBytes32.callAsync(testBytes32, badOffset),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -357,7 +358,7 @@ describe('LibBytes', () => {
|
||||
const offset = new BigNumber(0);
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicWriteBytes32.callAsync(byteArrayShorterThan32Bytes, offset, testBytes32),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||
);
|
||||
});
|
||||
it('should fail if the length between the offset and end of the byte array is too short to hold a bytes32', async () => {
|
||||
@@ -365,7 +366,7 @@ describe('LibBytes', () => {
|
||||
const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength);
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicWriteBytes32.callAsync(byteArray, badOffset, testBytes32),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -393,7 +394,7 @@ describe('LibBytes', () => {
|
||||
const offset = new BigNumber(0);
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicReadUint256.callAsync(byteArrayShorterThan32Bytes, offset),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||
);
|
||||
});
|
||||
it('should fail if the length between the offset and end of the byte array is too short to hold a uint256', async () => {
|
||||
@@ -403,7 +404,7 @@ describe('LibBytes', () => {
|
||||
const badOffset = new BigNumber(testUint256AsBuffer.byteLength);
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicReadUint256.callAsync(byteArray, badOffset),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -443,7 +444,7 @@ describe('LibBytes', () => {
|
||||
const offset = new BigNumber(0);
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicWriteUint256.callAsync(byteArrayShorterThan32Bytes, offset, testUint256),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||
);
|
||||
});
|
||||
it('should fail if the length between the offset and end of the byte array is too short to hold a uint256', async () => {
|
||||
@@ -451,7 +452,7 @@ describe('LibBytes', () => {
|
||||
const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength);
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicWriteUint256.callAsync(byteArray, badOffset, testUint256),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -462,7 +463,7 @@ describe('LibBytes', () => {
|
||||
const byteArrayLessThan4Bytes = '0x010101';
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicReadBytes4.callAsync(byteArrayLessThan4Bytes, new BigNumber(0)),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualTo4LengthRequired,
|
||||
);
|
||||
});
|
||||
it('should return the first 4 bytes of a byte array of arbitrary length', async () => {
|
||||
@@ -517,28 +518,28 @@ describe('LibBytes', () => {
|
||||
const offset = new BigNumber(0);
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicReadBytesWithLength.callAsync(byteArrayShorterThan32Bytes, offset),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||
);
|
||||
});
|
||||
it('should fail if we store a nested byte array length, without a nested byte array', async () => {
|
||||
const offset = new BigNumber(0);
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicReadBytesWithLength.callAsync(testBytes32, offset),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualToNestedBytesLengthRequired,
|
||||
);
|
||||
});
|
||||
it('should fail if the length between the offset and end of the byte array is too short to hold the length of a nested byte array', async () => {
|
||||
const badOffset = new BigNumber(ethUtil.toBuffer(byteArrayShorterThan32Bytes).byteLength);
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicReadBytesWithLength.callAsync(byteArrayShorterThan32Bytes, badOffset),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||
);
|
||||
});
|
||||
it('should fail if the length between the offset and end of the byte array is too short to hold the nested byte array', async () => {
|
||||
const badOffset = new BigNumber(ethUtil.toBuffer(testBytes32).byteLength);
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicReadBytesWithLength.callAsync(testBytes32, badOffset),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualTo32LengthRequired,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -650,7 +651,7 @@ describe('LibBytes', () => {
|
||||
const emptyByteArray = ethUtil.bufferToHex(new Buffer(1));
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, offset, longData),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualToNestedBytesLengthRequired,
|
||||
);
|
||||
});
|
||||
it('should fail if the length between the offset and end of the byte array is too short to hold the length of a nested byte array)', async () => {
|
||||
@@ -658,7 +659,7 @@ describe('LibBytes', () => {
|
||||
const badOffset = new BigNumber(ethUtil.toBuffer(shortTestBytesAsBuffer).byteLength);
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, badOffset, shortData),
|
||||
constants.LIB_BYTES_GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED,
|
||||
RevertReasons.LibBytesGreaterOrEqualToNestedBytesLengthRequired,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ import { artifacts } from '../src/utils/artifacts';
|
||||
import { expectRevertOrOtherErrorAsync } from '../src/utils/assertions';
|
||||
import { chaiSetup } from '../src/utils/chai_setup';
|
||||
import { constants } from '../src/utils/constants';
|
||||
import { RevertReasons } from '../src/utils/types';
|
||||
import { provider, txDefaults, web3Wrapper } from '../src/utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -55,7 +56,7 @@ describe('UnlimitedAllowanceToken', () => {
|
||||
const amountToTransfer = ownerBalance.plus(1);
|
||||
return expectRevertOrOtherErrorAsync(
|
||||
token.transfer.callAsync(spender, amountToTransfer, { from: owner }),
|
||||
constants.ERC20_INSUFFICIENT_BALANCE,
|
||||
RevertReasons.Erc20InsufficientBalance,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -96,7 +97,7 @@ describe('UnlimitedAllowanceToken', () => {
|
||||
token.transferFrom.callAsync(owner, spender, amountToTransfer, {
|
||||
from: spender,
|
||||
}),
|
||||
constants.ERC20_INSUFFICIENT_BALANCE,
|
||||
RevertReasons.Erc20InsufficientBalance,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -112,7 +113,7 @@ describe('UnlimitedAllowanceToken', () => {
|
||||
token.transferFrom.callAsync(owner, spender, amountToTransfer, {
|
||||
from: spender,
|
||||
}),
|
||||
constants.ERC20_INSUFFICIENT_ALLOWANCE,
|
||||
RevertReasons.Erc20InsufficientAllowance,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user