Add more verification test cases
This commit is contained in:
parent
3c649df3df
commit
2de9b862d8
@ -1,4 +1,3 @@
|
||||
import { artifacts as exchangeArtifacts, IExchangeContract } from '@0x/contracts-exchange';
|
||||
import {
|
||||
chaiSetup,
|
||||
constants as devConstants,
|
||||
@ -18,6 +17,7 @@ import {
|
||||
ApprovalFactory,
|
||||
artifacts,
|
||||
constants,
|
||||
exchangeDataEncoder,
|
||||
hashUtils,
|
||||
TECSignatureType,
|
||||
TECTransactionFactory,
|
||||
@ -29,34 +29,7 @@ const expect = chai.expect;
|
||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
||||
const timeBuffer = new BigNumber(1000);
|
||||
|
||||
const encodeBatchOrderApproval = (fn: string, orders: SignedOrder[], exchangeInstance: IExchangeContract): string => {
|
||||
let data;
|
||||
if (constants.BATCH_FILL_FN_NAMES.indexOf(fn) !== -1) {
|
||||
data = (exchangeInstance as any)[fn].getABIEncodedTransactionData(
|
||||
orders,
|
||||
orders.map(order => order.takerAssetAmount),
|
||||
orders.map(order => order.signature),
|
||||
);
|
||||
} else if (constants.MARKET_FILL_FN_NAMES.indexOf(fn) !== -1) {
|
||||
data = (exchangeInstance as any)[fn].getABIEncodedTransactionData(
|
||||
orders,
|
||||
orders[0].takerAssetAmount,
|
||||
orders.map(order => order.signature),
|
||||
);
|
||||
} else if (fn === 'matchOrders') {
|
||||
data = (exchangeInstance as any)[fn].getABIEncodedTransactionData(
|
||||
orders[0],
|
||||
orders[1],
|
||||
orders[0].signature,
|
||||
orders[1].signature,
|
||||
);
|
||||
} else {
|
||||
throw new Error(`Error: ${fn} not a batch fill function`);
|
||||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
describe.only('Mixins tests', () => {
|
||||
describe('Mixins tests', () => {
|
||||
let transactionSignerAddress: string;
|
||||
let approvalSignerAddress1: string;
|
||||
let approvalSignerAddress2: string;
|
||||
@ -65,7 +38,6 @@ describe.only('Mixins tests', () => {
|
||||
let approvalFactory1: ApprovalFactory;
|
||||
let approvalFactory2: ApprovalFactory;
|
||||
let defaultOrder: SignedOrder;
|
||||
let exchangeInterface: IExchangeContract;
|
||||
before(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
});
|
||||
@ -74,13 +46,8 @@ describe.only('Mixins tests', () => {
|
||||
});
|
||||
before(async () => {
|
||||
mixins = await TestMixinsContract.deployFrom0xArtifactAsync(artifacts.TestMixins, provider, txDefaults);
|
||||
exchangeInterface = await IExchangeContract.deployFrom0xArtifactAsync(
|
||||
exchangeArtifacts.IExchange,
|
||||
provider,
|
||||
txDefaults,
|
||||
);
|
||||
const accounts = await web3Wrapper.getAvailableAddressesAsync();
|
||||
[transactionSignerAddress, approvalSignerAddress1, approvalSignerAddress2] = accounts.slice(0, 2);
|
||||
[transactionSignerAddress, approvalSignerAddress1, approvalSignerAddress2] = accounts.slice(0, 3);
|
||||
defaultOrder = {
|
||||
exchangeAddress: devConstants.NULL_ADDRESS,
|
||||
makerAddress: devConstants.NULL_ADDRESS,
|
||||
@ -157,24 +124,20 @@ describe.only('Mixins tests', () => {
|
||||
});
|
||||
|
||||
describe('Single order approvals', () => {
|
||||
for (const fn of constants.SINGLE_FILL_FN_NAMES) {
|
||||
it(`Should be successful: function=${fn}, caller=tx_signer, senderAddress=verifier, approval_sig=approver1, expiration=valid`, async () => {
|
||||
const data = (exchangeInterface as any)[fn].getABIEncodedTransactionData(
|
||||
defaultOrder,
|
||||
defaultOrder.takerAssetAmount,
|
||||
defaultOrder.signature,
|
||||
);
|
||||
for (const fnName of constants.SINGLE_FILL_FN_NAMES) {
|
||||
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1], expiration=[valid]`, async () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const transactionHash = hashUtils.getTransactionHashHex(transaction);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
await mixins.assertValidSingleOrderApproval.callAsync(
|
||||
defaultOrder,
|
||||
transactionHash,
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transaction.signature,
|
||||
approvalExpirationTimeSeconds,
|
||||
approval.approvalSignature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.approvalSignature],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
await mixins.assertValidTECApprovals.callAsync(
|
||||
@ -185,27 +148,23 @@ describe.only('Mixins tests', () => {
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
});
|
||||
it(`Should be successful: function=${fn}, caller=tx_signer, senderAddress=null, approval_sig=approver1, expiration=valid`, async () => {
|
||||
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[null], approval_sig=[approver1], expiration=[valid]`, async () => {
|
||||
const order = {
|
||||
...defaultOrder,
|
||||
senderAddress: devConstants.NULL_ADDRESS,
|
||||
};
|
||||
const data = (exchangeInterface as any)[fn].getABIEncodedTransactionData(
|
||||
order,
|
||||
order.takerAssetAmount,
|
||||
order.signature,
|
||||
);
|
||||
const orders = [order];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const transactionHash = hashUtils.getTransactionHashHex(transaction);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
await mixins.assertValidSingleOrderApproval.callAsync(
|
||||
order,
|
||||
transactionHash,
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transaction.signature,
|
||||
approvalExpirationTimeSeconds,
|
||||
approval.approvalSignature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.approvalSignature],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
await mixins.assertValidTECApprovals.callAsync(
|
||||
@ -216,88 +175,65 @@ describe.only('Mixins tests', () => {
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
});
|
||||
it(`Should be successful: function=${fn}, caller=approver1, senderAddress=verifier, approval_sig=null, expiration=valid`, async () => {
|
||||
const data = (exchangeInterface as any)[fn].getABIEncodedTransactionData(
|
||||
defaultOrder,
|
||||
defaultOrder.takerAssetAmount,
|
||||
defaultOrder.signature,
|
||||
);
|
||||
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[], expiration=[]`, async () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const transactionHash = hashUtils.getTransactionHashHex(transaction);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
|
||||
const approvalSignature = devConstants.NULL_BYTES;
|
||||
await mixins.assertValidSingleOrderApproval.callAsync(
|
||||
defaultOrder,
|
||||
transactionHash,
|
||||
transaction.signature,
|
||||
approvalExpirationTimeSeconds,
|
||||
approvalSignature,
|
||||
{ from: approvalSignerAddress1 },
|
||||
);
|
||||
await mixins.assertValidTECApprovals.callAsync(
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approvalSignature],
|
||||
{ from: approvalSignerAddress1 },
|
||||
);
|
||||
});
|
||||
it(`Should be successful: function=${fn}, caller=approver1, senderAddress=verifier, approval_sig=approver1, expiration=invalid`, async () => {
|
||||
const data = (exchangeInterface as any)[fn].getABIEncodedTransactionData(
|
||||
defaultOrder,
|
||||
defaultOrder.takerAssetAmount,
|
||||
defaultOrder.signature,
|
||||
);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const transactionHash = hashUtils.getTransactionHashHex(transaction);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
await mixins.assertValidSingleOrderApproval.callAsync(
|
||||
defaultOrder,
|
||||
transactionHash,
|
||||
transaction.signature,
|
||||
approvalExpirationTimeSeconds,
|
||||
approval.approvalSignature,
|
||||
{ from: approvalSignerAddress1 },
|
||||
);
|
||||
await mixins.assertValidTECApprovals.callAsync(
|
||||
transaction,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.approvalSignature],
|
||||
{ from: approvalSignerAddress1 },
|
||||
);
|
||||
});
|
||||
it(`Should be successful: function=${fn}, caller=approver1, senderAddress=verifier, approval_sig=null, expiration=null`, async () => {
|
||||
const data = (exchangeInterface as any)[fn].getABIEncodedTransactionData(
|
||||
defaultOrder,
|
||||
defaultOrder.takerAssetAmount,
|
||||
defaultOrder.signature,
|
||||
);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const transactionHash = hashUtils.getTransactionHashHex(transaction);
|
||||
await mixins.assertValidSingleOrderApproval.callAsync(
|
||||
defaultOrder,
|
||||
transactionHash,
|
||||
transaction.signature,
|
||||
devConstants.ZERO_AMOUNT,
|
||||
devConstants.NULL_BYTES,
|
||||
[],
|
||||
[],
|
||||
{ from: approvalSignerAddress1 },
|
||||
);
|
||||
await mixins.assertValidTECApprovals.callAsync(transaction, transaction.signature, [], [], {
|
||||
from: approvalSignerAddress1,
|
||||
});
|
||||
});
|
||||
it(`Should revert: function=${fn}, caller=tx_signer, senderAddress=verifier, approval_sig=invalid, expiration=valid`, async () => {
|
||||
const data = (exchangeInterface as any)[fn].getABIEncodedTransactionData(
|
||||
defaultOrder,
|
||||
defaultOrder.takerAssetAmount,
|
||||
defaultOrder.signature,
|
||||
);
|
||||
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[approver1], expiration=[invalid]`, async () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.approvalSignature],
|
||||
{ from: approvalSignerAddress1 },
|
||||
);
|
||||
await mixins.assertValidTECApprovals.callAsync(
|
||||
transaction,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.approvalSignature],
|
||||
{ from: approvalSignerAddress1 },
|
||||
);
|
||||
});
|
||||
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[], expiration=[]`, async () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transaction.signature,
|
||||
[],
|
||||
[],
|
||||
{ from: approvalSignerAddress1 },
|
||||
);
|
||||
await mixins.assertValidTECApprovals.callAsync(transaction, transaction.signature, [], [], {
|
||||
from: approvalSignerAddress1,
|
||||
});
|
||||
});
|
||||
it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[invalid], expiration=[valid]`, async () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const transactionHash = hashUtils.getTransactionHashHex(transaction);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
@ -306,12 +242,12 @@ describe.only('Mixins tests', () => {
|
||||
4,
|
||||
)}FFFFFFFF${approval.approvalSignature.slice(12)}`;
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidSingleOrderApproval.callAsync(
|
||||
defaultOrder,
|
||||
transactionHash,
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transaction.signature,
|
||||
approvalExpirationTimeSeconds,
|
||||
approvalSignature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approvalSignature],
|
||||
{ from: transactionSignerAddress },
|
||||
),
|
||||
RevertReason.InvalidApprovalSignature,
|
||||
@ -327,24 +263,20 @@ describe.only('Mixins tests', () => {
|
||||
RevertReason.InvalidApprovalSignature,
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fn}, caller=tx_signer, senderAddress=verifier, approval_sig=approver1, expiration=invalid`, async () => {
|
||||
const data = (exchangeInterface as any)[fn].getABIEncodedTransactionData(
|
||||
defaultOrder,
|
||||
defaultOrder.takerAssetAmount,
|
||||
defaultOrder.signature,
|
||||
);
|
||||
it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1], expiration=[invalid]`, async () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const transactionHash = hashUtils.getTransactionHashHex(transaction);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(timeBuffer);
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidSingleOrderApproval.callAsync(
|
||||
defaultOrder,
|
||||
transactionHash,
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transaction.signature,
|
||||
approvalExpirationTimeSeconds,
|
||||
approval.approvalSignature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.approvalSignature],
|
||||
{ from: transactionSignerAddress },
|
||||
),
|
||||
RevertReason.ApprovalExpired,
|
||||
@ -360,21 +292,53 @@ describe.only('Mixins tests', () => {
|
||||
RevertReason.ApprovalExpired,
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fnName}, caller=approver2, senderAddress=[verifier], approval_sig=[approver1], expiration=[valid]`, async () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.approvalSignature],
|
||||
{ from: approvalSignerAddress2 },
|
||||
),
|
||||
RevertReason.InvalidSender,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTECApprovals.callAsync(
|
||||
transaction,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.approvalSignature],
|
||||
{ from: approvalSignerAddress2 },
|
||||
),
|
||||
RevertReason.InvalidSender,
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
describe('Batch order approvals', () => {
|
||||
for (const fn of [...constants.BATCH_FILL_FN_NAMES, ...constants.MARKET_FILL_FN_NAMES, 'matchOrders']) {
|
||||
it(`Should be successful: function=${fn} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => {
|
||||
for (const fnName of [
|
||||
...constants.BATCH_FILL_FN_NAMES,
|
||||
...constants.MARKET_FILL_FN_NAMES,
|
||||
constants.MATCH_ORDERS,
|
||||
]) {
|
||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => {
|
||||
const orders = [defaultOrder, defaultOrder];
|
||||
const data = encodeBatchOrderApproval(fn, orders, exchangeInterface);
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const transactionHash = hashUtils.getTransactionHashHex(transaction);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
await mixins.assertValidBatchOrderApproval.callAsync(
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionHash,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.approvalSignature],
|
||||
@ -388,20 +352,19 @@ describe.only('Mixins tests', () => {
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
});
|
||||
it(`Should be successful: function=${fn} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => {
|
||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => {
|
||||
const orders = [defaultOrder, defaultOrder].map(order => ({
|
||||
...order,
|
||||
senderAddress: devConstants.NULL_ADDRESS,
|
||||
}));
|
||||
const data = encodeBatchOrderApproval(fn, orders, exchangeInterface);
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const transactionHash = hashUtils.getTransactionHashHex(transaction);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
await mixins.assertValidBatchOrderApproval.callAsync(
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionHash,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.approvalSignature],
|
||||
@ -415,17 +378,16 @@ describe.only('Mixins tests', () => {
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
});
|
||||
it(`Should be successful: function=${fn} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[], expiration=[]`, async () => {
|
||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[], expiration=[]`, async () => {
|
||||
const orders = [defaultOrder, defaultOrder].map(order => ({
|
||||
...order,
|
||||
senderAddress: devConstants.NULL_ADDRESS,
|
||||
}));
|
||||
const data = encodeBatchOrderApproval(fn, orders, exchangeInterface);
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const transactionHash = hashUtils.getTransactionHashHex(transaction);
|
||||
await mixins.assertValidBatchOrderApproval.callAsync(
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionHash,
|
||||
transaction.signature,
|
||||
[],
|
||||
[],
|
||||
@ -435,17 +397,16 @@ describe.only('Mixins tests', () => {
|
||||
from: transactionSignerAddress,
|
||||
});
|
||||
});
|
||||
it(`Should be successful: function=${fn} caller=tx_signer, senderAddress=[verifier,null], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => {
|
||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,null], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => {
|
||||
const orders = [defaultOrder, { ...defaultOrder, senderAddress: devConstants.NULL_ADDRESS }];
|
||||
const data = encodeBatchOrderApproval(fn, orders, exchangeInterface);
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const transactionHash = hashUtils.getTransactionHashHex(transaction);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
await mixins.assertValidBatchOrderApproval.callAsync(
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionHash,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.approvalSignature],
|
||||
@ -459,18 +420,17 @@ describe.only('Mixins tests', () => {
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
});
|
||||
it(`Should be successful: function=${fn} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver1,approver2], expiration=[valid,valid]`, async () => {
|
||||
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver1,approver2], expiration=[valid,valid]`, async () => {
|
||||
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
||||
const data = encodeBatchOrderApproval(fn, orders, exchangeInterface);
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const transactionHash = hashUtils.getTransactionHashHex(transaction);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
|
||||
const approval1 = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
await mixins.assertValidBatchOrderApproval.callAsync(
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionHash,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
|
||||
[approval1.approvalSignature, approval2.approvalSignature],
|
||||
@ -484,14 +444,13 @@ describe.only('Mixins tests', () => {
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
});
|
||||
it(`Should be successful: function=${fn} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[], expiration=[]`, async () => {
|
||||
it(`Should be successful: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[], expiration=[]`, async () => {
|
||||
const orders = [defaultOrder, defaultOrder];
|
||||
const data = encodeBatchOrderApproval(fn, orders, exchangeInterface);
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const transactionHash = hashUtils.getTransactionHashHex(transaction);
|
||||
await mixins.assertValidBatchOrderApproval.callAsync(
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionHash,
|
||||
transaction.signature,
|
||||
[],
|
||||
[],
|
||||
@ -501,17 +460,16 @@ describe.only('Mixins tests', () => {
|
||||
from: approvalSignerAddress1,
|
||||
});
|
||||
});
|
||||
it(`Should be successful: function=${fn} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver2], expiration=[valid]`, async () => {
|
||||
it(`Should be successful: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver2], expiration=[valid]`, async () => {
|
||||
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
||||
const data = encodeBatchOrderApproval(fn, orders, exchangeInterface);
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const transactionHash = hashUtils.getTransactionHashHex(transaction);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
|
||||
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
await mixins.assertValidBatchOrderApproval.callAsync(
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionHash,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval2.approvalSignature],
|
||||
@ -525,7 +483,243 @@ describe.only('Mixins tests', () => {
|
||||
{ from: approvalSignerAddress1 },
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[], expiration=[]`, async () => {
|
||||
const orders = [defaultOrder, defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transaction.signature,
|
||||
[],
|
||||
[],
|
||||
{ from: transactionSignerAddress },
|
||||
),
|
||||
RevertReason.InvalidApprovalSignature,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTECApprovals.callAsync(transaction, transaction.signature, [], [], {
|
||||
from: transactionSignerAddress,
|
||||
}),
|
||||
RevertReason.InvalidApprovalSignature,
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[invalid], expiration=[valid]`, async () => {
|
||||
const orders = [defaultOrder, defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
|
||||
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
const approvalSignature = `${approval.approvalSignature.slice(
|
||||
0,
|
||||
4,
|
||||
)}FFFFFFFF${approval.approvalSignature.slice(12)}`;
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approvalSignature],
|
||||
{ from: transactionSignerAddress },
|
||||
),
|
||||
RevertReason.InvalidApprovalSignature,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTECApprovals.callAsync(
|
||||
transaction,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approvalSignature],
|
||||
{ from: transactionSignerAddress },
|
||||
),
|
||||
RevertReason.InvalidApprovalSignature,
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid,invalid], expiration=[valid,valid]`, async () => {
|
||||
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
|
||||
const approval1 = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
const approvalSignature2 = `${approval2.approvalSignature.slice(
|
||||
0,
|
||||
4,
|
||||
)}FFFFFFFF${approval2.approvalSignature.slice(12)}`;
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
|
||||
[approval1.approvalSignature, approvalSignature2],
|
||||
{ from: transactionSignerAddress },
|
||||
),
|
||||
RevertReason.InvalidApprovalSignature,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTECApprovals.callAsync(
|
||||
transaction,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
|
||||
[approval1.approvalSignature, approvalSignature2],
|
||||
{ from: transactionSignerAddress },
|
||||
),
|
||||
RevertReason.InvalidApprovalSignature,
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[invalid], expiration=[valid]`, async () => {
|
||||
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
|
||||
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
const approvalSignature2 = `${approval2.approvalSignature.slice(
|
||||
0,
|
||||
4,
|
||||
)}FFFFFFFF${approval2.approvalSignature.slice(12)}`;
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approvalSignature2],
|
||||
{ from: approvalSignerAddress1 },
|
||||
),
|
||||
RevertReason.InvalidApprovalSignature,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTECApprovals.callAsync(
|
||||
transaction,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approvalSignature2],
|
||||
{ from: approvalSignerAddress1 },
|
||||
),
|
||||
RevertReason.InvalidApprovalSignature,
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid,valid], expiration=[valid,invalid]`, async () => {
|
||||
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds1 = new BigNumber(currentTimestamp).plus(timeBuffer);
|
||||
const approvalExpirationTimeSeconds2 = new BigNumber(currentTimestamp).minus(timeBuffer);
|
||||
const approval1 = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds1);
|
||||
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds2);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds1, approvalExpirationTimeSeconds2],
|
||||
[approval1.approvalSignature, approval2.approvalSignature],
|
||||
{ from: transactionSignerAddress },
|
||||
),
|
||||
RevertReason.ApprovalExpired,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTECApprovals.callAsync(
|
||||
transaction,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds1, approvalExpirationTimeSeconds2],
|
||||
[approval1.approvalSignature, approval2.approvalSignature],
|
||||
{ from: transactionSignerAddress },
|
||||
),
|
||||
RevertReason.ApprovalExpired,
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid], expiration=[invalid]`, async () => {
|
||||
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(timeBuffer);
|
||||
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval2.approvalSignature],
|
||||
{ from: approvalSignerAddress1 },
|
||||
),
|
||||
RevertReason.ApprovalExpired,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTECApprovals.callAsync(
|
||||
transaction,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval2.approvalSignature],
|
||||
{ from: approvalSignerAddress1 },
|
||||
),
|
||||
RevertReason.ApprovalExpired,
|
||||
);
|
||||
});
|
||||
it(`Should revert: function=${fnName} caller=approver2, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[valid], expiration=[valid]`, async () => {
|
||||
const orders = [defaultOrder, defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
|
||||
const approval1 = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval1.approvalSignature],
|
||||
{ from: approvalSignerAddress2 },
|
||||
),
|
||||
RevertReason.InvalidSender,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTECApprovals.callAsync(
|
||||
transaction,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval1.approvalSignature],
|
||||
{ from: approvalSignerAddress2 },
|
||||
),
|
||||
RevertReason.InvalidSender,
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
describe('assertValidTECApprovals', () => {});
|
||||
describe('cancels', () => {
|
||||
it('should allow the tx signer to call `cancelOrders` without approval', async () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDERS, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
await mixins.assertValidTECApprovals.callAsync(transaction, transaction.signature, [], [], {
|
||||
from: transactionSignerAddress,
|
||||
});
|
||||
});
|
||||
it('should allow the tx signer to call `batchCancelOrders` without approval', async () => {
|
||||
const orders = [defaultOrder, defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.BATCH_CANCEL_ORDERS, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
await mixins.assertValidTECApprovals.callAsync(transaction, transaction.signature, [], [], {
|
||||
from: transactionSignerAddress,
|
||||
});
|
||||
});
|
||||
it('should allow the tx signer to call `cancelOrdersUpTo` without approval', async () => {
|
||||
const orders: SignedOrder[] = [];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDERS_UP_TO, orders);
|
||||
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||
await mixins.assertValidTECApprovals.callAsync(transaction, transaction.signature, [], [], {
|
||||
from: transactionSignerAddress,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -12,4 +12,8 @@ export const constants = {
|
||||
SINGLE_FILL_FN_NAMES: ['fillOrder', 'fillOrKillOrder', 'fillOrderNoThrow'],
|
||||
BATCH_FILL_FN_NAMES: ['batchFillOrders', 'batchFillOrKillOrders', 'batchFillOrdersNoThrow'],
|
||||
MARKET_FILL_FN_NAMES: ['marketBuyOrders', 'marketBuyOrdersNoThrow', 'marketSellOrders', 'marketSellOrdersNoThrow'],
|
||||
MATCH_ORDERS: 'matchOrders',
|
||||
CANCEL_ORDERS: 'cancelOrders',
|
||||
BATCH_CANCEL_ORDERS: 'batchCancelOrders',
|
||||
CANCEL_ORDERS_UP_TO: 'cancelOrdersUpTo',
|
||||
};
|
||||
|
51
contracts/tec/test/utils/exchange_data_encoder.ts
Normal file
51
contracts/tec/test/utils/exchange_data_encoder.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { artifacts, IExchangeContract } from '@0x/contracts-exchange';
|
||||
import { constants as devConstants, provider } from '@0x/contracts-test-utils';
|
||||
import { SignedOrder } from '@0x/types';
|
||||
|
||||
import { constants } from './index';
|
||||
|
||||
export const exchangeDataEncoder = {
|
||||
encodeOrdersToExchangeData(fnName: string, orders: SignedOrder[]): string {
|
||||
const exchangeInstance = new IExchangeContract(
|
||||
artifacts.IExchange.compilerOutput.abi,
|
||||
devConstants.NULL_ADDRESS,
|
||||
provider,
|
||||
);
|
||||
let data;
|
||||
if (constants.SINGLE_FILL_FN_NAMES.indexOf(fnName) !== -1) {
|
||||
data = (exchangeInstance as any)[fnName].getABIEncodedTransactionData(
|
||||
orders[0],
|
||||
orders[0].takerAssetAmount,
|
||||
orders[0].signature,
|
||||
);
|
||||
} else if (constants.BATCH_FILL_FN_NAMES.indexOf(fnName) !== -1) {
|
||||
data = (exchangeInstance as any)[fnName].getABIEncodedTransactionData(
|
||||
orders,
|
||||
orders.map(order => order.takerAssetAmount),
|
||||
orders.map(order => order.signature),
|
||||
);
|
||||
} else if (constants.MARKET_FILL_FN_NAMES.indexOf(fnName) !== -1) {
|
||||
data = (exchangeInstance as any)[fnName].getABIEncodedTransactionData(
|
||||
orders,
|
||||
orders[0].takerAssetAmount,
|
||||
orders.map(order => order.signature),
|
||||
);
|
||||
} else if (fnName === constants.MATCH_ORDERS) {
|
||||
data = exchangeInstance.matchOrders.getABIEncodedTransactionData(
|
||||
orders[0],
|
||||
orders[1],
|
||||
orders[0].signature,
|
||||
orders[1].signature,
|
||||
);
|
||||
} else if (fnName === constants.CANCEL_ORDERS) {
|
||||
data = exchangeInstance.cancelOrder.getABIEncodedTransactionData(orders[0]);
|
||||
} else if (fnName === constants.BATCH_CANCEL_ORDERS) {
|
||||
data = exchangeInstance.batchCancelOrders.getABIEncodedTransactionData(orders);
|
||||
} else if (fnName === constants.CANCEL_ORDERS_UP_TO) {
|
||||
data = exchangeInstance.cancelOrdersUpTo.getABIEncodedTransactionData(devConstants.ZERO_AMOUNT);
|
||||
} else {
|
||||
throw new Error(`Error: ${fnName} not a supported function`);
|
||||
}
|
||||
return data;
|
||||
},
|
||||
};
|
@ -3,4 +3,5 @@ export { signingUtils } from './signing_utils';
|
||||
export { TECTransactionFactory } from './tec_transaction_factory';
|
||||
export { ApprovalFactory } from './approval_factory';
|
||||
export { constants } from './constants';
|
||||
export { exchangeDataEncoder } from './exchange_data_encoder';
|
||||
export * from './types';
|
||||
|
Loading…
x
Reference in New Issue
Block a user