Update coordinator tests
This commit is contained in:
parent
0e7387550c
commit
9b922f746b
@ -48,7 +48,7 @@ contract MixinSignatureValidator is
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pop last byte off of signature byte array.
|
// Pop last byte off of signature byte array.
|
||||||
uint8 signatureTypeRaw = uint8(signature.popLastByte());
|
uint8 signatureTypeRaw = uint8(signature[signature.length - 1]);
|
||||||
|
|
||||||
// Ensure signature is supported
|
// Ensure signature is supported
|
||||||
if (signatureTypeRaw >= uint8(SignatureType.NSignatureTypes)) {
|
if (signatureTypeRaw >= uint8(SignatureType.NSignatureTypes)) {
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
"compile:truffle": "truffle compile"
|
"compile:truffle": "truffle compile"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"abis": "./generated-artifacts/@(Coordinator|CoordinatorRegistry).json",
|
"abis": "./generated-artifacts/@(Coordinator|CoordinatorRegistry|ICoordinatorApprovalVerifier|ICoordinatorCore|ICoordinatorRegistryCore|ICoordinatorSignatureValidator|LibConstants|LibCoordinatorApproval|LibCoordinatorRichErrors|LibEIP712CoordinatorDomain|MixinCoordinatorApprovalVerifier|MixinCoordinatorCore|MixinCoordinatorRegistryCore|MixinSignatureValidator).json",
|
||||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -7,7 +7,31 @@ import { ContractArtifact } from 'ethereum-types';
|
|||||||
|
|
||||||
import * as Coordinator from '../generated-artifacts/Coordinator.json';
|
import * as Coordinator from '../generated-artifacts/Coordinator.json';
|
||||||
import * as CoordinatorRegistry from '../generated-artifacts/CoordinatorRegistry.json';
|
import * as CoordinatorRegistry from '../generated-artifacts/CoordinatorRegistry.json';
|
||||||
|
import * as ICoordinatorApprovalVerifier from '../generated-artifacts/ICoordinatorApprovalVerifier.json';
|
||||||
|
import * as ICoordinatorCore from '../generated-artifacts/ICoordinatorCore.json';
|
||||||
|
import * as ICoordinatorRegistryCore from '../generated-artifacts/ICoordinatorRegistryCore.json';
|
||||||
|
import * as ICoordinatorSignatureValidator from '../generated-artifacts/ICoordinatorSignatureValidator.json';
|
||||||
|
import * as LibConstants from '../generated-artifacts/LibConstants.json';
|
||||||
|
import * as LibCoordinatorApproval from '../generated-artifacts/LibCoordinatorApproval.json';
|
||||||
|
import * as LibCoordinatorRichErrors from '../generated-artifacts/LibCoordinatorRichErrors.json';
|
||||||
|
import * as LibEIP712CoordinatorDomain from '../generated-artifacts/LibEIP712CoordinatorDomain.json';
|
||||||
|
import * as MixinCoordinatorApprovalVerifier from '../generated-artifacts/MixinCoordinatorApprovalVerifier.json';
|
||||||
|
import * as MixinCoordinatorCore from '../generated-artifacts/MixinCoordinatorCore.json';
|
||||||
|
import * as MixinCoordinatorRegistryCore from '../generated-artifacts/MixinCoordinatorRegistryCore.json';
|
||||||
|
import * as MixinSignatureValidator from '../generated-artifacts/MixinSignatureValidator.json';
|
||||||
export const artifacts = {
|
export const artifacts = {
|
||||||
Coordinator: Coordinator as ContractArtifact,
|
Coordinator: Coordinator as ContractArtifact,
|
||||||
|
MixinCoordinatorApprovalVerifier: MixinCoordinatorApprovalVerifier as ContractArtifact,
|
||||||
|
MixinCoordinatorCore: MixinCoordinatorCore as ContractArtifact,
|
||||||
|
MixinSignatureValidator: MixinSignatureValidator as ContractArtifact,
|
||||||
|
ICoordinatorApprovalVerifier: ICoordinatorApprovalVerifier as ContractArtifact,
|
||||||
|
ICoordinatorCore: ICoordinatorCore as ContractArtifact,
|
||||||
|
ICoordinatorSignatureValidator: ICoordinatorSignatureValidator as ContractArtifact,
|
||||||
|
LibConstants: LibConstants as ContractArtifact,
|
||||||
|
LibCoordinatorApproval: LibCoordinatorApproval as ContractArtifact,
|
||||||
|
LibCoordinatorRichErrors: LibCoordinatorRichErrors as ContractArtifact,
|
||||||
|
LibEIP712CoordinatorDomain: LibEIP712CoordinatorDomain as ContractArtifact,
|
||||||
CoordinatorRegistry: CoordinatorRegistry as ContractArtifact,
|
CoordinatorRegistry: CoordinatorRegistry as ContractArtifact,
|
||||||
|
MixinCoordinatorRegistryCore: MixinCoordinatorRegistryCore as ContractArtifact,
|
||||||
|
ICoordinatorRegistryCore: ICoordinatorRegistryCore as ContractArtifact,
|
||||||
};
|
};
|
||||||
|
@ -5,3 +5,15 @@
|
|||||||
*/
|
*/
|
||||||
export * from '../generated-wrappers/coordinator';
|
export * from '../generated-wrappers/coordinator';
|
||||||
export * from '../generated-wrappers/coordinator_registry';
|
export * from '../generated-wrappers/coordinator_registry';
|
||||||
|
export * from '../generated-wrappers/i_coordinator_approval_verifier';
|
||||||
|
export * from '../generated-wrappers/i_coordinator_core';
|
||||||
|
export * from '../generated-wrappers/i_coordinator_registry_core';
|
||||||
|
export * from '../generated-wrappers/i_coordinator_signature_validator';
|
||||||
|
export * from '../generated-wrappers/lib_constants';
|
||||||
|
export * from '../generated-wrappers/lib_coordinator_approval';
|
||||||
|
export * from '../generated-wrappers/lib_coordinator_rich_errors';
|
||||||
|
export * from '../generated-wrappers/lib_e_i_p712_coordinator_domain';
|
||||||
|
export * from '../generated-wrappers/mixin_coordinator_approval_verifier';
|
||||||
|
export * from '../generated-wrappers/mixin_coordinator_core';
|
||||||
|
export * from '../generated-wrappers/mixin_coordinator_registry_core';
|
||||||
|
export * from '../generated-wrappers/mixin_signature_validator';
|
||||||
|
@ -7,35 +7,28 @@ import {
|
|||||||
ExchangeCancelUpToEventArgs,
|
ExchangeCancelUpToEventArgs,
|
||||||
ExchangeContract,
|
ExchangeContract,
|
||||||
exchangeDataEncoder,
|
exchangeDataEncoder,
|
||||||
|
ExchangeEvents,
|
||||||
ExchangeFillEventArgs,
|
ExchangeFillEventArgs,
|
||||||
ExchangeFunctionName,
|
ExchangeFunctionName,
|
||||||
} from '@0x/contracts-exchange';
|
} from '@0x/contracts-exchange';
|
||||||
import {
|
import {
|
||||||
chaiSetup,
|
blockchainTests,
|
||||||
constants,
|
constants,
|
||||||
expectTransactionFailedAsync,
|
expect,
|
||||||
|
filterLogsToArguments,
|
||||||
getLatestBlockTimestampAsync,
|
getLatestBlockTimestampAsync,
|
||||||
OrderFactory,
|
OrderFactory,
|
||||||
provider,
|
|
||||||
TransactionFactory,
|
TransactionFactory,
|
||||||
txDefaults,
|
|
||||||
web3Wrapper,
|
|
||||||
} from '@0x/contracts-test-utils';
|
} from '@0x/contracts-test-utils';
|
||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
import { assetDataUtils, CoordinatorRevertErrors, orderHashUtils, transactionHashUtils } from '@0x/order-utils';
|
||||||
import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
|
import { SignedOrder } from '@0x/types';
|
||||||
import { RevertReason } from '@0x/types';
|
import { BigNumber } from '@0x/utils';
|
||||||
import { BigNumber, providerUtils } from '@0x/utils';
|
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||||
import * as chai from 'chai';
|
|
||||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
|
||||||
|
|
||||||
import { ApprovalFactory, artifacts, CoordinatorContract } from '../src';
|
import { ApprovalFactory, artifacts, CoordinatorContract } from '../src';
|
||||||
|
|
||||||
chaiSetup.configure();
|
|
||||||
const expect = chai.expect;
|
|
||||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
|
||||||
web3Wrapper.abiDecoder.addABI(exchangeArtifacts.Exchange.compilerOutput.abi);
|
|
||||||
// tslint:disable:no-unnecessary-type-assertion
|
// tslint:disable:no-unnecessary-type-assertion
|
||||||
describe('Coordinator tests', () => {
|
blockchainTests.resets('Coordinator tests', env => {
|
||||||
let chainId: number;
|
let chainId: number;
|
||||||
let makerAddress: string;
|
let makerAddress: string;
|
||||||
let owner: string;
|
let owner: string;
|
||||||
@ -55,18 +48,17 @@ describe('Coordinator tests', () => {
|
|||||||
let makerTransactionFactory: TransactionFactory;
|
let makerTransactionFactory: TransactionFactory;
|
||||||
let approvalFactory: ApprovalFactory;
|
let approvalFactory: ApprovalFactory;
|
||||||
|
|
||||||
before(async () => {
|
// const GAS_PRICE = new BigNumber(env.txDefaults.gasPrice || constants.DEFAULT_GAS_PRICE);
|
||||||
await blockchainLifecycle.startAsync();
|
// const PROTOCOL_FEE_MULTIPLIER = new BigNumber(150);
|
||||||
});
|
// const PROTOCOL_FEE = GAS_PRICE.times(PROTOCOL_FEE_MULTIPLIER);
|
||||||
after(async () => {
|
const PROTOCOL_FEE = new BigNumber(0);
|
||||||
await blockchainLifecycle.revertAsync();
|
|
||||||
});
|
|
||||||
before(async () => {
|
|
||||||
chainId = await providerUtils.getChainIdAsync(provider);
|
|
||||||
const accounts = await web3Wrapper.getAvailableAddressesAsync();
|
|
||||||
const usedAddresses = ([owner, makerAddress, takerAddress, feeRecipientAddress] = accounts.slice(0, 4));
|
|
||||||
|
|
||||||
erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner);
|
before(async () => {
|
||||||
|
chainId = await env.getChainIdAsync();
|
||||||
|
const accounts = await env.getAccountAddressesAsync();
|
||||||
|
const usedAddresses = ([owner, makerAddress, takerAddress, feeRecipientAddress] = accounts);
|
||||||
|
|
||||||
|
erc20Wrapper = new ERC20Wrapper(env.provider, usedAddresses, owner);
|
||||||
erc20Proxy = await erc20Wrapper.deployProxyAsync();
|
erc20Proxy = await erc20Wrapper.deployProxyAsync();
|
||||||
const numDummyErc20ToDeploy = 3;
|
const numDummyErc20ToDeploy = 3;
|
||||||
[erc20TokenA, erc20TokenB, makerFeeToken] = await erc20Wrapper.deployDummyTokensAsync(
|
[erc20TokenA, erc20TokenB, makerFeeToken] = await erc20Wrapper.deployDummyTokensAsync(
|
||||||
@ -77,26 +69,28 @@ describe('Coordinator tests', () => {
|
|||||||
|
|
||||||
exchange = await ExchangeContract.deployFrom0xArtifactAsync(
|
exchange = await ExchangeContract.deployFrom0xArtifactAsync(
|
||||||
exchangeArtifacts.Exchange,
|
exchangeArtifacts.Exchange,
|
||||||
provider,
|
env.provider,
|
||||||
txDefaults,
|
env.txDefaults,
|
||||||
|
{},
|
||||||
new BigNumber(chainId),
|
new BigNumber(chainId),
|
||||||
);
|
);
|
||||||
|
|
||||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
await erc20Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||||
await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, { from: owner }),
|
exchange.address,
|
||||||
|
{ from: owner },
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
|
await exchange.registerAssetProxy.awaitTransactionSuccessAsync(
|
||||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
erc20Proxy.address,
|
||||||
await exchange.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, { from: owner }),
|
{ from: owner },
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
|
|
||||||
coordinatorContract = await CoordinatorContract.deployFrom0xArtifactAsync(
|
coordinatorContract = await CoordinatorContract.deployFrom0xArtifactAsync(
|
||||||
artifacts.Coordinator,
|
artifacts.Coordinator,
|
||||||
provider,
|
env.provider,
|
||||||
txDefaults,
|
env.txDefaults,
|
||||||
artifacts,
|
{ ...exchangeArtifacts, ...artifacts },
|
||||||
exchange.address,
|
exchange.address,
|
||||||
new BigNumber(chainId),
|
new BigNumber(chainId),
|
||||||
);
|
);
|
||||||
@ -106,6 +100,7 @@ describe('Coordinator tests', () => {
|
|||||||
...constants.STATIC_ORDER_PARAMS,
|
...constants.STATIC_ORDER_PARAMS,
|
||||||
senderAddress: coordinatorContract.address,
|
senderAddress: coordinatorContract.address,
|
||||||
makerAddress,
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
feeRecipientAddress,
|
feeRecipientAddress,
|
||||||
makerAssetData: assetDataUtils.encodeERC20AssetData(erc20TokenA.address),
|
makerAssetData: assetDataUtils.encodeERC20AssetData(erc20TokenA.address),
|
||||||
takerAssetData: assetDataUtils.encodeERC20AssetData(erc20TokenB.address),
|
takerAssetData: assetDataUtils.encodeERC20AssetData(erc20TokenB.address),
|
||||||
@ -122,12 +117,48 @@ describe('Coordinator tests', () => {
|
|||||||
takerTransactionFactory = new TransactionFactory(takerPrivateKey, exchange.address, chainId);
|
takerTransactionFactory = new TransactionFactory(takerPrivateKey, exchange.address, chainId);
|
||||||
approvalFactory = new ApprovalFactory(feeRecipientPrivateKey, coordinatorContract.address);
|
approvalFactory = new ApprovalFactory(feeRecipientPrivateKey, coordinatorContract.address);
|
||||||
});
|
});
|
||||||
beforeEach(async () => {
|
|
||||||
await blockchainLifecycle.startAsync();
|
function verifyEvents<TEventArgs>(
|
||||||
});
|
txReceipt: TransactionReceiptWithDecodedLogs,
|
||||||
afterEach(async () => {
|
expectedEvents: TEventArgs[],
|
||||||
await blockchainLifecycle.revertAsync();
|
eventName: string,
|
||||||
|
): void {
|
||||||
|
const logs = filterLogsToArguments<TEventArgs>(txReceipt.logs, eventName);
|
||||||
|
expect(logs.length).to.eq(expectedEvents.length);
|
||||||
|
logs.forEach((log, index) => {
|
||||||
|
expect(log).to.deep.equal(expectedEvents[index]);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function expectedFillEvent(order: SignedOrder): ExchangeFillEventArgs {
|
||||||
|
return {
|
||||||
|
makerAddress: order.makerAddress,
|
||||||
|
feeRecipientAddress: order.feeRecipientAddress,
|
||||||
|
makerAssetData: order.makerAssetData,
|
||||||
|
takerAssetData: order.takerAssetData,
|
||||||
|
makerFeeAssetData: order.makerFeeAssetData,
|
||||||
|
takerFeeAssetData: order.takerFeeAssetData,
|
||||||
|
takerAddress: order.takerAddress,
|
||||||
|
senderAddress: order.senderAddress,
|
||||||
|
makerAssetFilledAmount: order.makerAssetAmount,
|
||||||
|
takerAssetFilledAmount: order.takerAssetAmount,
|
||||||
|
makerFeePaid: order.makerFee,
|
||||||
|
takerFeePaid: order.takerFee,
|
||||||
|
protocolFeePaid: PROTOCOL_FEE,
|
||||||
|
orderHash: orderHashUtils.getOrderHashHex(order),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function expectedCancelEvent(order: SignedOrder): ExchangeCancelEventArgs {
|
||||||
|
return {
|
||||||
|
makerAddress: order.makerAddress,
|
||||||
|
feeRecipientAddress: order.feeRecipientAddress,
|
||||||
|
makerAssetData: order.makerAssetData,
|
||||||
|
takerAssetData: order.takerAssetData,
|
||||||
|
senderAddress: order.senderAddress,
|
||||||
|
orderHash: orderHashUtils.getOrderHashHex(order),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
describe('single order fills', () => {
|
describe('single order fills', () => {
|
||||||
for (const fnName of exchangeConstants.SINGLE_FILL_FN_NAMES) {
|
for (const fnName of exchangeConstants.SINGLE_FILL_FN_NAMES) {
|
||||||
@ -142,72 +173,38 @@ describe('Coordinator tests', () => {
|
|||||||
takerAddress,
|
takerAddress,
|
||||||
approvalExpirationTimeSeconds,
|
approvalExpirationTimeSeconds,
|
||||||
);
|
);
|
||||||
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
|
const transactionReceipt = await coordinatorContract.executeTransaction.awaitTransactionSuccessAsync(
|
||||||
await coordinatorContract.executeTransaction.sendTransactionAsync(
|
|
||||||
transaction,
|
transaction,
|
||||||
takerAddress,
|
takerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[approvalExpirationTimeSeconds],
|
[approvalExpirationTimeSeconds],
|
||||||
[approval.signature],
|
[approval.signature],
|
||||||
{ from: takerAddress },
|
{ from: takerAddress },
|
||||||
),
|
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
const fillLogs = transactionReceipt.logs.filter(
|
|
||||||
log => (log as LogWithDecodedArgs<ExchangeFillEventArgs>).event === 'Fill',
|
verifyEvents(transactionReceipt, [expectedFillEvent(orders[0])], ExchangeEvents.Fill);
|
||||||
);
|
|
||||||
expect(fillLogs.length).to.eq(1);
|
|
||||||
const fillLogArgs = (fillLogs[0] as LogWithDecodedArgs<ExchangeFillEventArgs>).args;
|
|
||||||
expect(fillLogArgs.makerAddress).to.eq(makerAddress);
|
|
||||||
expect(fillLogArgs.takerAddress).to.eq(takerAddress);
|
|
||||||
expect(fillLogArgs.senderAddress).to.eq(coordinatorContract.address);
|
|
||||||
expect(fillLogArgs.feeRecipientAddress).to.eq(feeRecipientAddress);
|
|
||||||
expect(fillLogArgs.makerAssetData).to.eq(orders[0].makerAssetData);
|
|
||||||
expect(fillLogArgs.takerAssetData).to.eq(orders[0].takerAssetData);
|
|
||||||
expect(fillLogArgs.makerAssetFilledAmount).to.bignumber.eq(orders[0].makerAssetAmount);
|
|
||||||
expect(fillLogArgs.takerAssetFilledAmount).to.bignumber.eq(orders[0].takerAssetAmount);
|
|
||||||
expect(fillLogArgs.makerFeePaid).to.bignumber.eq(orders[0].makerFee);
|
|
||||||
expect(fillLogArgs.takerFeePaid).to.bignumber.eq(orders[0].takerFee);
|
|
||||||
expect(fillLogArgs.orderHash).to.eq(orderHashUtils.getOrderHashHex(orders[0]));
|
|
||||||
});
|
});
|
||||||
it(`${fnName} should fill the order if called by approver`, async () => {
|
it(`${fnName} should fill the order if called by approver`, async () => {
|
||||||
const orders = [await orderFactory.newSignedOrderAsync()];
|
const orders = [await orderFactory.newSignedOrderAsync()];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
|
||||||
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
|
const transactionReceipt = await coordinatorContract.executeTransaction.awaitTransactionSuccessAsync(
|
||||||
await coordinatorContract.executeTransaction.sendTransactionAsync(
|
|
||||||
transaction,
|
transaction,
|
||||||
feeRecipientAddress,
|
feeRecipientAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[],
|
[],
|
||||||
[],
|
[],
|
||||||
{ from: feeRecipientAddress },
|
{ from: feeRecipientAddress },
|
||||||
),
|
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
const fillLogs = transactionReceipt.logs.filter(
|
verifyEvents(transactionReceipt, [expectedFillEvent(orders[0])], ExchangeEvents.Fill);
|
||||||
log => (log as LogWithDecodedArgs<ExchangeFillEventArgs>).event === 'Fill',
|
|
||||||
);
|
|
||||||
expect(fillLogs.length).to.eq(1);
|
|
||||||
const fillLogArgs = (fillLogs[0] as LogWithDecodedArgs<ExchangeFillEventArgs>).args;
|
|
||||||
expect(fillLogArgs.makerAddress).to.eq(makerAddress);
|
|
||||||
expect(fillLogArgs.takerAddress).to.eq(takerAddress);
|
|
||||||
expect(fillLogArgs.senderAddress).to.eq(coordinatorContract.address);
|
|
||||||
expect(fillLogArgs.feeRecipientAddress).to.eq(feeRecipientAddress);
|
|
||||||
expect(fillLogArgs.makerAssetData).to.eq(orders[0].makerAssetData);
|
|
||||||
expect(fillLogArgs.takerAssetData).to.eq(orders[0].takerAssetData);
|
|
||||||
expect(fillLogArgs.makerAssetFilledAmount).to.bignumber.eq(orders[0].makerAssetAmount);
|
|
||||||
expect(fillLogArgs.takerAssetFilledAmount).to.bignumber.eq(orders[0].takerAssetAmount);
|
|
||||||
expect(fillLogArgs.makerFeePaid).to.bignumber.eq(orders[0].makerFee);
|
|
||||||
expect(fillLogArgs.takerFeePaid).to.bignumber.eq(orders[0].takerFee);
|
|
||||||
expect(fillLogArgs.orderHash).to.eq(orderHashUtils.getOrderHashHex(orders[0]));
|
|
||||||
});
|
});
|
||||||
it(`${fnName} should revert with no approval signature`, async () => {
|
it(`${fnName} should revert with no approval signature`, async () => {
|
||||||
const orders = [await orderFactory.newSignedOrderAsync()];
|
const orders = [await orderFactory.newSignedOrderAsync()];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
|
||||||
await expectTransactionFailedAsync(
|
const tx = coordinatorContract.executeTransaction.awaitTransactionSuccessAsync(
|
||||||
coordinatorContract.executeTransaction.sendTransactionAsync(
|
|
||||||
transaction,
|
transaction,
|
||||||
takerAddress,
|
takerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
@ -217,8 +214,11 @@ describe('Coordinator tests', () => {
|
|||||||
from: takerAddress,
|
from: takerAddress,
|
||||||
gas: constants.MAX_EXECUTE_TRANSACTION_GAS,
|
gas: constants.MAX_EXECUTE_TRANSACTION_GAS,
|
||||||
},
|
},
|
||||||
),
|
);
|
||||||
RevertReason.InvalidApprovalSignature,
|
|
||||||
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
|
expect(tx).to.revertWith(
|
||||||
|
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, feeRecipientAddress),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it(`${fnName} should revert with an invalid approval signature`, async () => {
|
it(`${fnName} should revert with an invalid approval signature`, async () => {
|
||||||
@ -233,16 +233,18 @@ describe('Coordinator tests', () => {
|
|||||||
approvalExpirationTimeSeconds,
|
approvalExpirationTimeSeconds,
|
||||||
);
|
);
|
||||||
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
|
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
|
||||||
await expectTransactionFailedAsync(
|
const tx = coordinatorContract.executeTransaction.awaitTransactionSuccessAsync(
|
||||||
coordinatorContract.executeTransaction.sendTransactionAsync(
|
|
||||||
transaction,
|
transaction,
|
||||||
takerAddress,
|
takerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[approvalExpirationTimeSeconds],
|
[approvalExpirationTimeSeconds],
|
||||||
[signature],
|
[signature],
|
||||||
{ from: takerAddress },
|
{ from: takerAddress },
|
||||||
),
|
);
|
||||||
RevertReason.InvalidApprovalSignature,
|
|
||||||
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
|
expect(tx).to.revertWith(
|
||||||
|
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, feeRecipientAddress),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it(`${fnName} should revert with an expired approval`, async () => {
|
it(`${fnName} should revert with an expired approval`, async () => {
|
||||||
@ -256,16 +258,19 @@ describe('Coordinator tests', () => {
|
|||||||
takerAddress,
|
takerAddress,
|
||||||
approvalExpirationTimeSeconds,
|
approvalExpirationTimeSeconds,
|
||||||
);
|
);
|
||||||
await expectTransactionFailedAsync(
|
|
||||||
coordinatorContract.executeTransaction.sendTransactionAsync(
|
const tx = coordinatorContract.executeTransaction.awaitTransactionSuccessAsync(
|
||||||
transaction,
|
transaction,
|
||||||
takerAddress,
|
takerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[approvalExpirationTimeSeconds],
|
[approvalExpirationTimeSeconds],
|
||||||
[approval.signature],
|
[approval.signature],
|
||||||
{ from: takerAddress },
|
{ from: takerAddress },
|
||||||
),
|
);
|
||||||
RevertReason.ApprovalExpired,
|
|
||||||
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
|
expect(tx).to.revertWith(
|
||||||
|
new CoordinatorRevertErrors.ApprovalExpiredError(transactionHash, approvalExpirationTimeSeconds),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it(`${fnName} should revert if not called by tx signer or approver`, async () => {
|
it(`${fnName} should revert if not called by tx signer or approver`, async () => {
|
||||||
@ -279,17 +284,16 @@ describe('Coordinator tests', () => {
|
|||||||
takerAddress,
|
takerAddress,
|
||||||
approvalExpirationTimeSeconds,
|
approvalExpirationTimeSeconds,
|
||||||
);
|
);
|
||||||
await expectTransactionFailedAsync(
|
|
||||||
coordinatorContract.executeTransaction.sendTransactionAsync(
|
const tx = coordinatorContract.executeTransaction.awaitTransactionSuccessAsync(
|
||||||
transaction,
|
transaction,
|
||||||
takerAddress,
|
takerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[approvalExpirationTimeSeconds],
|
[approvalExpirationTimeSeconds],
|
||||||
[approval.signature],
|
[approval.signature],
|
||||||
{ from: owner },
|
{ from: owner },
|
||||||
),
|
|
||||||
RevertReason.InvalidOrigin,
|
|
||||||
);
|
);
|
||||||
|
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(takerAddress));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -306,69 +310,35 @@ describe('Coordinator tests', () => {
|
|||||||
takerAddress,
|
takerAddress,
|
||||||
approvalExpirationTimeSeconds,
|
approvalExpirationTimeSeconds,
|
||||||
);
|
);
|
||||||
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
|
const transactionReceipt = await coordinatorContract.executeTransaction.awaitTransactionSuccessAsync(
|
||||||
await coordinatorContract.executeTransaction.sendTransactionAsync(
|
|
||||||
transaction,
|
transaction,
|
||||||
takerAddress,
|
takerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[approvalExpirationTimeSeconds],
|
[approvalExpirationTimeSeconds],
|
||||||
[approval.signature],
|
[approval.signature],
|
||||||
{ from: takerAddress, gas: constants.MAX_EXECUTE_TRANSACTION_GAS },
|
{ from: takerAddress, gas: constants.MAX_EXECUTE_TRANSACTION_GAS },
|
||||||
),
|
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
const fillLogs = transactionReceipt.logs.filter(
|
|
||||||
log => (log as LogWithDecodedArgs<ExchangeFillEventArgs>).event === 'Fill',
|
const expectedEvents = orders.map(order => expectedFillEvent(order));
|
||||||
);
|
verifyEvents(transactionReceipt, expectedEvents, ExchangeEvents.Fill);
|
||||||
expect(fillLogs.length).to.eq(orders.length);
|
|
||||||
orders.forEach((order, index) => {
|
|
||||||
const fillLogArgs = (fillLogs[index] as LogWithDecodedArgs<ExchangeFillEventArgs>).args;
|
|
||||||
expect(fillLogArgs.makerAddress).to.eq(makerAddress);
|
|
||||||
expect(fillLogArgs.takerAddress).to.eq(takerAddress);
|
|
||||||
expect(fillLogArgs.senderAddress).to.eq(coordinatorContract.address);
|
|
||||||
expect(fillLogArgs.feeRecipientAddress).to.eq(feeRecipientAddress);
|
|
||||||
expect(fillLogArgs.makerAssetData).to.eq(order.makerAssetData);
|
|
||||||
expect(fillLogArgs.takerAssetData).to.eq(order.takerAssetData);
|
|
||||||
expect(fillLogArgs.makerAssetFilledAmount).to.bignumber.eq(order.makerAssetAmount);
|
|
||||||
expect(fillLogArgs.takerAssetFilledAmount).to.bignumber.eq(order.takerAssetAmount);
|
|
||||||
expect(fillLogArgs.makerFeePaid).to.bignumber.eq(order.makerFee);
|
|
||||||
expect(fillLogArgs.takerFeePaid).to.bignumber.eq(order.takerFee);
|
|
||||||
expect(fillLogArgs.orderHash).to.eq(orderHashUtils.getOrderHashHex(order));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
it(`${fnName} should fill the orders if called by approver`, async () => {
|
it(`${fnName} should fill the orders if called by approver`, async () => {
|
||||||
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
|
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
|
||||||
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
|
const transactionReceipt = await coordinatorContract.executeTransaction.awaitTransactionSuccessAsync(
|
||||||
await coordinatorContract.executeTransaction.sendTransactionAsync(
|
|
||||||
transaction,
|
transaction,
|
||||||
feeRecipientAddress,
|
feeRecipientAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[],
|
[],
|
||||||
[],
|
[],
|
||||||
{ from: feeRecipientAddress, gas: constants.MAX_EXECUTE_TRANSACTION_GAS },
|
{ from: feeRecipientAddress, gas: constants.MAX_EXECUTE_TRANSACTION_GAS },
|
||||||
),
|
|
||||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||||
);
|
);
|
||||||
const fillLogs = transactionReceipt.logs.filter(
|
|
||||||
log => (log as LogWithDecodedArgs<ExchangeFillEventArgs>).event === 'Fill',
|
const expectedEvents = orders.map(order => expectedFillEvent(order));
|
||||||
);
|
verifyEvents(transactionReceipt, expectedEvents, ExchangeEvents.Fill);
|
||||||
expect(fillLogs.length).to.eq(orders.length);
|
|
||||||
orders.forEach((order, index) => {
|
|
||||||
const fillLogArgs = (fillLogs[index] as LogWithDecodedArgs<ExchangeFillEventArgs>).args;
|
|
||||||
expect(fillLogArgs.makerAddress).to.eq(makerAddress);
|
|
||||||
expect(fillLogArgs.takerAddress).to.eq(takerAddress);
|
|
||||||
expect(fillLogArgs.senderAddress).to.eq(coordinatorContract.address);
|
|
||||||
expect(fillLogArgs.feeRecipientAddress).to.eq(feeRecipientAddress);
|
|
||||||
expect(fillLogArgs.makerAssetData).to.eq(order.makerAssetData);
|
|
||||||
expect(fillLogArgs.takerAssetData).to.eq(order.takerAssetData);
|
|
||||||
expect(fillLogArgs.makerAssetFilledAmount).to.bignumber.eq(order.makerAssetAmount);
|
|
||||||
expect(fillLogArgs.takerAssetFilledAmount).to.bignumber.eq(order.takerAssetAmount);
|
|
||||||
expect(fillLogArgs.makerFeePaid).to.bignumber.eq(order.makerFee);
|
|
||||||
expect(fillLogArgs.takerFeePaid).to.bignumber.eq(order.takerFee);
|
|
||||||
expect(fillLogArgs.orderHash).to.eq(orderHashUtils.getOrderHashHex(order));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
it(`${fnName} should revert with an invalid approval signature`, async () => {
|
it(`${fnName} should revert with an invalid approval signature`, async () => {
|
||||||
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
|
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
|
||||||
@ -382,16 +352,18 @@ describe('Coordinator tests', () => {
|
|||||||
approvalExpirationTimeSeconds,
|
approvalExpirationTimeSeconds,
|
||||||
);
|
);
|
||||||
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
|
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
|
||||||
await expectTransactionFailedAsync(
|
const tx = coordinatorContract.executeTransaction.awaitTransactionSuccessAsync(
|
||||||
coordinatorContract.executeTransaction.sendTransactionAsync(
|
|
||||||
transaction,
|
transaction,
|
||||||
takerAddress,
|
takerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[approvalExpirationTimeSeconds],
|
[approvalExpirationTimeSeconds],
|
||||||
[signature],
|
[signature],
|
||||||
{ from: takerAddress },
|
{ from: takerAddress },
|
||||||
),
|
);
|
||||||
RevertReason.InvalidApprovalSignature,
|
|
||||||
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
|
expect(tx).to.revertWith(
|
||||||
|
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, feeRecipientAddress),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it(`${fnName} should revert with an expired approval`, async () => {
|
it(`${fnName} should revert with an expired approval`, async () => {
|
||||||
@ -405,16 +377,18 @@ describe('Coordinator tests', () => {
|
|||||||
takerAddress,
|
takerAddress,
|
||||||
approvalExpirationTimeSeconds,
|
approvalExpirationTimeSeconds,
|
||||||
);
|
);
|
||||||
await expectTransactionFailedAsync(
|
const tx = coordinatorContract.executeTransaction.awaitTransactionSuccessAsync(
|
||||||
coordinatorContract.executeTransaction.sendTransactionAsync(
|
|
||||||
transaction,
|
transaction,
|
||||||
takerAddress,
|
takerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[approvalExpirationTimeSeconds],
|
[approvalExpirationTimeSeconds],
|
||||||
[approval.signature],
|
[approval.signature],
|
||||||
{ from: takerAddress },
|
{ from: takerAddress },
|
||||||
),
|
);
|
||||||
RevertReason.ApprovalExpired,
|
|
||||||
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
|
expect(tx).to.revertWith(
|
||||||
|
new CoordinatorRevertErrors.ApprovalExpiredError(transactionHash, approvalExpirationTimeSeconds),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it(`${fnName} should revert if not called by tx signer or approver`, async () => {
|
it(`${fnName} should revert if not called by tx signer or approver`, async () => {
|
||||||
@ -428,17 +402,16 @@ describe('Coordinator tests', () => {
|
|||||||
takerAddress,
|
takerAddress,
|
||||||
approvalExpirationTimeSeconds,
|
approvalExpirationTimeSeconds,
|
||||||
);
|
);
|
||||||
await expectTransactionFailedAsync(
|
|
||||||
coordinatorContract.executeTransaction.sendTransactionAsync(
|
const tx = coordinatorContract.executeTransaction.awaitTransactionSuccessAsync(
|
||||||
transaction,
|
transaction,
|
||||||
takerAddress,
|
takerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[approvalExpirationTimeSeconds],
|
[approvalExpirationTimeSeconds],
|
||||||
[approval.signature],
|
[approval.signature],
|
||||||
{ from: owner },
|
{ from: owner },
|
||||||
),
|
|
||||||
RevertReason.InvalidOrigin,
|
|
||||||
);
|
);
|
||||||
|
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(takerAddress));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -447,8 +420,7 @@ describe('Coordinator tests', () => {
|
|||||||
const orders = [await orderFactory.newSignedOrderAsync()];
|
const orders = [await orderFactory.newSignedOrderAsync()];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrder, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrder, orders);
|
||||||
const transaction = await makerTransactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await makerTransactionFactory.newSignedTransactionAsync({ data });
|
||||||
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
|
const transactionReceipt = await coordinatorContract.executeTransaction.awaitTransactionSuccessAsync(
|
||||||
await coordinatorContract.executeTransaction.sendTransactionAsync(
|
|
||||||
transaction,
|
transaction,
|
||||||
makerAddress,
|
makerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
@ -457,26 +429,14 @@ describe('Coordinator tests', () => {
|
|||||||
{
|
{
|
||||||
from: makerAddress,
|
from: makerAddress,
|
||||||
},
|
},
|
||||||
),
|
|
||||||
);
|
);
|
||||||
const cancelLogs = transactionReceipt.logs.filter(
|
verifyEvents(transactionReceipt, [expectedCancelEvent(orders[0])], ExchangeEvents.Cancel);
|
||||||
log => (log as LogWithDecodedArgs<ExchangeCancelEventArgs>).event === 'Cancel',
|
|
||||||
);
|
|
||||||
expect(cancelLogs.length).to.eq(1);
|
|
||||||
const cancelLogArgs = (cancelLogs[0] as LogWithDecodedArgs<ExchangeCancelEventArgs>).args;
|
|
||||||
expect(cancelLogArgs.makerAddress).to.eq(makerAddress);
|
|
||||||
expect(cancelLogArgs.senderAddress).to.eq(coordinatorContract.address);
|
|
||||||
expect(cancelLogArgs.feeRecipientAddress).to.eq(feeRecipientAddress);
|
|
||||||
expect(cancelLogArgs.makerAssetData).to.eq(orders[0].makerAssetData);
|
|
||||||
expect(cancelLogArgs.takerAssetData).to.eq(orders[0].takerAssetData);
|
|
||||||
expect(cancelLogArgs.orderHash).to.eq(orderHashUtils.getOrderHashHex(orders[0]));
|
|
||||||
});
|
});
|
||||||
it('batchCancelOrders call should be successful without an approval', async () => {
|
it('batchCancelOrders call should be successful without an approval', async () => {
|
||||||
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
|
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.BatchCancelOrders, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.BatchCancelOrders, orders);
|
||||||
const transaction = await makerTransactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await makerTransactionFactory.newSignedTransactionAsync({ data });
|
||||||
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
|
const transactionReceipt = await coordinatorContract.executeTransaction.awaitTransactionSuccessAsync(
|
||||||
await coordinatorContract.executeTransaction.sendTransactionAsync(
|
|
||||||
transaction,
|
transaction,
|
||||||
makerAddress,
|
makerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
@ -485,28 +445,15 @@ describe('Coordinator tests', () => {
|
|||||||
{
|
{
|
||||||
from: makerAddress,
|
from: makerAddress,
|
||||||
},
|
},
|
||||||
),
|
|
||||||
);
|
);
|
||||||
const cancelLogs = transactionReceipt.logs.filter(
|
const expectedEvents = orders.map(order => expectedCancelEvent(order));
|
||||||
log => (log as LogWithDecodedArgs<ExchangeCancelEventArgs>).event === 'Cancel',
|
verifyEvents(transactionReceipt, expectedEvents, ExchangeEvents.Cancel);
|
||||||
);
|
|
||||||
expect(cancelLogs.length).to.eq(orders.length);
|
|
||||||
orders.forEach((order, index) => {
|
|
||||||
const cancelLogArgs = (cancelLogs[index] as LogWithDecodedArgs<ExchangeCancelEventArgs>).args;
|
|
||||||
expect(cancelLogArgs.makerAddress).to.eq(makerAddress);
|
|
||||||
expect(cancelLogArgs.senderAddress).to.eq(coordinatorContract.address);
|
|
||||||
expect(cancelLogArgs.feeRecipientAddress).to.eq(feeRecipientAddress);
|
|
||||||
expect(cancelLogArgs.makerAssetData).to.eq(order.makerAssetData);
|
|
||||||
expect(cancelLogArgs.takerAssetData).to.eq(order.takerAssetData);
|
|
||||||
expect(cancelLogArgs.orderHash).to.eq(orderHashUtils.getOrderHashHex(order));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
it('cancelOrdersUpTo call should be successful without an approval', async () => {
|
it('cancelOrdersUpTo call should be successful without an approval', async () => {
|
||||||
const targetEpoch = constants.ZERO_AMOUNT;
|
const targetEpoch = constants.ZERO_AMOUNT;
|
||||||
const data = exchange.cancelOrdersUpTo.getABIEncodedTransactionData(targetEpoch);
|
const data = exchange.cancelOrdersUpTo.getABIEncodedTransactionData(targetEpoch);
|
||||||
const transaction = await makerTransactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await makerTransactionFactory.newSignedTransactionAsync({ data });
|
||||||
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
|
const transactionReceipt = await coordinatorContract.executeTransaction.awaitTransactionSuccessAsync(
|
||||||
await coordinatorContract.executeTransaction.sendTransactionAsync(
|
|
||||||
transaction,
|
transaction,
|
||||||
makerAddress,
|
makerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
@ -515,16 +462,13 @@ describe('Coordinator tests', () => {
|
|||||||
{
|
{
|
||||||
from: makerAddress,
|
from: makerAddress,
|
||||||
},
|
},
|
||||||
),
|
|
||||||
);
|
);
|
||||||
const cancelLogs = transactionReceipt.logs.filter(
|
const expectedEvent: ExchangeCancelUpToEventArgs = {
|
||||||
log => (log as LogWithDecodedArgs<ExchangeCancelUpToEventArgs>).event === 'CancelUpTo',
|
makerAddress,
|
||||||
);
|
orderSenderAddress: coordinatorContract.address,
|
||||||
expect(cancelLogs.length).to.eq(1);
|
orderEpoch: targetEpoch.plus(1),
|
||||||
const cancelLogArgs = (cancelLogs[0] as LogWithDecodedArgs<ExchangeCancelUpToEventArgs>).args;
|
};
|
||||||
expect(cancelLogArgs.makerAddress).to.eq(makerAddress);
|
verifyEvents(transactionReceipt, [expectedEvent], ExchangeEvents.CancelUpTo);
|
||||||
expect(cancelLogArgs.orderSenderAddress).to.eq(coordinatorContract.address);
|
|
||||||
expect(cancelLogArgs.orderEpoch).to.bignumber.eq(targetEpoch.plus(1));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,44 +1,25 @@
|
|||||||
import { artifacts as exchangeArtifacts } from '@0x/contracts-exchange';
|
import { blockchainTests, expect } from '@0x/contracts-test-utils';
|
||||||
import { chaiSetup, provider, web3Wrapper } from '@0x/contracts-test-utils';
|
|
||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
|
||||||
import * as chai from 'chai';
|
|
||||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
import { LogWithDecodedArgs } from 'ethereum-types';
|
||||||
|
|
||||||
import { CoordinatorRegistryCoordinatorEndpointSetEventArgs } from '../src';
|
import { CoordinatorRegistryCoordinatorEndpointSetEventArgs } from '../src';
|
||||||
|
|
||||||
import { CoordinatorRegistryWrapper } from './utils/coordinator_registry_wrapper';
|
import { CoordinatorRegistryWrapper } from './utils/coordinator_registry_wrapper';
|
||||||
|
|
||||||
chaiSetup.configure();
|
|
||||||
const expect = chai.expect;
|
|
||||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
|
||||||
web3Wrapper.abiDecoder.addABI(exchangeArtifacts.Exchange.compilerOutput.abi);
|
|
||||||
// tslint:disable:no-unnecessary-type-assertion
|
// tslint:disable:no-unnecessary-type-assertion
|
||||||
describe('Coordinator Registry tests', () => {
|
blockchainTests.resets('Coordinator Registry tests', env => {
|
||||||
let coordinatorOperator: string;
|
let coordinatorOperator: string;
|
||||||
const coordinatorEndpoint = 'http://sometec.0x.org';
|
const coordinatorEndpoint = 'http://sometec.0x.org';
|
||||||
const nilCoordinatorEndpoint = '';
|
const nilCoordinatorEndpoint = '';
|
||||||
let coordinatorRegistryWrapper: CoordinatorRegistryWrapper;
|
let coordinatorRegistryWrapper: CoordinatorRegistryWrapper;
|
||||||
// tests
|
// tests
|
||||||
before(async () => {
|
|
||||||
await blockchainLifecycle.startAsync();
|
|
||||||
});
|
|
||||||
after(async () => {
|
|
||||||
await blockchainLifecycle.revertAsync();
|
|
||||||
});
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
// setup accounts (skip owner)
|
// setup accounts (skip owner)
|
||||||
const accounts = await web3Wrapper.getAvailableAddressesAsync();
|
const accounts = await env.getAccountAddressesAsync();
|
||||||
[, coordinatorOperator] = accounts;
|
[, coordinatorOperator] = accounts;
|
||||||
// deploy coordinator registry
|
// deploy coordinator registry
|
||||||
coordinatorRegistryWrapper = new CoordinatorRegistryWrapper(provider);
|
coordinatorRegistryWrapper = new CoordinatorRegistryWrapper(env.provider);
|
||||||
await coordinatorRegistryWrapper.deployCoordinatorRegistryAsync();
|
await coordinatorRegistryWrapper.deployCoordinatorRegistryAsync();
|
||||||
});
|
});
|
||||||
beforeEach(async () => {
|
|
||||||
await blockchainLifecycle.startAsync();
|
|
||||||
});
|
|
||||||
afterEach(async () => {
|
|
||||||
await blockchainLifecycle.revertAsync();
|
|
||||||
});
|
|
||||||
describe('core', () => {
|
describe('core', () => {
|
||||||
it('Should successfully set a Coordinator endpoint', async () => {
|
it('Should successfully set a Coordinator endpoint', async () => {
|
||||||
await coordinatorRegistryWrapper.setCoordinatorEndpointAsync(coordinatorOperator, coordinatorEndpoint);
|
await coordinatorRegistryWrapper.setCoordinatorEndpointAsync(coordinatorOperator, coordinatorEndpoint);
|
||||||
|
@ -1,66 +1,31 @@
|
|||||||
import { chaiSetup, constants, provider, randomAddress, txDefaults, web3Wrapper } from '@0x/contracts-test-utils';
|
import { blockchainTests, constants, expect, randomAddress } from '@0x/contracts-test-utils';
|
||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
|
||||||
import { transactionHashUtils } from '@0x/order-utils';
|
import { transactionHashUtils } from '@0x/order-utils';
|
||||||
import { BigNumber, providerUtils } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
import * as chai from 'chai';
|
|
||||||
|
|
||||||
import { artifacts, CoordinatorContract, hashUtils } from '../src';
|
import { artifacts, CoordinatorContract, hashUtils } from '../src';
|
||||||
|
|
||||||
chaiSetup.configure();
|
blockchainTests.resets('Libs tests', env => {
|
||||||
const expect = chai.expect;
|
|
||||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
|
||||||
|
|
||||||
describe('Libs tests', () => {
|
|
||||||
let coordinatorContract: CoordinatorContract;
|
let coordinatorContract: CoordinatorContract;
|
||||||
let chainId: number;
|
let chainId: number;
|
||||||
const exchangeAddress = randomAddress();
|
const exchangeAddress = randomAddress();
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
await blockchainLifecycle.startAsync();
|
chainId = await env.getChainIdAsync();
|
||||||
});
|
|
||||||
after(async () => {
|
|
||||||
await blockchainLifecycle.revertAsync();
|
|
||||||
});
|
|
||||||
before(async () => {
|
|
||||||
chainId = await providerUtils.getChainIdAsync(provider);
|
|
||||||
coordinatorContract = await CoordinatorContract.deployFrom0xArtifactAsync(
|
coordinatorContract = await CoordinatorContract.deployFrom0xArtifactAsync(
|
||||||
artifacts.Coordinator,
|
artifacts.Coordinator,
|
||||||
provider,
|
env.provider,
|
||||||
txDefaults,
|
env.txDefaults,
|
||||||
artifacts,
|
artifacts,
|
||||||
exchangeAddress,
|
exchangeAddress,
|
||||||
new BigNumber(chainId),
|
new BigNumber(chainId),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
beforeEach(async () => {
|
|
||||||
await blockchainLifecycle.startAsync();
|
|
||||||
});
|
|
||||||
afterEach(async () => {
|
|
||||||
await blockchainLifecycle.revertAsync();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getTransactionHash', () => {
|
|
||||||
it('should return the correct transaction hash', async () => {
|
|
||||||
const tx = {
|
|
||||||
salt: new BigNumber(0),
|
|
||||||
expirationTimeSeconds: new BigNumber(0),
|
|
||||||
signerAddress: constants.NULL_ADDRESS,
|
|
||||||
data: '0x1234',
|
|
||||||
domain: {
|
|
||||||
verifyingContract: exchangeAddress,
|
|
||||||
chainId,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const expectedTxHash = transactionHashUtils.getTransactionHashHex(tx);
|
|
||||||
const txHash = await coordinatorContract.getTransactionHash.callAsync(tx);
|
|
||||||
expect(expectedTxHash).to.eq(txHash);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getApprovalHash', () => {
|
describe('getApprovalHash', () => {
|
||||||
it('should return the correct approval hash', async () => {
|
it('should return the correct approval hash', async () => {
|
||||||
const signedTx = {
|
const signedTx = {
|
||||||
salt: new BigNumber(0),
|
salt: new BigNumber(0),
|
||||||
|
gasPrice: new BigNumber(0),
|
||||||
expirationTimeSeconds: new BigNumber(0),
|
expirationTimeSeconds: new BigNumber(0),
|
||||||
signerAddress: constants.NULL_ADDRESS,
|
signerAddress: constants.NULL_ADDRESS,
|
||||||
data: '0x1234',
|
data: '0x1234',
|
||||||
|
@ -1,29 +1,20 @@
|
|||||||
import { constants as exchangeConstants, exchangeDataEncoder, ExchangeFunctionName } from '@0x/contracts-exchange';
|
import { constants as exchangeConstants, exchangeDataEncoder, ExchangeFunctionName } from '@0x/contracts-exchange';
|
||||||
import {
|
import {
|
||||||
chaiSetup,
|
blockchainTests,
|
||||||
constants,
|
constants,
|
||||||
expectContractCallFailedAsync,
|
expect,
|
||||||
getLatestBlockTimestampAsync,
|
getLatestBlockTimestampAsync,
|
||||||
provider,
|
|
||||||
randomAddress,
|
randomAddress,
|
||||||
TransactionFactory,
|
TransactionFactory,
|
||||||
txDefaults,
|
|
||||||
web3Wrapper,
|
|
||||||
} from '@0x/contracts-test-utils';
|
} from '@0x/contracts-test-utils';
|
||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
import { CoordinatorRevertErrors, transactionHashUtils } from '@0x/order-utils';
|
||||||
import { transactionHashUtils } from '@0x/order-utils';
|
import { SignatureType, SignedOrder } from '@0x/types';
|
||||||
import { RevertReason, SignatureType, SignedOrder } from '@0x/types';
|
import { BigNumber, LibBytesRevertErrors } from '@0x/utils';
|
||||||
import { BigNumber, LibBytesRevertErrors, providerUtils } from '@0x/utils';
|
|
||||||
import * as chai from 'chai';
|
|
||||||
import * as ethUtil from 'ethereumjs-util';
|
import * as ethUtil from 'ethereumjs-util';
|
||||||
|
|
||||||
import { ApprovalFactory, artifacts, CoordinatorContract } from '../src';
|
import { ApprovalFactory, artifacts, CoordinatorContract } from '../src';
|
||||||
|
|
||||||
chaiSetup.configure();
|
blockchainTests.resets('Mixins tests', env => {
|
||||||
const expect = chai.expect;
|
|
||||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
|
||||||
|
|
||||||
describe('Mixins tests', () => {
|
|
||||||
let chainId: number;
|
let chainId: number;
|
||||||
let transactionSignerAddress: string;
|
let transactionSignerAddress: string;
|
||||||
let approvalSignerAddress1: string;
|
let approvalSignerAddress1: string;
|
||||||
@ -36,23 +27,17 @@ describe('Mixins tests', () => {
|
|||||||
const exchangeAddress = randomAddress();
|
const exchangeAddress = randomAddress();
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
await blockchainLifecycle.startAsync();
|
chainId = await env.getChainIdAsync();
|
||||||
});
|
|
||||||
after(async () => {
|
|
||||||
await blockchainLifecycle.revertAsync();
|
|
||||||
});
|
|
||||||
before(async () => {
|
|
||||||
chainId = await providerUtils.getChainIdAsync(provider);
|
|
||||||
mixins = await CoordinatorContract.deployFrom0xArtifactAsync(
|
mixins = await CoordinatorContract.deployFrom0xArtifactAsync(
|
||||||
artifacts.Coordinator,
|
artifacts.Coordinator,
|
||||||
provider,
|
env.provider,
|
||||||
txDefaults,
|
env.txDefaults,
|
||||||
artifacts,
|
artifacts,
|
||||||
exchangeAddress,
|
exchangeAddress,
|
||||||
new BigNumber(chainId),
|
new BigNumber(chainId),
|
||||||
);
|
);
|
||||||
const accounts = await web3Wrapper.getAvailableAddressesAsync();
|
const accounts = await env.getAccountAddressesAsync();
|
||||||
[transactionSignerAddress, approvalSignerAddress1, approvalSignerAddress2] = accounts.slice(0, 3);
|
[transactionSignerAddress, approvalSignerAddress1, approvalSignerAddress2] = accounts;
|
||||||
defaultOrder = {
|
defaultOrder = {
|
||||||
makerAddress: constants.NULL_ADDRESS,
|
makerAddress: constants.NULL_ADDRESS,
|
||||||
takerAddress: constants.NULL_ADDRESS,
|
takerAddress: constants.NULL_ADDRESS,
|
||||||
@ -79,12 +64,6 @@ describe('Mixins tests', () => {
|
|||||||
approvalFactory1 = new ApprovalFactory(approvalSignerPrivateKey1, mixins.address);
|
approvalFactory1 = new ApprovalFactory(approvalSignerPrivateKey1, mixins.address);
|
||||||
approvalFactory2 = new ApprovalFactory(approvalSignerPrivateKey2, mixins.address);
|
approvalFactory2 = new ApprovalFactory(approvalSignerPrivateKey2, mixins.address);
|
||||||
});
|
});
|
||||||
beforeEach(async () => {
|
|
||||||
await blockchainLifecycle.startAsync();
|
|
||||||
});
|
|
||||||
afterEach(async () => {
|
|
||||||
await blockchainLifecycle.revertAsync();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getSignerAddress', () => {
|
describe('getSignerAddress', () => {
|
||||||
it('should return the correct address using the EthSign signature type', async () => {
|
it('should return the correct address using the EthSign signature type', async () => {
|
||||||
@ -110,8 +89,12 @@ describe('Mixins tests', () => {
|
|||||||
transaction.signature.length - 2,
|
transaction.signature.length - 2,
|
||||||
)}${illegalSignatureByte}`;
|
)}${illegalSignatureByte}`;
|
||||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.be.rejectedWith(
|
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith(
|
||||||
RevertReason.SignatureIllegal,
|
new CoordinatorRevertErrors.SignatureError(
|
||||||
|
CoordinatorRevertErrors.SignatureErrorCodes.Illegal,
|
||||||
|
transactionHash,
|
||||||
|
transaction.signature,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should revert with with the Invalid signature type', async () => {
|
it('should revert with with the Invalid signature type', async () => {
|
||||||
@ -120,8 +103,12 @@ describe('Mixins tests', () => {
|
|||||||
const invalidSignatureByte = ethUtil.toBuffer(SignatureType.Invalid).toString('hex');
|
const invalidSignatureByte = ethUtil.toBuffer(SignatureType.Invalid).toString('hex');
|
||||||
transaction.signature = `0x${invalidSignatureByte}`;
|
transaction.signature = `0x${invalidSignatureByte}`;
|
||||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.be.rejectedWith(
|
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith(
|
||||||
RevertReason.SignatureInvalid,
|
new CoordinatorRevertErrors.SignatureError(
|
||||||
|
CoordinatorRevertErrors.SignatureErrorCodes.Invalid,
|
||||||
|
transactionHash,
|
||||||
|
transaction.signature,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it("should revert with with a signature type that doesn't exist", async () => {
|
it("should revert with with a signature type that doesn't exist", async () => {
|
||||||
@ -133,8 +120,12 @@ describe('Mixins tests', () => {
|
|||||||
transaction.signature.length - 2,
|
transaction.signature.length - 2,
|
||||||
)}${invalidSignatureByte}`;
|
)}${invalidSignatureByte}`;
|
||||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.be.rejectedWith(
|
expect(mixins.getSignerAddress.callAsync(transactionHash, transaction.signature)).to.revertWith(
|
||||||
RevertReason.SignatureUnsupported,
|
new CoordinatorRevertErrors.SignatureError(
|
||||||
|
CoordinatorRevertErrors.SignatureErrorCodes.Unsupported,
|
||||||
|
transactionHash,
|
||||||
|
transaction.signature,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -320,16 +311,18 @@ describe('Mixins tests', () => {
|
|||||||
approvalExpirationTimeSeconds,
|
approvalExpirationTimeSeconds,
|
||||||
);
|
);
|
||||||
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
|
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
|
||||||
expectContractCallFailedAsync(
|
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
|
||||||
transaction,
|
transaction,
|
||||||
transactionSignerAddress,
|
transactionSignerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[approvalExpirationTimeSeconds],
|
[approvalExpirationTimeSeconds],
|
||||||
[signature],
|
[signature],
|
||||||
{ from: transactionSignerAddress },
|
{ from: transactionSignerAddress },
|
||||||
),
|
);
|
||||||
RevertReason.InvalidApprovalSignature,
|
|
||||||
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
|
expect(tx).to.revertWith(
|
||||||
|
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, approvalSignerAddress1),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1], expiration=[invalid]`, async () => {
|
it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1], expiration=[invalid]`, async () => {
|
||||||
@ -343,16 +336,18 @@ describe('Mixins tests', () => {
|
|||||||
transactionSignerAddress,
|
transactionSignerAddress,
|
||||||
approvalExpirationTimeSeconds,
|
approvalExpirationTimeSeconds,
|
||||||
);
|
);
|
||||||
expectContractCallFailedAsync(
|
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
|
||||||
transaction,
|
transaction,
|
||||||
transactionSignerAddress,
|
transactionSignerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[approvalExpirationTimeSeconds],
|
[approvalExpirationTimeSeconds],
|
||||||
[approval.signature],
|
[approval.signature],
|
||||||
{ from: transactionSignerAddress },
|
{ from: transactionSignerAddress },
|
||||||
),
|
);
|
||||||
RevertReason.ApprovalExpired,
|
|
||||||
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
|
expect(tx).to.revertWith(
|
||||||
|
new CoordinatorRevertErrors.ApprovalExpiredError(transactionHash, approvalExpirationTimeSeconds),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it(`Should revert: function=${fnName}, caller=approver2, senderAddress=[verifier], approval_sig=[approver1], expiration=[valid]`, async () => {
|
it(`Should revert: function=${fnName}, caller=approver2, senderAddress=[verifier], approval_sig=[approver1], expiration=[valid]`, async () => {
|
||||||
@ -366,17 +361,16 @@ describe('Mixins tests', () => {
|
|||||||
transactionSignerAddress,
|
transactionSignerAddress,
|
||||||
approvalExpirationTimeSeconds,
|
approvalExpirationTimeSeconds,
|
||||||
);
|
);
|
||||||
expectContractCallFailedAsync(
|
|
||||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||||
transaction,
|
transaction,
|
||||||
transactionSignerAddress,
|
transactionSignerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[approvalExpirationTimeSeconds],
|
[approvalExpirationTimeSeconds],
|
||||||
[approval.signature],
|
[approval.signature],
|
||||||
{ from: approvalSignerAddress2 },
|
{ from: approvalSignerAddress2 },
|
||||||
),
|
|
||||||
RevertReason.InvalidOrigin,
|
|
||||||
);
|
);
|
||||||
|
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -514,32 +508,33 @@ describe('Mixins tests', () => {
|
|||||||
transactionSignerAddress,
|
transactionSignerAddress,
|
||||||
approvalExpirationTimeSeconds,
|
approvalExpirationTimeSeconds,
|
||||||
);
|
);
|
||||||
expectContractCallFailedAsync(
|
|
||||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||||
transaction,
|
transaction,
|
||||||
transactionSignerAddress,
|
transactionSignerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[approvalExpirationTimeSeconds],
|
[approvalExpirationTimeSeconds],
|
||||||
[approval2.signature],
|
[approval2.signature],
|
||||||
{ from: approvalSignerAddress1 },
|
{ from: approvalSignerAddress1 },
|
||||||
),
|
|
||||||
RevertReason.InvalidOrigin,
|
|
||||||
);
|
);
|
||||||
|
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress));
|
||||||
});
|
});
|
||||||
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[], expiration=[]`, async () => {
|
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[], expiration=[]`, async () => {
|
||||||
const orders = [defaultOrder, defaultOrder];
|
const orders = [defaultOrder, defaultOrder];
|
||||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||||
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
const transaction = await transactionFactory.newSignedTransactionAsync({ data });
|
||||||
expectContractCallFailedAsync(
|
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
|
||||||
transaction,
|
transaction,
|
||||||
transactionSignerAddress,
|
transactionSignerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[],
|
[],
|
||||||
[],
|
[],
|
||||||
{ from: transactionSignerAddress },
|
{ from: transactionSignerAddress },
|
||||||
),
|
);
|
||||||
RevertReason.InvalidApprovalSignature,
|
|
||||||
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
|
expect(tx).to.revertWith(
|
||||||
|
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, approvalSignerAddress1),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[invalid], expiration=[valid]`, async () => {
|
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[invalid], expiration=[valid]`, async () => {
|
||||||
@ -554,16 +549,18 @@ describe('Mixins tests', () => {
|
|||||||
approvalExpirationTimeSeconds,
|
approvalExpirationTimeSeconds,
|
||||||
);
|
);
|
||||||
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
|
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
|
||||||
expectContractCallFailedAsync(
|
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
|
||||||
transaction,
|
transaction,
|
||||||
transactionSignerAddress,
|
transactionSignerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[approvalExpirationTimeSeconds],
|
[approvalExpirationTimeSeconds],
|
||||||
[signature],
|
[signature],
|
||||||
{ from: transactionSignerAddress },
|
{ from: transactionSignerAddress },
|
||||||
),
|
);
|
||||||
RevertReason.InvalidApprovalSignature,
|
|
||||||
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
|
expect(tx).to.revertWith(
|
||||||
|
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, approvalSignerAddress1),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid,invalid], expiration=[valid,valid]`, async () => {
|
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid,invalid], expiration=[valid,valid]`, async () => {
|
||||||
@ -583,16 +580,18 @@ describe('Mixins tests', () => {
|
|||||||
approvalExpirationTimeSeconds,
|
approvalExpirationTimeSeconds,
|
||||||
);
|
);
|
||||||
const approvalSignature2 = `${approval2.signature.slice(0, 4)}FFFFFFFF${approval2.signature.slice(12)}`;
|
const approvalSignature2 = `${approval2.signature.slice(0, 4)}FFFFFFFF${approval2.signature.slice(12)}`;
|
||||||
expectContractCallFailedAsync(
|
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
|
||||||
transaction,
|
transaction,
|
||||||
transactionSignerAddress,
|
transactionSignerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
|
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
|
||||||
[approval1.signature, approvalSignature2],
|
[approval1.signature, approvalSignature2],
|
||||||
{ from: transactionSignerAddress },
|
{ from: transactionSignerAddress },
|
||||||
),
|
);
|
||||||
RevertReason.InvalidApprovalSignature,
|
|
||||||
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
|
expect(tx).to.revertWith(
|
||||||
|
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, approvalSignerAddress2),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[invalid], expiration=[valid]`, async () => {
|
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[invalid], expiration=[valid]`, async () => {
|
||||||
@ -607,16 +606,18 @@ describe('Mixins tests', () => {
|
|||||||
approvalExpirationTimeSeconds,
|
approvalExpirationTimeSeconds,
|
||||||
);
|
);
|
||||||
const approvalSignature2 = `${approval2.signature.slice(0, 4)}FFFFFFFF${approval2.signature.slice(12)}`;
|
const approvalSignature2 = `${approval2.signature.slice(0, 4)}FFFFFFFF${approval2.signature.slice(12)}`;
|
||||||
expectContractCallFailedAsync(
|
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
|
||||||
transaction,
|
transaction,
|
||||||
approvalSignerAddress1,
|
approvalSignerAddress1,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[approvalExpirationTimeSeconds],
|
[approvalExpirationTimeSeconds],
|
||||||
[approvalSignature2],
|
[approvalSignature2],
|
||||||
{ from: approvalSignerAddress1 },
|
{ from: approvalSignerAddress1 },
|
||||||
),
|
);
|
||||||
RevertReason.InvalidApprovalSignature,
|
|
||||||
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
|
expect(tx).to.revertWith(
|
||||||
|
new CoordinatorRevertErrors.InvalidApprovalSignatureError(transactionHash, approvalSignerAddress2),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid,valid], expiration=[valid,invalid]`, async () => {
|
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid,valid], expiration=[valid,invalid]`, async () => {
|
||||||
@ -636,16 +637,18 @@ describe('Mixins tests', () => {
|
|||||||
transactionSignerAddress,
|
transactionSignerAddress,
|
||||||
approvalExpirationTimeSeconds2,
|
approvalExpirationTimeSeconds2,
|
||||||
);
|
);
|
||||||
expectContractCallFailedAsync(
|
|
||||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||||
transaction,
|
transaction,
|
||||||
transactionSignerAddress,
|
transactionSignerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[approvalExpirationTimeSeconds1, approvalExpirationTimeSeconds2],
|
[approvalExpirationTimeSeconds1, approvalExpirationTimeSeconds2],
|
||||||
[approval1.signature, approval2.signature],
|
[approval1.signature, approval2.signature],
|
||||||
{ from: transactionSignerAddress },
|
{ from: transactionSignerAddress },
|
||||||
),
|
);
|
||||||
RevertReason.ApprovalExpired,
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
|
expect(tx).to.revertWith(
|
||||||
|
new CoordinatorRevertErrors.ApprovalExpiredError(transactionHash, approvalExpirationTimeSeconds2),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid], expiration=[invalid]`, async () => {
|
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid], expiration=[invalid]`, async () => {
|
||||||
@ -659,16 +662,18 @@ describe('Mixins tests', () => {
|
|||||||
transactionSignerAddress,
|
transactionSignerAddress,
|
||||||
approvalExpirationTimeSeconds,
|
approvalExpirationTimeSeconds,
|
||||||
);
|
);
|
||||||
expectContractCallFailedAsync(
|
|
||||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||||
transaction,
|
transaction,
|
||||||
approvalSignerAddress1,
|
approvalSignerAddress1,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[approvalExpirationTimeSeconds],
|
[approvalExpirationTimeSeconds],
|
||||||
[approval2.signature],
|
[approval2.signature],
|
||||||
{ from: approvalSignerAddress1 },
|
{ from: approvalSignerAddress1 },
|
||||||
),
|
);
|
||||||
RevertReason.ApprovalExpired,
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
|
expect(tx).to.revertWith(
|
||||||
|
new CoordinatorRevertErrors.ApprovalExpiredError(transactionHash, approvalExpirationTimeSeconds),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it(`Should revert: function=${fnName} caller=approver2, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[valid], expiration=[valid]`, async () => {
|
it(`Should revert: function=${fnName} caller=approver2, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[valid], expiration=[valid]`, async () => {
|
||||||
@ -682,17 +687,16 @@ describe('Mixins tests', () => {
|
|||||||
transactionSignerAddress,
|
transactionSignerAddress,
|
||||||
approvalExpirationTimeSeconds,
|
approvalExpirationTimeSeconds,
|
||||||
);
|
);
|
||||||
expectContractCallFailedAsync(
|
|
||||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
const tx = mixins.assertValidCoordinatorApprovals.callAsync(
|
||||||
transaction,
|
transaction,
|
||||||
transactionSignerAddress,
|
transactionSignerAddress,
|
||||||
transaction.signature,
|
transaction.signature,
|
||||||
[approvalExpirationTimeSeconds],
|
[approvalExpirationTimeSeconds],
|
||||||
[approval1.signature],
|
[approval1.signature],
|
||||||
{ from: approvalSignerAddress2 },
|
{ from: approvalSignerAddress2 },
|
||||||
),
|
|
||||||
RevertReason.InvalidOrigin,
|
|
||||||
);
|
);
|
||||||
|
expect(tx).to.revertWith(new CoordinatorRevertErrors.InvalidOriginError(transactionSignerAddress));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { artifacts as exchangeArtifacts } from '@0x/contracts-exchange';
|
||||||
import { LogDecoder, txDefaults } from '@0x/contracts-test-utils';
|
import { LogDecoder, txDefaults } from '@0x/contracts-test-utils';
|
||||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||||
import { TransactionReceiptWithDecodedLogs, ZeroExProvider } from 'ethereum-types';
|
import { TransactionReceiptWithDecodedLogs, ZeroExProvider } from 'ethereum-types';
|
||||||
@ -17,7 +18,7 @@ export class CoordinatorRegistryWrapper {
|
|||||||
constructor(provider: ZeroExProvider) {
|
constructor(provider: ZeroExProvider) {
|
||||||
this._web3Wrapper = new Web3Wrapper(provider);
|
this._web3Wrapper = new Web3Wrapper(provider);
|
||||||
this._provider = provider;
|
this._provider = provider;
|
||||||
this._logDecoder = new LogDecoder(this._web3Wrapper, artifacts);
|
this._logDecoder = new LogDecoder(this._web3Wrapper, { ...exchangeArtifacts, ...artifacts });
|
||||||
}
|
}
|
||||||
public async deployCoordinatorRegistryAsync(): Promise<CoordinatorRegistryContract> {
|
public async deployCoordinatorRegistryAsync(): Promise<CoordinatorRegistryContract> {
|
||||||
this._coordinatorRegistryContract = await CoordinatorRegistryContract.deployFrom0xArtifactAsync(
|
this._coordinatorRegistryContract = await CoordinatorRegistryContract.deployFrom0xArtifactAsync(
|
||||||
|
@ -2,6 +2,21 @@
|
|||||||
"extends": "../../tsconfig",
|
"extends": "../../tsconfig",
|
||||||
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
|
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
|
||||||
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
|
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
|
||||||
"files": ["generated-artifacts/Coordinator.json", "generated-artifacts/CoordinatorRegistry.json"],
|
"files": [
|
||||||
|
"generated-artifacts/Coordinator.json",
|
||||||
|
"generated-artifacts/CoordinatorRegistry.json",
|
||||||
|
"generated-artifacts/ICoordinatorApprovalVerifier.json",
|
||||||
|
"generated-artifacts/ICoordinatorCore.json",
|
||||||
|
"generated-artifacts/ICoordinatorRegistryCore.json",
|
||||||
|
"generated-artifacts/ICoordinatorSignatureValidator.json",
|
||||||
|
"generated-artifacts/LibConstants.json",
|
||||||
|
"generated-artifacts/LibCoordinatorApproval.json",
|
||||||
|
"generated-artifacts/LibCoordinatorRichErrors.json",
|
||||||
|
"generated-artifacts/LibEIP712CoordinatorDomain.json",
|
||||||
|
"generated-artifacts/MixinCoordinatorApprovalVerifier.json",
|
||||||
|
"generated-artifacts/MixinCoordinatorCore.json",
|
||||||
|
"generated-artifacts/MixinCoordinatorRegistryCore.json",
|
||||||
|
"generated-artifacts/MixinSignatureValidator.json"
|
||||||
|
],
|
||||||
"exclude": ["./deploy/solc/solc_bin"]
|
"exclude": ["./deploy/solc/solc_bin"]
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ export const constants = {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
COORDINATOR_DOMAIN_NAME: '0x Protocol Coordinator',
|
COORDINATOR_DOMAIN_NAME: '0x Protocol Coordinator',
|
||||||
COORDINATOR_DOMAIN_VERSION: '2.0.0',
|
COORDINATOR_DOMAIN_VERSION: '3.0.0',
|
||||||
COORDINATOR_APPROVAL_SCHEMA: {
|
COORDINATOR_APPROVAL_SCHEMA: {
|
||||||
name: 'CoordinatorApproval',
|
name: 'CoordinatorApproval',
|
||||||
parameters: [
|
parameters: [
|
||||||
|
@ -34,17 +34,17 @@ export class ApprovalExpiredError extends RevertError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class InvalidApprovalSignature extends RevertError {
|
export class InvalidApprovalSignatureError extends RevertError {
|
||||||
constructor(transactionHash?: string, approverAddress?: string) {
|
constructor(transactionHash?: string, approverAddress?: string) {
|
||||||
super(
|
super(
|
||||||
'InvalidApprovalSignature',
|
'InvalidApprovalSignatureError',
|
||||||
'InvalidApprovalSignature(bytes32 transactionHash, address approverAddress)',
|
'InvalidApprovalSignatureError(bytes32 transactionHash, address approverAddress)',
|
||||||
{ transactionHash, approverAddress },
|
{ transactionHash, approverAddress },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const types = [SignatureError, InvalidOriginError, ApprovalExpiredError, InvalidApprovalSignature];
|
const types = [SignatureError, InvalidOriginError, ApprovalExpiredError, InvalidApprovalSignatureError];
|
||||||
|
|
||||||
// Register the types we've defined.
|
// Register the types we've defined.
|
||||||
for (const type of types) {
|
for (const type of types) {
|
||||||
|
@ -95,7 +95,7 @@ export const eip712Utils = {
|
|||||||
return typedData;
|
return typedData;
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Creates an Coordiantor typedData EIP712TypedData object for use with the Coordinator extension contract
|
* Creates an Coordinator typedData EIP712TypedData object for use with the Coordinator extension contract
|
||||||
* @param transaction A 0x transaction
|
* @param transaction A 0x transaction
|
||||||
* @param verifyingContract The coordinator extension contract address that will be verifying the typedData
|
* @param verifyingContract The coordinator extension contract address that will be verifying the typedData
|
||||||
* @param txOrigin The desired `tx.origin` that should be able to submit an Ethereum txn involving this 0x transaction
|
* @param txOrigin The desired `tx.origin` that should be able to submit an Ethereum txn involving this 0x transaction
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
export import CoordinatorRevertErrors = require('./coordinator_revert_errors');
|
||||||
export import ExchangeRevertErrors = require('./exchange_revert_errors');
|
export import ExchangeRevertErrors = require('./exchange_revert_errors');
|
||||||
export import ForwarderRevertErrors = require('./forwarder_revert_errors');
|
export import ForwarderRevertErrors = require('./forwarder_revert_errors');
|
||||||
export import LibMathRevertErrors = require('./lib_math_revert_errors');
|
export import LibMathRevertErrors = require('./lib_math_revert_errors');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user