Refactor integrations directory structure; move core.ts, balance stores, and FillOrderWrapper to integrations
This commit is contained in:
parent
bdca84fe72
commit
7f4cbba076
@ -1,37 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibEIP712ExchangeDomain.sol";
|
||||
import "../src/MixinSignatureValidator.sol";
|
||||
import "../src/MixinTransactions.sol";
|
||||
|
||||
|
||||
contract TestSignatureValidator is
|
||||
LibEIP712ExchangeDomain,
|
||||
MixinSignatureValidator
|
||||
{
|
||||
|
||||
// solhint-disable no-empty-blocks
|
||||
constructor (uint256 chainId)
|
||||
public
|
||||
LibEIP712ExchangeDomain(chainId, address(0))
|
||||
{}
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
export * from './artifacts';
|
||||
export * from './wrappers';
|
||||
export import ExchangeRevertErrors = require('./revert_errors');
|
||||
export { BlockchainBalanceStore } from './balance_stores/blockchain_balance_store';
|
||||
export { LocalBalanceStore } from './balance_stores/local_balance_store';
|
||||
export { exchangeDataEncoder } from './exchange_data_encoder';
|
||||
|
@ -37,7 +37,6 @@ import * as TestLibExchangeRichErrorDecoder from '../test/generated-artifacts/Te
|
||||
import * as TestProtocolFeeCollector from '../test/generated-artifacts/TestProtocolFeeCollector.json';
|
||||
import * as TestProtocolFees from '../test/generated-artifacts/TestProtocolFees.json';
|
||||
import * as TestProtocolFeesReceiver from '../test/generated-artifacts/TestProtocolFeesReceiver.json';
|
||||
import * as TestSignatureValidator from '../test/generated-artifacts/TestSignatureValidator.json';
|
||||
import * as TestTransactions from '../test/generated-artifacts/TestTransactions.json';
|
||||
import * as TestValidatorWallet from '../test/generated-artifacts/TestValidatorWallet.json';
|
||||
import * as TestWrapperFunctions from '../test/generated-artifacts/TestWrapperFunctions.json';
|
||||
@ -74,7 +73,6 @@ export const artifacts = {
|
||||
TestProtocolFeeCollector: TestProtocolFeeCollector as ContractArtifact,
|
||||
TestProtocolFees: TestProtocolFees as ContractArtifact,
|
||||
TestProtocolFeesReceiver: TestProtocolFeesReceiver as ContractArtifact,
|
||||
TestSignatureValidator: TestSignatureValidator as ContractArtifact,
|
||||
TestTransactions: TestTransactions as ContractArtifact,
|
||||
TestValidatorWallet: TestValidatorWallet as ContractArtifact,
|
||||
TestWrapperFunctions: TestWrapperFunctions as ContractArtifact,
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
|
||||
import { DevUtilsContract } from '@0x/contracts-dev-utils';
|
||||
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
||||
import {
|
||||
blockchainTests,
|
||||
constants,
|
||||
@ -12,6 +14,7 @@ import {
|
||||
randomAddress,
|
||||
TransactionFactory,
|
||||
transactionHashUtils,
|
||||
ValidatorWalletAction,
|
||||
} from '@0x/contracts-test-utils';
|
||||
import { SignatureType, SignedOrder, SignedZeroExTransaction } from '@0x/types';
|
||||
import { BigNumber, StringRevertError } from '@0x/utils';
|
||||
@ -22,33 +25,35 @@ import ExchangeRevertErrors = require('../src/revert_errors');
|
||||
|
||||
import { artifacts } from './artifacts';
|
||||
import {
|
||||
ExchangeContract,
|
||||
ExchangeSignatureValidatorApprovalEventArgs,
|
||||
IEIP1271DataContract,
|
||||
TestSignatureValidatorContract,
|
||||
TestSignatureValidatorSignatureValidatorApprovalEventArgs,
|
||||
TestValidatorWalletContract,
|
||||
} from './wrappers';
|
||||
|
||||
import { ValidatorWalletAction } from './utils/constants';
|
||||
|
||||
// tslint:disable:no-unnecessary-type-assertion
|
||||
blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
let chainId: number;
|
||||
let signatureValidator: TestSignatureValidatorContract;
|
||||
let exchange: ExchangeContract;
|
||||
let validatorWallet: TestValidatorWalletContract;
|
||||
let validatorWalletRevertReason: string;
|
||||
let signerAddress: string;
|
||||
let signerPrivateKey: Buffer;
|
||||
let notSignerAddress: string;
|
||||
let accounts: string[];
|
||||
let owner: string;
|
||||
let makerAddress: string;
|
||||
let takerAddress: string;
|
||||
let feeRecipientAddress: string;
|
||||
|
||||
const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, env.provider, env.txDefaults);
|
||||
const eip1271Data = new IEIP1271DataContract(constants.NULL_ADDRESS, env.provider, env.txDefaults);
|
||||
before(async () => {
|
||||
chainId = await env.getChainIdAsync();
|
||||
const accounts = await env.getAccountAddressesAsync();
|
||||
signerAddress = accounts[0];
|
||||
notSignerAddress = accounts[1];
|
||||
signatureValidator = await TestSignatureValidatorContract.deployFrom0xArtifactAsync(
|
||||
artifacts.TestSignatureValidator,
|
||||
accounts = await env.getAccountAddressesAsync();
|
||||
[owner, signerAddress, notSignerAddress, makerAddress, takerAddress, feeRecipientAddress] = accounts;
|
||||
exchange = await ExchangeContract.deployFrom0xArtifactAsync(
|
||||
artifacts.Exchange,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
{},
|
||||
@ -59,14 +64,14 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
{},
|
||||
signatureValidator.address,
|
||||
exchange.address,
|
||||
);
|
||||
validatorWalletRevertReason = await validatorWallet.REVERT_REASON().callAsync();
|
||||
|
||||
// Approve the validator for both signers.
|
||||
await Promise.all(
|
||||
[signerAddress, notSignerAddress].map(async (addr: string) => {
|
||||
return signatureValidator
|
||||
return exchange
|
||||
.setSignatureValidatorApproval(validatorWallet.address, true)
|
||||
.awaitTransactionSuccessAsync({ from: addr });
|
||||
}),
|
||||
@ -300,7 +305,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
it('should return true when SignatureType=Presigned and signer has presigned hash', async () => {
|
||||
const hashHex = getCurrentHashHex();
|
||||
// Presign the hash
|
||||
await signatureValidator.preSign(hashHex).awaitTransactionSuccessAsync({ from: signerAddress });
|
||||
await exchange.preSign(hashHex).awaitTransactionSuccessAsync({ from: signerAddress });
|
||||
// Validate presigned signature
|
||||
const signatureHex = hexConcat(SignatureType.PreSigned);
|
||||
const isValidSignature = await validateAsync(hashHex, signerAddress, signatureHex);
|
||||
@ -338,7 +343,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
.prepare(_hashHex, validatorAction, expectedSignatureHashHex)
|
||||
.awaitTransactionSuccessAsync();
|
||||
}
|
||||
return signatureValidator.isValidHashSignature(_hashHex, _signerAddress, signatureHex).callAsync();
|
||||
return exchange.isValidHashSignature(_hashHex, _signerAddress, signatureHex).callAsync();
|
||||
};
|
||||
|
||||
it('should revert when signerAddress == 0', async () => {
|
||||
@ -387,9 +392,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
const trezorSignatureType = ethUtil.toBuffer(`0x${SignatureType.EthSign}`);
|
||||
const signature = Buffer.concat([v, r, s, trezorSignatureType]);
|
||||
const signatureHex = ethUtil.bufferToHex(signature);
|
||||
const isValidSignature = await signatureValidator
|
||||
.isValidHashSignature(messageHash, signer, signatureHex)
|
||||
.callAsync();
|
||||
const isValidSignature = await exchange.isValidHashSignature(messageHash, signer, signatureHex).callAsync();
|
||||
expect(isValidSignature).to.be.true();
|
||||
});
|
||||
|
||||
@ -403,9 +406,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
const trezorSignatureType = ethUtil.toBuffer(`0x${SignatureType.EthSign}`);
|
||||
const signature = Buffer.concat([v, r, s, trezorSignatureType]);
|
||||
const signatureHex = ethUtil.bufferToHex(signature);
|
||||
const isValidSignature = await signatureValidator
|
||||
.isValidHashSignature(messageHash, signer, signatureHex)
|
||||
.callAsync();
|
||||
const isValidSignature = await exchange.isValidHashSignature(messageHash, signer, signatureHex).callAsync();
|
||||
expect(isValidSignature).to.be.true();
|
||||
});
|
||||
|
||||
@ -417,10 +418,9 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
let signedOrder: SignedOrder;
|
||||
|
||||
before(async () => {
|
||||
const makerAddress = signerAddress;
|
||||
const defaultOrderParams = {
|
||||
...constants.STATIC_ORDER_PARAMS,
|
||||
makerAddress,
|
||||
makerAddress: signerAddress,
|
||||
feeRecipientAddress: randomAddress(),
|
||||
makerAssetData: await devUtils.encodeERC20AssetData(randomAddress()).callAsync(),
|
||||
takerAssetData: await devUtils.encodeERC20AssetData(randomAddress()).callAsync(),
|
||||
@ -428,7 +428,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
takerFeeAssetData: await devUtils.encodeERC20AssetData(randomAddress()).callAsync(),
|
||||
makerFee: constants.ZERO_AMOUNT,
|
||||
takerFee: constants.ZERO_AMOUNT,
|
||||
exchangeAddress: signatureValidator.address,
|
||||
exchangeAddress: exchange.address,
|
||||
chainId,
|
||||
};
|
||||
orderFactory = new OrderFactory(signerPrivateKey, defaultOrderParams);
|
||||
@ -454,7 +454,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
.prepare(orderHashHex, validatorAction, expectedSignatureHashHex)
|
||||
.awaitTransactionSuccessAsync();
|
||||
}
|
||||
return signatureValidator.isValidOrderSignature(order, signatureHex).callAsync();
|
||||
return exchange.isValidOrderSignature(order, signatureHex).callAsync();
|
||||
};
|
||||
|
||||
it('should revert when signerAddress == 0', async () => {
|
||||
@ -470,7 +470,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
constants.NULL_ADDRESS,
|
||||
signatureHex,
|
||||
);
|
||||
const tx = signatureValidator.isValidOrderSignature(nullMakerOrder, signatureHex).callAsync();
|
||||
const tx = exchange.isValidOrderSignature(nullMakerOrder, signatureHex).callAsync();
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
@ -566,7 +566,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
|
||||
it('should revert when SignatureType=Validator and signature is shorter than 21 bytes', async () => {
|
||||
// Set approval of signature validator to false
|
||||
await signatureValidator
|
||||
await exchange
|
||||
.setSignatureValidatorApproval(validatorWallet.address, false)
|
||||
.awaitTransactionSuccessAsync({ from: signedOrder.makerAddress });
|
||||
// Doesn't have to contain a real signature since our wallet contract
|
||||
@ -585,7 +585,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
|
||||
it('should revert when SignatureType=Validator, signature is valid and validator is not approved', async () => {
|
||||
// Set approval of signature validator to false
|
||||
await signatureValidator
|
||||
await exchange
|
||||
.setSignatureValidatorApproval(validatorWallet.address, false)
|
||||
.awaitTransactionSuccessAsync({ from: signedOrder.makerAddress });
|
||||
// Doesn't have to contain a real signature since our wallet contract
|
||||
@ -706,7 +706,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
signatureHex,
|
||||
constants.NULL_BYTES,
|
||||
);
|
||||
const tx = signatureValidator.isValidOrderSignature(signedOrder, signatureHex).callAsync();
|
||||
const tx = exchange.isValidOrderSignature(signedOrder, signatureHex).callAsync();
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
@ -721,16 +721,16 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
constants.NULL_BYTES,
|
||||
);
|
||||
// Register an EOA as a validator.
|
||||
await signatureValidator
|
||||
await exchange
|
||||
.setSignatureValidatorApproval(notSignerAddress, true)
|
||||
.awaitTransactionSuccessAsync({ from: signerAddress });
|
||||
const tx = signatureValidator.isValidOrderSignature(signedOrder, signatureHex).callAsync();
|
||||
const tx = exchange.isValidOrderSignature(signedOrder, signatureHex).callAsync();
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
// Run hash-only signature type tests as well.
|
||||
const validateOrderHashAsync = async (
|
||||
hashHex: string,
|
||||
_hashHex: string,
|
||||
_signerAddress: string,
|
||||
signatureHex: string,
|
||||
validatorAction?: ValidatorWalletAction,
|
||||
@ -751,7 +751,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
const TRANSACTION_DATA_LENGTH = 100;
|
||||
|
||||
before(async () => {
|
||||
transactionFactory = new TransactionFactory(signerPrivateKey, signatureValidator.address, chainId);
|
||||
transactionFactory = new TransactionFactory(signerPrivateKey, exchange.address, chainId);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
@ -778,7 +778,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
.prepare(transactionHashHex, validatorAction, expectedSignatureHashHex)
|
||||
.awaitTransactionSuccessAsync();
|
||||
}
|
||||
return signatureValidator.isValidTransactionSignature(transaction, signatureHex).callAsync();
|
||||
return exchange.isValidTransactionSignature(transaction, signatureHex).callAsync();
|
||||
};
|
||||
|
||||
it('should revert when signerAddress == 0', async () => {
|
||||
@ -794,7 +794,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
constants.NULL_ADDRESS,
|
||||
signatureHex,
|
||||
);
|
||||
const tx = signatureValidator.isValidTransactionSignature(nullSignerTransaction, signatureHex).callAsync();
|
||||
const tx = exchange.isValidTransactionSignature(nullSignerTransaction, signatureHex).callAsync();
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
@ -841,7 +841,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
|
||||
it('should revert when SignatureType=Validator and signature is shorter than 21 bytes', async () => {
|
||||
// Set approval of signature validator to false
|
||||
await signatureValidator
|
||||
await exchange
|
||||
.setSignatureValidatorApproval(validatorWallet.address, false)
|
||||
.awaitTransactionSuccessAsync({ from: signedTransaction.signerAddress });
|
||||
// Doesn't have to contain a real signature since our wallet contract
|
||||
@ -920,7 +920,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
|
||||
it('should revert when SignatureType=Validator, signature is valid and validator is not approved', async () => {
|
||||
// Set approval of signature validator to false
|
||||
await signatureValidator
|
||||
await exchange
|
||||
.setSignatureValidatorApproval(validatorWallet.address, false)
|
||||
.awaitTransactionSuccessAsync({ from: signedTransaction.signerAddress });
|
||||
// Doesn't have to contain a real signature since our wallet contract
|
||||
@ -1055,7 +1055,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
signatureHex,
|
||||
constants.NULL_BYTES,
|
||||
);
|
||||
const tx = signatureValidator.isValidTransactionSignature(signedTransaction, signatureHex).callAsync();
|
||||
const tx = exchange.isValidTransactionSignature(signedTransaction, signatureHex).callAsync();
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
@ -1072,16 +1072,16 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
constants.NULL_BYTES,
|
||||
);
|
||||
// Register an EOA as a validator.
|
||||
await signatureValidator
|
||||
await exchange
|
||||
.setSignatureValidatorApproval(notSignerAddress, true)
|
||||
.awaitTransactionSuccessAsync({ from: signerAddress });
|
||||
const tx = signatureValidator.isValidTransactionSignature(signedTransaction, signatureHex).callAsync();
|
||||
const tx = exchange.isValidTransactionSignature(signedTransaction, signatureHex).callAsync();
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
// Run hash-only signature type tests as well.
|
||||
const validateOrderHashAsync = async (
|
||||
hashHex: string,
|
||||
_hashHex: string,
|
||||
_signerAddress: string,
|
||||
signatureHex: string,
|
||||
validatorAction?: ValidatorWalletAction,
|
||||
@ -1105,14 +1105,14 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
|
||||
it('should emit a SignatureValidatorApprovalSet with correct args when a validator is approved', async () => {
|
||||
const approval = true;
|
||||
const res = await signatureValidator
|
||||
const res = await exchange
|
||||
.setSignatureValidatorApproval(validatorWallet.address, approval)
|
||||
.awaitTransactionSuccessAsync({
|
||||
from: signerAddress,
|
||||
});
|
||||
expect(res.logs.length).to.equal(1);
|
||||
const log = signatureValidatorLogDecoder.decodeLogOrThrow(res.logs[0]) as LogWithDecodedArgs<
|
||||
TestSignatureValidatorSignatureValidatorApprovalEventArgs
|
||||
ExchangeSignatureValidatorApprovalEventArgs
|
||||
>;
|
||||
const logArgs = log.args;
|
||||
expect(logArgs.signerAddress).to.equal(signerAddress);
|
||||
@ -1121,14 +1121,14 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
});
|
||||
it('should emit a SignatureValidatorApprovalSet with correct args when a validator is disapproved', async () => {
|
||||
const approval = false;
|
||||
const res = await signatureValidator
|
||||
const res = await exchange
|
||||
.setSignatureValidatorApproval(validatorWallet.address, approval)
|
||||
.awaitTransactionSuccessAsync({
|
||||
from: signerAddress,
|
||||
});
|
||||
expect(res.logs.length).to.equal(1);
|
||||
const log = signatureValidatorLogDecoder.decodeLogOrThrow(res.logs[0]) as LogWithDecodedArgs<
|
||||
TestSignatureValidatorSignatureValidatorApprovalEventArgs
|
||||
ExchangeSignatureValidatorApprovalEventArgs
|
||||
>;
|
||||
const logArgs = log.args;
|
||||
expect(logArgs.signerAddress).to.equal(signerAddress);
|
||||
@ -1136,6 +1136,153 @@ blockchainTests.resets('MixinSignatureValidator', env => {
|
||||
expect(logArgs.isApproved).to.equal(approval);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fillOrder integration tests', () => {
|
||||
let erc20Wrapper: ERC20Wrapper;
|
||||
let erc20Proxy: ERC20ProxyContract;
|
||||
let erc20TokenA: DummyERC20TokenContract;
|
||||
let erc20TokenB: DummyERC20TokenContract;
|
||||
let feeToken: DummyERC20TokenContract;
|
||||
let orderFactory: OrderFactory;
|
||||
let signedOrder: SignedOrder;
|
||||
|
||||
before(async () => {
|
||||
// Deploy ERC20 proxy and tokens
|
||||
erc20Wrapper = new ERC20Wrapper(env.provider, accounts, owner);
|
||||
erc20Proxy = await erc20Wrapper.deployProxyAsync();
|
||||
const numDummyErc20ToDeploy = 3;
|
||||
[erc20TokenA, erc20TokenB, feeToken] = await erc20Wrapper.deployDummyTokensAsync(
|
||||
numDummyErc20ToDeploy,
|
||||
constants.DUMMY_TOKEN_DECIMALS,
|
||||
);
|
||||
await erc20Wrapper.setBalancesAndAllowancesAsync();
|
||||
|
||||
// Configure ERC20 proxy and exchange
|
||||
await erc20Proxy.addAuthorizedAddress(exchange.address).awaitTransactionSuccessAsync({ from: owner });
|
||||
await exchange.registerAssetProxy(erc20Proxy.address).awaitTransactionSuccessAsync({ from: owner });
|
||||
|
||||
// Configure order defaults
|
||||
const defaultMakerAssetAddress = erc20TokenA.address;
|
||||
const defaultTakerAssetAddress = erc20TokenB.address;
|
||||
const defaultFeeAssetAddress = feeToken.address;
|
||||
const defaultOrderParams = {
|
||||
...constants.STATIC_ORDER_PARAMS,
|
||||
makerAddress,
|
||||
feeRecipientAddress,
|
||||
makerAssetData: await devUtils.encodeERC20AssetData(defaultMakerAssetAddress).callAsync(),
|
||||
takerAssetData: await devUtils.encodeERC20AssetData(defaultTakerAssetAddress).callAsync(),
|
||||
makerFeeAssetData: await devUtils.encodeERC20AssetData(defaultFeeAssetAddress).callAsync(),
|
||||
takerFeeAssetData: await devUtils.encodeERC20AssetData(defaultFeeAssetAddress).callAsync(),
|
||||
exchangeAddress: exchange.address,
|
||||
chainId,
|
||||
};
|
||||
const privateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)];
|
||||
orderFactory = new OrderFactory(privateKey, defaultOrderParams);
|
||||
|
||||
// Approve the ERC20 proxy with the test validator wallet.
|
||||
await validatorWallet
|
||||
.approveERC20(erc20TokenA.address, erc20Proxy.address, constants.INITIAL_ERC20_ALLOWANCE)
|
||||
.awaitTransactionSuccessAsync();
|
||||
// Mint some ERC20 tokens to the test validator wallet.
|
||||
await erc20TokenA
|
||||
.setBalance(validatorWallet.address, constants.INITIAL_ERC20_BALANCE)
|
||||
.awaitTransactionSuccessAsync();
|
||||
// Approve the validator.
|
||||
await exchange.setSignatureValidatorApproval(validatorWallet.address, true).awaitTransactionSuccessAsync({
|
||||
from: makerAddress,
|
||||
});
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerFee: constants.ZERO_AMOUNT,
|
||||
takerFee: constants.ZERO_AMOUNT,
|
||||
});
|
||||
});
|
||||
|
||||
it('should revert if `Validator` signature type rejects during a second fill', async () => {
|
||||
const signatureHex = hexConcat(validatorWallet.address, SignatureType.Validator);
|
||||
signedOrder.signature = signatureHex;
|
||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
// Allow the signature check for the first fill.
|
||||
await validatorWallet
|
||||
.prepare(orderHashHex, ValidatorWalletAction.Accept, constants.NULL_BYTES)
|
||||
.awaitTransactionSuccessAsync();
|
||||
const fillAmount = signedOrder.takerAssetAmount.div(10);
|
||||
await exchange.fillOrder(signedOrder, fillAmount, signedOrder.signature).awaitTransactionSuccessAsync({
|
||||
from: takerAddress,
|
||||
});
|
||||
// Reject the signature check for the second fill.
|
||||
await validatorWallet
|
||||
.prepare(orderHashHex, ValidatorWalletAction.Reject, constants.NULL_BYTES)
|
||||
.awaitTransactionSuccessAsync();
|
||||
const tx = exchange.fillOrder(signedOrder, fillAmount, signedOrder.signature).awaitTransactionSuccessAsync({
|
||||
from: takerAddress,
|
||||
});
|
||||
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||
ExchangeRevertErrors.SignatureErrorCode.BadOrderSignature,
|
||||
orderHashHex,
|
||||
signedOrder.makerAddress,
|
||||
signedOrder.signature,
|
||||
);
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('should revert if `Wallet` signature type rejects during a second fill', async () => {
|
||||
const signatureHex = hexConcat(SignatureType.Wallet);
|
||||
signedOrder.makerAddress = validatorWallet.address;
|
||||
signedOrder.signature = signatureHex;
|
||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
// Allow the signature check for the first fill.
|
||||
await validatorWallet
|
||||
.prepare(orderHashHex, ValidatorWalletAction.Accept, constants.NULL_BYTES)
|
||||
.awaitTransactionSuccessAsync();
|
||||
const fillAmount = signedOrder.takerAssetAmount.div(10);
|
||||
await exchange.fillOrder(signedOrder, fillAmount, signedOrder.signature).awaitTransactionSuccessAsync({
|
||||
from: takerAddress,
|
||||
});
|
||||
// Reject the signature check for the second fill.
|
||||
await validatorWallet
|
||||
.prepare(orderHashHex, ValidatorWalletAction.Reject, constants.NULL_BYTES)
|
||||
.awaitTransactionSuccessAsync();
|
||||
const tx = exchange.fillOrder(signedOrder, fillAmount, signedOrder.signature).awaitTransactionSuccessAsync({
|
||||
from: takerAddress,
|
||||
});
|
||||
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||
ExchangeRevertErrors.SignatureErrorCode.BadOrderSignature,
|
||||
orderHashHex,
|
||||
signedOrder.makerAddress,
|
||||
signedOrder.signature,
|
||||
);
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('should revert if `EIP1271Wallet` signature type rejects during a second fill', async () => {
|
||||
const signatureHex = hexConcat(SignatureType.EIP1271Wallet);
|
||||
signedOrder.makerAddress = validatorWallet.address;
|
||||
signedOrder.signature = signatureHex;
|
||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
// Allow the signature check for the first fill.
|
||||
await validatorWallet
|
||||
.prepare(orderHashHex, ValidatorWalletAction.Accept, constants.NULL_BYTES)
|
||||
.awaitTransactionSuccessAsync();
|
||||
const fillAmount = signedOrder.takerAssetAmount.div(10);
|
||||
await exchange.fillOrder(signedOrder, fillAmount, signedOrder.signature).awaitTransactionSuccessAsync({
|
||||
from: takerAddress,
|
||||
});
|
||||
// Reject the signature check for the second fill.
|
||||
await validatorWallet
|
||||
.prepare(orderHashHex, ValidatorWalletAction.Reject, constants.NULL_BYTES)
|
||||
.awaitTransactionSuccessAsync();
|
||||
const tx = exchange.fillOrder(signedOrder, fillAmount, signedOrder.signature).awaitTransactionSuccessAsync({
|
||||
from: takerAddress,
|
||||
});
|
||||
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||
ExchangeRevertErrors.SignatureErrorCode.BadOrderSignature,
|
||||
orderHashHex,
|
||||
signedOrder.makerAddress,
|
||||
signedOrder.signature,
|
||||
);
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
});
|
||||
});
|
||||
// tslint:disable:max-file-line-count
|
||||
// tslint:enable:no-unnecessary-type-assertion
|
||||
|
@ -14,14 +14,3 @@ export const constants = {
|
||||
ExchangeFunctionName.DetachProtocolFeeCollector,
|
||||
],
|
||||
};
|
||||
|
||||
export enum ValidatorWalletAction {
|
||||
Reject = 0,
|
||||
Accept = 1,
|
||||
Revert = 2,
|
||||
UpdateState = 3,
|
||||
MatchSignatureHash = 4,
|
||||
ReturnTrue = 5,
|
||||
ReturnNothing = 6,
|
||||
NTypes = 7,
|
||||
}
|
||||
|
@ -35,7 +35,6 @@ export * from '../test/generated-wrappers/test_lib_exchange_rich_error_decoder';
|
||||
export * from '../test/generated-wrappers/test_protocol_fee_collector';
|
||||
export * from '../test/generated-wrappers/test_protocol_fees';
|
||||
export * from '../test/generated-wrappers/test_protocol_fees_receiver';
|
||||
export * from '../test/generated-wrappers/test_signature_validator';
|
||||
export * from '../test/generated-wrappers/test_transactions';
|
||||
export * from '../test/generated-wrappers/test_validator_wallet';
|
||||
export * from '../test/generated-wrappers/test_wrapper_functions';
|
||||
|
@ -37,7 +37,6 @@
|
||||
"test/generated-artifacts/TestProtocolFeeCollector.json",
|
||||
"test/generated-artifacts/TestProtocolFees.json",
|
||||
"test/generated-artifacts/TestProtocolFeesReceiver.json",
|
||||
"test/generated-artifacts/TestSignatureValidator.json",
|
||||
"test/generated-artifacts/TestTransactions.json",
|
||||
"test/generated-artifacts/TestValidatorWallet.json",
|
||||
"test/generated-artifacts/TestWrapperFunctions.json"
|
||||
|
@ -70,6 +70,7 @@
|
||||
"chai-as-promised": "^7.1.0",
|
||||
"chai-bignumber": "^3.0.0",
|
||||
"dirty-chai": "^2.0.1",
|
||||
"js-combinatorics": "^0.5.3",
|
||||
"make-promises-safe": "^1.1.0",
|
||||
"mocha": "^6.2.0",
|
||||
"npm-run-all": "^4.1.2",
|
||||
|
@ -1,3 +1,2 @@
|
||||
export * from './artifacts';
|
||||
export * from './wrappers';
|
||||
export * from './function_assertions';
|
||||
|
@ -1,9 +0,0 @@
|
||||
export { Actor } from './base';
|
||||
export { Maker } from './maker';
|
||||
export { PoolOperator } from './pool_operator';
|
||||
export { FeeRecipient } from './fee_recipient';
|
||||
export { Staker } from './staker';
|
||||
export { Keeper } from './keeper';
|
||||
export { Taker } from './taker';
|
||||
export * from './hybrids';
|
||||
export * from './utils';
|
@ -1,13 +1,11 @@
|
||||
import { CoordinatorContract, CoordinatorRevertErrors, SignedCoordinatorApproval } from '@0x/contracts-coordinator';
|
||||
import { DevUtilsContract } from '@0x/contracts-dev-utils';
|
||||
import {
|
||||
BlockchainBalanceStore,
|
||||
ExchangeCancelEventArgs,
|
||||
ExchangeCancelUpToEventArgs,
|
||||
exchangeDataEncoder,
|
||||
ExchangeEvents,
|
||||
ExchangeFillEventArgs,
|
||||
LocalBalanceStore,
|
||||
} from '@0x/contracts-exchange';
|
||||
import {
|
||||
blockchainTests,
|
||||
@ -25,8 +23,13 @@ import { SignedOrder, SignedZeroExTransaction } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
|
||||
import { Actor, actorAddressesByName, FeeRecipient, Maker } from '../actors';
|
||||
import { DeploymentManager } from '../deployment_manager';
|
||||
import { Actor } from '../framework/actors/base';
|
||||
import { FeeRecipient } from '../framework/actors/fee_recipient';
|
||||
import { Maker } from '../framework/actors/maker';
|
||||
import { actorAddressesByName } from '../framework/actors/utils';
|
||||
import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
|
||||
import { LocalBalanceStore } from '../framework/balances/local_balance_store';
|
||||
import { DeploymentManager } from '../framework/deployment_manager';
|
||||
|
||||
import { deployCoordinatorAsync } from './deploy_coordinator';
|
||||
|
||||
|
@ -3,7 +3,7 @@ import { artifacts as exchangeArtifacts } from '@0x/contracts-exchange';
|
||||
import { BlockchainTestsEnvironment } from '@0x/contracts-test-utils';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
|
||||
import { DeploymentManager } from '../deployment_manager';
|
||||
import { DeploymentManager } from '../framework/deployment_manager';
|
||||
|
||||
/**
|
||||
* Deploys a Coordinator contract configured to work alongside the provided `deployment`.
|
||||
|
@ -33,7 +33,7 @@ import { AssetProxyId } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { TxData } from 'ethereum-types';
|
||||
|
||||
import { AssetProxyDispatcher, Authorizable, Ownable } from '../wrapper_interfaces';
|
||||
import { AssetProxyDispatcher, Authorizable, Ownable } from './framework/wrapper_interfaces';
|
||||
|
||||
// tslint:disable:no-unnecessary-type-assertion
|
||||
blockchainTests('Deployment and Configuration End to End Tests', env => {
|
@ -18,6 +18,7 @@ import {
|
||||
DummyNoReturnERC20TokenContract,
|
||||
} from '@0x/contracts-erc20';
|
||||
import { DummyERC721TokenContract } from '@0x/contracts-erc721';
|
||||
import { artifacts, ExchangeCancelEventArgs, ExchangeContract, ExchangeRevertErrors } from '@0x/contracts-exchange';
|
||||
import { LibMathRevertErrors } from '@0x/contracts-exchange-libs';
|
||||
import {
|
||||
blockchainTests,
|
||||
@ -26,7 +27,6 @@ import {
|
||||
ERC20BalancesByOwner,
|
||||
expect,
|
||||
getLatestBlockTimestampAsync,
|
||||
hexConcat,
|
||||
increaseTimeAndMineBlockAsync,
|
||||
OrderFactory,
|
||||
orderHashUtils,
|
||||
@ -35,20 +35,13 @@ import {
|
||||
txDefaults,
|
||||
web3Wrapper,
|
||||
} from '@0x/contracts-test-utils';
|
||||
import { RevertReason, SignatureType, SignedOrder } from '@0x/types';
|
||||
import { RevertReason, SignedOrder } from '@0x/types';
|
||||
import { BigNumber, providerUtils, StringRevertError } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import ExchangeRevertErrors = require('../src/revert_errors');
|
||||
|
||||
import { ValidatorWalletAction } from './utils/constants';
|
||||
import { ExchangeWrapper } from './utils/exchange_wrapper';
|
||||
|
||||
import { artifacts } from './artifacts';
|
||||
import { FillOrderWrapper } from './assertion_wrappers/fill_order_wrapper';
|
||||
import { ExchangeCancelEventArgs, ExchangeContract, TestValidatorWalletContract } from './wrappers';
|
||||
import { FillOrderWrapper } from './fill_order_wrapper';
|
||||
|
||||
// tslint:disable:no-unnecessary-type-assertion
|
||||
blockchainTests.resets('Exchange core', () => {
|
||||
@ -69,14 +62,12 @@ blockchainTests.resets('Exchange core', () => {
|
||||
let erc721Proxy: ERC721ProxyContract;
|
||||
let erc1155Proxy: ERC1155ProxyContract;
|
||||
let multiAssetProxy: MultiAssetProxyContract;
|
||||
let validatorWallet: TestValidatorWalletContract;
|
||||
let erc1155Contract: ERC1155MintableContract;
|
||||
let staticCallProxy: StaticCallProxyContract;
|
||||
let staticCallTarget: TestStaticCallTargetContract;
|
||||
|
||||
let signedOrder: SignedOrder;
|
||||
let erc20Balances: ERC20BalancesByOwner;
|
||||
let exchangeWrapper: ExchangeWrapper;
|
||||
let erc20Wrapper: ERC20Wrapper;
|
||||
let erc721Wrapper: ERC721Wrapper;
|
||||
let erc1155Wrapper: Erc1155Wrapper;
|
||||
@ -147,13 +138,6 @@ blockchainTests.resets('Exchange core', () => {
|
||||
{},
|
||||
new BigNumber(chainId),
|
||||
);
|
||||
validatorWallet = await TestValidatorWalletContract.deployFrom0xArtifactAsync(
|
||||
artifacts.TestValidatorWallet,
|
||||
provider,
|
||||
txDefaults,
|
||||
{},
|
||||
exchange.address,
|
||||
);
|
||||
// Configure ERC20Proxy
|
||||
await erc20Proxy.addAuthorizedAddress(exchange.address).awaitTransactionSuccessAsync({ from: owner });
|
||||
await erc20Proxy.addAuthorizedAddress(multiAssetProxy.address).awaitTransactionSuccessAsync({ from: owner });
|
||||
@ -173,12 +157,9 @@ blockchainTests.resets('Exchange core', () => {
|
||||
await multiAssetProxy.registerAssetProxy(staticCallProxy.address).awaitTransactionSuccessAsync({ from: owner });
|
||||
|
||||
// Configure Exchange
|
||||
exchangeWrapper = new ExchangeWrapper(exchange);
|
||||
await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner);
|
||||
await exchangeWrapper.registerAssetProxyAsync(erc721Proxy.address, owner);
|
||||
await exchangeWrapper.registerAssetProxyAsync(erc1155Proxy.address, owner);
|
||||
await exchangeWrapper.registerAssetProxyAsync(multiAssetProxy.address, owner);
|
||||
await exchangeWrapper.registerAssetProxyAsync(staticCallProxy.address, owner);
|
||||
for (const proxy of [erc20Proxy, erc721Proxy, erc1155Proxy, multiAssetProxy, staticCallProxy]) {
|
||||
await exchange.registerAssetProxy(proxy.address).awaitTransactionSuccessAsync({ from: owner });
|
||||
}
|
||||
|
||||
// Configure ERC20 tokens
|
||||
await erc20Wrapper.setBalancesAndAllowancesAsync();
|
||||
@ -252,115 +233,16 @@ blockchainTests.resets('Exchange core', () => {
|
||||
signedOrder = await orderFactory.newSignedOrderAsync();
|
||||
});
|
||||
|
||||
describe('callback signature types', () => {
|
||||
beforeEach(async () => {
|
||||
// Approve the ERC20 proxy with the test validator wallet.
|
||||
await validatorWallet
|
||||
.approveERC20(erc20TokenA.address, erc20Proxy.address, constants.INITIAL_ERC20_ALLOWANCE)
|
||||
.awaitTransactionSuccessAsync();
|
||||
// Mint some ERC20 tokens to the test validator wallet.
|
||||
await erc20TokenA
|
||||
.setBalance(validatorWallet.address, constants.INITIAL_ERC20_BALANCE)
|
||||
.awaitTransactionSuccessAsync();
|
||||
// Approve the validator.
|
||||
await exchange
|
||||
.setSignatureValidatorApproval(validatorWallet.address, true)
|
||||
.awaitTransactionSuccessAsync({
|
||||
from: makerAddress,
|
||||
});
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerFee: constants.ZERO_AMOUNT,
|
||||
takerFee: constants.ZERO_AMOUNT,
|
||||
});
|
||||
});
|
||||
|
||||
it('should revert if `Validator` signature type rejects during a second fill', async () => {
|
||||
const signatureHex = hexConcat(validatorWallet.address, SignatureType.Validator);
|
||||
signedOrder.signature = signatureHex;
|
||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
// Allow the signature check for the first fill.
|
||||
await validatorWallet
|
||||
.prepare(orderHashHex, ValidatorWalletAction.Accept, constants.NULL_BYTES)
|
||||
.awaitTransactionSuccessAsync();
|
||||
const fillAmount = signedOrder.takerAssetAmount.div(10);
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount: fillAmount });
|
||||
// Reject the signature check for the second fill.
|
||||
await validatorWallet
|
||||
.prepare(orderHashHex, ValidatorWalletAction.Reject, constants.NULL_BYTES)
|
||||
.awaitTransactionSuccessAsync();
|
||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
||||
takerAssetFillAmount: fillAmount,
|
||||
});
|
||||
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||
ExchangeRevertErrors.SignatureErrorCode.BadOrderSignature,
|
||||
orderHashHex,
|
||||
signedOrder.makerAddress,
|
||||
signedOrder.signature,
|
||||
);
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('should revert if `Wallet` signature type rejects during a second fill', async () => {
|
||||
const signatureHex = hexConcat(SignatureType.Wallet);
|
||||
signedOrder.makerAddress = validatorWallet.address;
|
||||
signedOrder.signature = signatureHex;
|
||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
// Allow the signature check for the first fill.
|
||||
await validatorWallet
|
||||
.prepare(orderHashHex, ValidatorWalletAction.Accept, constants.NULL_BYTES)
|
||||
.awaitTransactionSuccessAsync();
|
||||
const fillAmount = signedOrder.takerAssetAmount.div(10);
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount: fillAmount });
|
||||
// Reject the signature check for the second fill.
|
||||
await validatorWallet
|
||||
.prepare(orderHashHex, ValidatorWalletAction.Reject, constants.NULL_BYTES)
|
||||
.awaitTransactionSuccessAsync();
|
||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
||||
takerAssetFillAmount: fillAmount,
|
||||
});
|
||||
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||
ExchangeRevertErrors.SignatureErrorCode.BadOrderSignature,
|
||||
orderHashHex,
|
||||
signedOrder.makerAddress,
|
||||
signedOrder.signature,
|
||||
);
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('should revert if `EIP1271Wallet` signature type rejects during a second fill', async () => {
|
||||
const signatureHex = hexConcat(SignatureType.EIP1271Wallet);
|
||||
signedOrder.makerAddress = validatorWallet.address;
|
||||
signedOrder.signature = signatureHex;
|
||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
// Allow the signature check for the first fill.
|
||||
await validatorWallet
|
||||
.prepare(orderHashHex, ValidatorWalletAction.Accept, constants.NULL_BYTES)
|
||||
.awaitTransactionSuccessAsync();
|
||||
const fillAmount = signedOrder.takerAssetAmount.div(10);
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount: fillAmount });
|
||||
// Reject the signature check for the second fill.
|
||||
await validatorWallet
|
||||
.prepare(orderHashHex, ValidatorWalletAction.Reject, constants.NULL_BYTES)
|
||||
.awaitTransactionSuccessAsync();
|
||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
||||
takerAssetFillAmount: fillAmount,
|
||||
});
|
||||
const expectedError = new ExchangeRevertErrors.SignatureError(
|
||||
ExchangeRevertErrors.SignatureErrorCode.BadOrderSignature,
|
||||
orderHashHex,
|
||||
signedOrder.makerAddress,
|
||||
signedOrder.signature,
|
||||
);
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
});
|
||||
|
||||
it('should revert if fully filled', async () => {
|
||||
signedOrder = await orderFactory.newSignedOrderAsync();
|
||||
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
||||
await exchange
|
||||
.fillOrder(signedOrder, signedOrder.takerAssetAmount, signedOrder.signature)
|
||||
.awaitTransactionSuccessAsync({ from: takerAddress });
|
||||
const expectedError = new ExchangeRevertErrors.OrderStatusError(orderHashHex, OrderStatus.FullyFilled);
|
||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
||||
const tx = exchange
|
||||
.fillOrder(signedOrder, signedOrder.takerAssetAmount, signedOrder.signature)
|
||||
.awaitTransactionSuccessAsync({ from: takerAddress });
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
@ -375,7 +257,9 @@ blockchainTests.resets('Exchange core', () => {
|
||||
});
|
||||
const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedError = new ExchangeRevertErrors.OrderStatusError(orderHash, OrderStatus.Expired);
|
||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
||||
const tx = exchange
|
||||
.fillOrder(signedOrder, signedOrder.takerAssetAmount, signedOrder.signature)
|
||||
.awaitTransactionSuccessAsync({ from: takerAddress });
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
@ -386,9 +270,9 @@ blockchainTests.resets('Exchange core', () => {
|
||||
});
|
||||
|
||||
const fillTakerAssetAmount1 = new BigNumber(2);
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
||||
takerAssetFillAmount: fillTakerAssetAmount1,
|
||||
});
|
||||
await exchange
|
||||
.fillOrder(signedOrder, fillTakerAssetAmount1, signedOrder.signature)
|
||||
.awaitTransactionSuccessAsync({ from: takerAddress });
|
||||
|
||||
const fillTakerAssetAmount2 = new BigNumber(1);
|
||||
const expectedError = new LibMathRevertErrors.RoundingError(
|
||||
@ -396,9 +280,9 @@ blockchainTests.resets('Exchange core', () => {
|
||||
new BigNumber(3),
|
||||
new BigNumber(1001),
|
||||
);
|
||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
||||
takerAssetFillAmount: fillTakerAssetAmount2,
|
||||
});
|
||||
const tx = exchange
|
||||
.fillOrder(signedOrder, fillTakerAssetAmount2, signedOrder.signature)
|
||||
.awaitTransactionSuccessAsync({ from: takerAddress });
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
});
|
||||
@ -500,7 +384,7 @@ blockchainTests.resets('Exchange core', () => {
|
||||
orderHash,
|
||||
takerAddress,
|
||||
);
|
||||
const tx = exchangeWrapper.cancelOrderAsync(signedOrder, takerAddress);
|
||||
const tx = exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: takerAddress });
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
@ -508,7 +392,7 @@ blockchainTests.resets('Exchange core', () => {
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber(0),
|
||||
});
|
||||
const tx = await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||
const tx = await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
|
||||
expect(tx.logs.length).to.equal(0);
|
||||
});
|
||||
|
||||
@ -516,22 +400,22 @@ blockchainTests.resets('Exchange core', () => {
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
takerAssetAmount: new BigNumber(0),
|
||||
});
|
||||
const tx = await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||
const tx = await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
|
||||
expect(tx.logs.length).to.equal(0);
|
||||
});
|
||||
|
||||
it('should be able to cancel an order', async () => {
|
||||
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||
await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
|
||||
const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedError = new ExchangeRevertErrors.OrderStatusError(orderHash, OrderStatus.Cancelled);
|
||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
|
||||
takerAssetFillAmount: signedOrder.takerAssetAmount.div(2),
|
||||
});
|
||||
const tx = exchange
|
||||
.fillOrder(signedOrder, signedOrder.takerAssetAmount.div(2), signedOrder.signature)
|
||||
.awaitTransactionSuccessAsync({ from: takerAddress });
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('should log 1 event with correct arguments if cancelled successfully', async () => {
|
||||
const res = await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||
const res = await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
|
||||
expect(res.logs).to.have.length(1);
|
||||
|
||||
const log = res.logs[0] as LogWithDecodedArgs<ExchangeCancelEventArgs>;
|
||||
@ -546,8 +430,8 @@ blockchainTests.resets('Exchange core', () => {
|
||||
});
|
||||
|
||||
it('should noop if already cancelled', async () => {
|
||||
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||
const tx = await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||
await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
|
||||
const tx = await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
|
||||
expect(tx.logs.length).to.equal(0);
|
||||
});
|
||||
|
||||
@ -556,7 +440,7 @@ blockchainTests.resets('Exchange core', () => {
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({
|
||||
expirationTimeSeconds: new BigNumber(currentTimestamp).minus(10),
|
||||
});
|
||||
const tx = await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||
const tx = await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
|
||||
expect(tx.logs.length).to.equal(0);
|
||||
});
|
||||
});
|
||||
@ -564,33 +448,33 @@ blockchainTests.resets('Exchange core', () => {
|
||||
describe('cancelOrdersUpTo', () => {
|
||||
it('should fail to set orderEpoch less than current orderEpoch', async () => {
|
||||
const orderEpoch = new BigNumber(1);
|
||||
await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
|
||||
await exchange.cancelOrdersUpTo(orderEpoch).awaitTransactionSuccessAsync({ from: makerAddress });
|
||||
const lesserOrderEpoch = new BigNumber(0);
|
||||
const expectedError = new ExchangeRevertErrors.OrderEpochError(
|
||||
makerAddress,
|
||||
constants.NULL_ADDRESS,
|
||||
orderEpoch.plus(1),
|
||||
);
|
||||
const tx = exchangeWrapper.cancelOrdersUpToAsync(lesserOrderEpoch, makerAddress);
|
||||
const tx = exchange.cancelOrdersUpTo(lesserOrderEpoch).awaitTransactionSuccessAsync({ from: makerAddress });
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('should fail to set orderEpoch equal to existing orderEpoch', async () => {
|
||||
const orderEpoch = new BigNumber(1);
|
||||
await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
|
||||
await exchange.cancelOrdersUpTo(orderEpoch).awaitTransactionSuccessAsync({ from: makerAddress });
|
||||
const expectedError = new ExchangeRevertErrors.OrderEpochError(
|
||||
makerAddress,
|
||||
constants.NULL_ADDRESS,
|
||||
orderEpoch.plus(1),
|
||||
);
|
||||
const tx = exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
|
||||
const tx = exchange.cancelOrdersUpTo(orderEpoch).awaitTransactionSuccessAsync({ from: makerAddress });
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('should cancel only orders with a orderEpoch less than existing orderEpoch', async () => {
|
||||
// Cancel all transactions with a orderEpoch less than 2
|
||||
const orderEpoch = new BigNumber(1);
|
||||
await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
|
||||
await exchange.cancelOrdersUpTo(orderEpoch).awaitTransactionSuccessAsync({ from: makerAddress });
|
||||
|
||||
// Create 4 orders with orderEpoch values: 0,1,2,3
|
||||
// Since we cancelled with orderEpoch=1, orders with orderEpoch<=1 will not be processed
|
||||
@ -617,8 +501,13 @@ blockchainTests.resets('Exchange core', () => {
|
||||
salt: new BigNumber(3),
|
||||
}),
|
||||
];
|
||||
await exchangeWrapper.batchFillOrdersNoThrowAsync(signedOrders, takerAddress);
|
||||
|
||||
await exchange
|
||||
.batchFillOrdersNoThrow(
|
||||
signedOrders,
|
||||
signedOrders.map(order => order.takerAssetAmount),
|
||||
signedOrders.map(order => order.signature),
|
||||
)
|
||||
.awaitTransactionSuccessAsync({ from: takerAddress });
|
||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||
const fillMakerAssetAmount = signedOrders[2].makerAssetAmount.plus(signedOrders[3].makerAssetAmount);
|
||||
const fillTakerAssetAmount = signedOrders[2].takerAssetAmount.plus(signedOrders[3].takerAssetAmount);
|
||||
@ -672,7 +561,9 @@ blockchainTests.resets('Exchange core', () => {
|
||||
signedOrder.makerAssetData,
|
||||
new StringRevertError(RevertReason.TransferFailed).encode(),
|
||||
);
|
||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
|
||||
const tx = exchange
|
||||
.fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature)
|
||||
.awaitTransactionSuccessAsync({ from: takerAddress });
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
@ -699,7 +590,9 @@ blockchainTests.resets('Exchange core', () => {
|
||||
signedOrder.takerAssetData,
|
||||
new StringRevertError(RevertReason.TransferFailed).encode(),
|
||||
);
|
||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
|
||||
const tx = exchange
|
||||
.fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature)
|
||||
.awaitTransactionSuccessAsync({ from: takerAddress });
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
@ -726,7 +619,9 @@ blockchainTests.resets('Exchange core', () => {
|
||||
signedOrder.makerAssetData,
|
||||
new StringRevertError(RevertReason.InvalidAmount).encode(),
|
||||
);
|
||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
|
||||
const tx = exchange
|
||||
.fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature)
|
||||
.awaitTransactionSuccessAsync({ from: takerAddress });
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
@ -753,7 +648,9 @@ blockchainTests.resets('Exchange core', () => {
|
||||
signedOrder.takerAssetData,
|
||||
new StringRevertError(RevertReason.InvalidAmount).encode(),
|
||||
);
|
||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
|
||||
const tx = exchange
|
||||
.fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature)
|
||||
.awaitTransactionSuccessAsync({ from: takerAddress });
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
@ -773,7 +670,9 @@ blockchainTests.resets('Exchange core', () => {
|
||||
signedOrder.takerAssetAmount,
|
||||
signedOrder.makerAssetAmount,
|
||||
);
|
||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
|
||||
const tx = exchange
|
||||
.fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature)
|
||||
.awaitTransactionSuccessAsync({ from: takerAddress });
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
});
|
||||
@ -1102,7 +1001,9 @@ blockchainTests.resets('Exchange core', () => {
|
||||
assetData,
|
||||
new StringRevertError(RevertReason.TargetNotEven).encode(),
|
||||
);
|
||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
||||
const tx = exchange
|
||||
.fillOrder(signedOrder, signedOrder.takerAssetAmount, signedOrder.signature)
|
||||
.awaitTransactionSuccessAsync({ from: takerAddress });
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
it('should fill the order if the staticcall is successful', async () => {
|
||||
@ -1133,7 +1034,9 @@ blockchainTests.resets('Exchange core', () => {
|
||||
assetData,
|
||||
new StringRevertError(RevertReason.TargetNotEven).encode(),
|
||||
);
|
||||
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
||||
const tx = exchange
|
||||
.fillOrder(signedOrder, signedOrder.takerAssetAmount, signedOrder.signature)
|
||||
.awaitTransactionSuccessAsync({ from: takerAddress });
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
it('should fill the order is the staticcall is successful using the MultiAssetProxy', async () => {
|
||||
@ -1159,7 +1062,7 @@ blockchainTests.resets('Exchange core', () => {
|
||||
signedOrder = await orderFactory.newSignedOrderAsync();
|
||||
});
|
||||
it('should return the correct orderInfo for an unfilled valid order', async () => {
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = new BigNumber(0);
|
||||
const expectedOrderStatus = OrderStatus.Fillable;
|
||||
@ -1175,8 +1078,8 @@ blockchainTests.resets('Exchange core', () => {
|
||||
await fillOrderWrapper.fillOrderAndAssertEffectsAsync(signedOrder, takerAddress, { takerAssetFillAmount });
|
||||
});
|
||||
it('should return the correct orderInfo for a cancelled and unfilled order', async () => {
|
||||
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
|
||||
const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = new BigNumber(0);
|
||||
const expectedOrderStatus = OrderStatus.Cancelled;
|
||||
@ -1186,9 +1089,11 @@ blockchainTests.resets('Exchange core', () => {
|
||||
});
|
||||
it('should return the correct orderInfo for a cancelled and partially filled order', async () => {
|
||||
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
|
||||
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
await exchange
|
||||
.fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature)
|
||||
.awaitTransactionSuccessAsync({ from: takerAddress });
|
||||
await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
|
||||
const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = takerAssetFillAmount;
|
||||
const expectedOrderStatus = OrderStatus.Cancelled;
|
||||
@ -1200,7 +1105,7 @@ blockchainTests.resets('Exchange core', () => {
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const timeUntilExpiration = signedOrder.expirationTimeSeconds.minus(currentTimestamp).toNumber();
|
||||
await increaseTimeAndMineBlockAsync(timeUntilExpiration);
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = new BigNumber(0);
|
||||
const expectedOrderStatus = OrderStatus.Expired;
|
||||
@ -1210,11 +1115,13 @@ blockchainTests.resets('Exchange core', () => {
|
||||
});
|
||||
it('should return the correct orderInfo for an expired and partially filled order', async () => {
|
||||
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
|
||||
await exchange
|
||||
.fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature)
|
||||
.awaitTransactionSuccessAsync({ from: takerAddress });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const timeUntilExpiration = signedOrder.expirationTimeSeconds.minus(currentTimestamp).toNumber();
|
||||
await increaseTimeAndMineBlockAsync(timeUntilExpiration);
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = takerAssetFillAmount;
|
||||
const expectedOrderStatus = OrderStatus.Expired;
|
||||
@ -1223,11 +1130,13 @@ blockchainTests.resets('Exchange core', () => {
|
||||
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
|
||||
});
|
||||
it('should return the correct orderInfo for an expired and fully filled order', async () => {
|
||||
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
|
||||
await exchange
|
||||
.fillOrder(signedOrder, signedOrder.takerAssetAmount, signedOrder.signature)
|
||||
.awaitTransactionSuccessAsync({ from: takerAddress });
|
||||
const currentTimestamp = await getLatestBlockTimestampAsync();
|
||||
const timeUntilExpiration = signedOrder.expirationTimeSeconds.minus(currentTimestamp).toNumber();
|
||||
await increaseTimeAndMineBlockAsync(timeUntilExpiration);
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount;
|
||||
// FULLY_FILLED takes precedence over EXPIRED
|
||||
@ -1238,7 +1147,7 @@ blockchainTests.resets('Exchange core', () => {
|
||||
});
|
||||
it('should return the correct orderInfo for an order with a makerAssetAmount of 0', async () => {
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetAmount: new BigNumber(0) });
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = new BigNumber(0);
|
||||
const expectedOrderStatus = OrderStatus.InvalidMakerAssetAmount;
|
||||
@ -1248,7 +1157,7 @@ blockchainTests.resets('Exchange core', () => {
|
||||
});
|
||||
it('should return the correct orderInfo for an order with a takerAssetAmount of 0', async () => {
|
||||
signedOrder = await orderFactory.newSignedOrderAsync({ takerAssetAmount: new BigNumber(0) });
|
||||
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
|
||||
const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
|
||||
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const expectedTakerAssetFilledAmount = new BigNumber(0);
|
||||
const expectedOrderStatus = OrderStatus.InvalidTakerAssetAmount;
|
@ -1,12 +1,6 @@
|
||||
import { DevUtilsContract } from '@0x/contracts-dev-utils';
|
||||
import { ERC20TokenEvents, ERC20TokenTransferEventArgs } from '@0x/contracts-erc20';
|
||||
import {
|
||||
BlockchainBalanceStore,
|
||||
ExchangeRevertErrors,
|
||||
IExchangeEvents,
|
||||
IExchangeFillEventArgs,
|
||||
LocalBalanceStore,
|
||||
} from '@0x/contracts-exchange';
|
||||
import { ExchangeRevertErrors, IExchangeEvents, IExchangeFillEventArgs } from '@0x/contracts-exchange';
|
||||
import { ReferenceFunctions } from '@0x/contracts-exchange-libs';
|
||||
import {
|
||||
blockchainTests,
|
||||
@ -25,9 +19,11 @@ import { BigNumber } from '@0x/utils';
|
||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { Actor } from '../actors/base';
|
||||
import { Maker } from '../actors/maker';
|
||||
import { DeploymentManager } from '../deployment_manager';
|
||||
import { Actor } from '../framework/actors/base';
|
||||
import { Maker } from '../framework/actors/maker';
|
||||
import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
|
||||
import { LocalBalanceStore } from '../framework/balances/local_balance_store';
|
||||
import { DeploymentManager } from '../framework/deployment_manager';
|
||||
|
||||
const { addFillResults, safeGetPartialAmountFloor } = ReferenceFunctions;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { DevUtilsContract } from '@0x/contracts-dev-utils';
|
||||
import { ExchangeContract } from '@0x/contracts-exchange';
|
||||
import { ReferenceFunctions as LibReferenceFunctions } from '@0x/contracts-exchange-libs';
|
||||
import {
|
||||
constants,
|
||||
@ -14,12 +15,10 @@ import { BigNumber } from '@0x/utils';
|
||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { ExchangeContract } from '../wrappers';
|
||||
|
||||
import { BalanceStore } from '../../src/balance_stores/balance_store';
|
||||
import { BlockchainBalanceStore } from '../../src/balance_stores/blockchain_balance_store';
|
||||
import { LocalBalanceStore } from '../../src/balance_stores/local_balance_store';
|
||||
import { TokenContractsByName, TokenIds, TokenOwnersByName } from '../../src/balance_stores/types';
|
||||
import { BalanceStore } from '../framework/balances/balance_store';
|
||||
import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
|
||||
import { LocalBalanceStore } from '../framework/balances/local_balance_store';
|
||||
import { TokenContractsByName, TokenIds, TokenOwnersByName } from '../framework/balances/types';
|
||||
|
||||
export class FillOrderWrapper {
|
||||
private readonly _blockchainBalanceStore: BlockchainBalanceStore;
|
@ -1,11 +1,6 @@
|
||||
import { DevUtilsContract } from '@0x/contracts-dev-utils';
|
||||
import { ERC20TokenEvents, ERC20TokenTransferEventArgs } from '@0x/contracts-erc20';
|
||||
import {
|
||||
BlockchainBalanceStore,
|
||||
ExchangeEvents,
|
||||
ExchangeFillEventArgs,
|
||||
LocalBalanceStore,
|
||||
} from '@0x/contracts-exchange';
|
||||
import { ExchangeEvents, ExchangeFillEventArgs } from '@0x/contracts-exchange';
|
||||
import { ReferenceFunctions } from '@0x/contracts-exchange-libs';
|
||||
import {
|
||||
constants as stakingConstants,
|
||||
@ -28,8 +23,14 @@ import { SignedOrder } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
|
||||
import { actorAddressesByName, FeeRecipient, Maker, OperatorStakerMaker, StakerKeeper, Taker } from '../actors';
|
||||
import { DeploymentManager } from '../deployment_manager';
|
||||
import { FeeRecipient } from '../framework/actors/fee_recipient';
|
||||
import { OperatorStakerMaker, StakerKeeper } from '../framework/actors/hybrids';
|
||||
import { Maker } from '../framework/actors/maker';
|
||||
import { Taker } from '../framework/actors/taker';
|
||||
import { actorAddressesByName } from '../framework/actors/utils';
|
||||
import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
|
||||
import { LocalBalanceStore } from '../framework/balances/local_balance_store';
|
||||
import { DeploymentManager } from '../framework/deployment_manager';
|
||||
|
||||
const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider);
|
||||
blockchainTests.resets('fillOrder integration tests', env => {
|
@ -3,7 +3,7 @@ import { artifacts, ForwarderContract } from '@0x/contracts-exchange-forwarder';
|
||||
import { BlockchainTestsEnvironment } from '@0x/contracts-test-utils';
|
||||
import { assetDataUtils } from '@0x/order-utils';
|
||||
|
||||
import { DeploymentManager } from '../deployment_manager';
|
||||
import { DeploymentManager } from '../framework/deployment_manager';
|
||||
|
||||
/**
|
||||
* Deploys a Forwarder contract configured to work alongside the provided `deployment`.
|
||||
|
@ -1,12 +1,7 @@
|
||||
import { DevUtilsContract } from '@0x/contracts-dev-utils';
|
||||
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
||||
import { DummyERC721TokenContract } from '@0x/contracts-erc721';
|
||||
import {
|
||||
artifacts as exchangeArtifacts,
|
||||
BlockchainBalanceStore,
|
||||
ExchangeContract,
|
||||
LocalBalanceStore,
|
||||
} from '@0x/contracts-exchange';
|
||||
import { artifacts as exchangeArtifacts, ExchangeContract } from '@0x/contracts-exchange';
|
||||
import { artifacts, ForwarderContract, ForwarderRevertErrors } from '@0x/contracts-exchange-forwarder';
|
||||
import {
|
||||
blockchainTests,
|
||||
@ -19,8 +14,13 @@ import {
|
||||
} from '@0x/contracts-test-utils';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
|
||||
import { Actor, actorAddressesByName, FeeRecipient, Maker } from '../actors';
|
||||
import { DeploymentManager } from '../deployment_manager';
|
||||
import { FeeRecipient } from '../framework/actors/fee_recipient';
|
||||
import { Maker } from '../framework/actors/maker';
|
||||
import { Taker } from '../framework/actors/taker';
|
||||
import { actorAddressesByName } from '../framework/actors/utils';
|
||||
import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
|
||||
import { LocalBalanceStore } from '../framework/balances/local_balance_store';
|
||||
import { DeploymentManager } from '../framework/deployment_manager';
|
||||
|
||||
import { deployForwarderAsync } from './deploy_forwarder';
|
||||
import { ForwarderTestFactory } from './forwarder_test_factory';
|
||||
@ -42,7 +42,7 @@ blockchainTests('Forwarder integration tests', env => {
|
||||
let makerAssetData: string;
|
||||
|
||||
let maker: Maker;
|
||||
let taker: Actor;
|
||||
let taker: Taker;
|
||||
let orderFeeRecipient: FeeRecipient;
|
||||
let forwarderFeeRecipient: FeeRecipient;
|
||||
|
||||
@ -59,7 +59,7 @@ blockchainTests('Forwarder integration tests', env => {
|
||||
wethAssetData = await devUtils.encodeERC20AssetData(deployment.tokens.weth.address).callAsync();
|
||||
makerAssetData = await devUtils.encodeERC20AssetData(makerToken.address).callAsync();
|
||||
|
||||
taker = new Actor({ name: 'Taker', deployment });
|
||||
taker = new Taker({ name: 'Taker', deployment });
|
||||
orderFeeRecipient = new FeeRecipient({
|
||||
name: 'Order fee recipient',
|
||||
deployment,
|
||||
@ -560,14 +560,24 @@ blockchainTests('Forwarder integration tests', env => {
|
||||
|
||||
// Compute expected balances
|
||||
const expectedBalances = LocalBalanceStore.create(devUtils, balanceStore);
|
||||
expectedBalances.transferAssetAsync(maker.address, taker.address, makerAssetFillAmount, makerAssetData);
|
||||
await expectedBalances.transferAssetAsync(
|
||||
maker.address,
|
||||
taker.address,
|
||||
makerAssetFillAmount,
|
||||
makerAssetData,
|
||||
);
|
||||
expectedBalances.wrapEth(
|
||||
taker.address,
|
||||
deployment.tokens.weth.address,
|
||||
takerAssetFillAmount.plus(DeploymentManager.protocolFee),
|
||||
);
|
||||
expectedBalances.transferAssetAsync(taker.address, maker.address, takerAssetFillAmount, wethAssetData);
|
||||
expectedBalances.transferAssetAsync(
|
||||
await expectedBalances.transferAssetAsync(
|
||||
taker.address,
|
||||
maker.address,
|
||||
takerAssetFillAmount,
|
||||
wethAssetData,
|
||||
);
|
||||
await expectedBalances.transferAssetAsync(
|
||||
taker.address,
|
||||
deployment.staking.stakingProxy.address,
|
||||
DeploymentManager.protocolFee,
|
||||
|
@ -1,13 +1,16 @@
|
||||
import { DevUtilsContract } from '@0x/contracts-dev-utils';
|
||||
import { BlockchainBalanceStore, LocalBalanceStore } from '@0x/contracts-exchange';
|
||||
import { ForwarderContract } from '@0x/contracts-exchange-forwarder';
|
||||
import { constants, expect, getPercentageOfValue, OrderStatus } from '@0x/contracts-test-utils';
|
||||
import { OrderInfo, SignedOrder } from '@0x/types';
|
||||
import { BigNumber, RevertError } from '@0x/utils';
|
||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
|
||||
import { Actor, FeeRecipient, Maker } from '../actors';
|
||||
import { DeploymentManager } from '../deployment_manager';
|
||||
import { FeeRecipient } from '../framework/actors/fee_recipient';
|
||||
import { Maker } from '../framework/actors/maker';
|
||||
import { Taker } from '../framework/actors/taker';
|
||||
import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
|
||||
import { LocalBalanceStore } from '../framework/balances/local_balance_store';
|
||||
import { DeploymentManager } from '../framework/deployment_manager';
|
||||
|
||||
// Necessary bookkeeping to validate Forwarder results
|
||||
interface ForwarderFillState {
|
||||
@ -31,7 +34,7 @@ export class ForwarderTestFactory {
|
||||
private readonly _deployment: DeploymentManager,
|
||||
private readonly _balanceStore: BlockchainBalanceStore,
|
||||
private readonly _maker: Maker,
|
||||
private readonly _taker: Actor,
|
||||
private readonly _taker: Taker,
|
||||
private readonly _orderFeeRecipient: FeeRecipient,
|
||||
private readonly _forwarderFeeRecipient: FeeRecipient,
|
||||
private readonly _devUtils: DevUtilsContract,
|
||||
|
@ -5,9 +5,9 @@ import { SignatureType, SignedZeroExTransaction, ZeroExTransaction } from '@0x/t
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { AssertionResult } from '../../src/function_assertions';
|
||||
import { AssertionResult } from '../assertions/function_assertion';
|
||||
import { DeploymentManager } from '../deployment_manager';
|
||||
import { SimulationEnvironment } from '../simulation/simulation';
|
||||
import { SimulationEnvironment } from '../simulation';
|
||||
|
||||
export type Constructor<T = {}> = new (...args: any[]) => T;
|
||||
|
@ -4,11 +4,9 @@ import '@azure/core-asynciterator-polyfill';
|
||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { AssertionResult } from '../../src/function_assertions';
|
||||
import {
|
||||
validCreateStakingPoolAssertion,
|
||||
validDecreaseStakingPoolOperatorShareAssertion,
|
||||
} from '../function-assertions';
|
||||
import { validCreateStakingPoolAssertion } from '../assertions/createStakingPool';
|
||||
import { validDecreaseStakingPoolOperatorShareAssertion } from '../assertions/decreaseStakingPoolOperatorShare';
|
||||
import { AssertionResult } from '../assertions/function_assertion';
|
||||
|
||||
import { Actor, Constructor } from './base';
|
||||
|
@ -4,8 +4,10 @@ import { BigNumber } from '@0x/utils';
|
||||
import '@azure/core-asynciterator-polyfill';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { AssertionResult } from '../../src/function_assertions';
|
||||
import { validMoveStakeAssertion, validStakeAssertion, validUnstakeAssertion } from '../function-assertions';
|
||||
import { AssertionResult } from '../assertions/function_assertion';
|
||||
import { validMoveStakeAssertion } from '../assertions/moveStake';
|
||||
import { validStakeAssertion } from '../assertions/stake';
|
||||
import { validUnstakeAssertion } from '../assertions/unstake';
|
||||
|
||||
import { Actor, Constructor } from './base';
|
||||
|
@ -3,9 +3,10 @@ import { expect } from '@0x/contracts-test-utils';
|
||||
import { BigNumber, logUtils } from '@0x/utils';
|
||||
import { TxData } from 'ethereum-types';
|
||||
|
||||
import { FunctionAssertion, FunctionResult } from '../../src/function_assertions';
|
||||
import { DeploymentManager } from '../deployment_manager';
|
||||
|
||||
import { FunctionAssertion, FunctionResult } from './function_assertion';
|
||||
|
||||
// tslint:disable:no-unnecessary-type-assertion
|
||||
|
||||
/**
|
@ -2,9 +2,10 @@ import { StakingPoolById } from '@0x/contracts-staking';
|
||||
import { expect } from '@0x/contracts-test-utils';
|
||||
import { logUtils } from '@0x/utils';
|
||||
|
||||
import { FunctionAssertion, FunctionResult } from '../../src/function_assertions';
|
||||
import { DeploymentManager } from '../deployment_manager';
|
||||
|
||||
import { FunctionAssertion, FunctionResult } from './function_assertion';
|
||||
|
||||
/**
|
||||
* Returns a FunctionAssertion for `decreaseStakingPoolOperatorShare` which assumes valid input is
|
||||
* provided. The FunctionAssertion checks that the operator share actually gets updated.
|
@ -106,79 +106,3 @@ export class FunctionAssertion<TBefore, ReturnDataType> implements Assertion {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export type IndexGenerator = () => number;
|
||||
|
||||
export type InputGenerator = () => Promise<any[]>;
|
||||
|
||||
export interface AssertionGenerator {
|
||||
assertion: Assertion;
|
||||
generator: InputGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is an abstract way to represent collections of function assertions.
|
||||
* Using this, we can use closures to build up many useful collections with different
|
||||
* properties. Notably, this abstraction supports function assertion collections
|
||||
* that can be run continuously and also those that terminate in a finite number
|
||||
* of steps.
|
||||
*/
|
||||
class MetaAssertion implements Assertion {
|
||||
constructor(
|
||||
protected readonly assertionGenerators: AssertionGenerator[],
|
||||
protected readonly indexGenerator: IndexGenerator,
|
||||
) {}
|
||||
|
||||
public async executeAsync(): Promise<void> {
|
||||
let idx = this.indexGenerator();
|
||||
while (idx > 0) {
|
||||
const args = await this.assertionGenerators[idx].generator();
|
||||
await this.assertionGenerators[idx].assertion.executeAsync(...args);
|
||||
idx = this.indexGenerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a class that can execute a set of function assertions in sequence.
|
||||
* @param assertionGenerators A set of assertion generators to run in sequence.
|
||||
*/
|
||||
export function FunctionAssertionSequence(assertionGenerators: AssertionGenerator[]): MetaAssertion {
|
||||
let idx = 0;
|
||||
return new MetaAssertion(assertionGenerators, () => {
|
||||
if (idx < assertionGenerators.length) {
|
||||
return idx++;
|
||||
} else {
|
||||
idx = 0;
|
||||
return -1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export interface WeightedAssertionGenerator extends AssertionGenerator {
|
||||
weight?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a class that can execute a set of function assertions at random continuously.
|
||||
* This will not terminate unless the process that called `runAsync` terminates.
|
||||
* @param weightedAssertionGenerators A set of function assertions that have been
|
||||
* assigned weights.
|
||||
*/
|
||||
export function ContinuousFunctionAssertionSet(
|
||||
weightedAssertionGenerators: WeightedAssertionGenerator[],
|
||||
): MetaAssertion {
|
||||
// Construct an array of assertion generators that allows random sampling from a
|
||||
// uniform distribution to correctly bias assertion selection.
|
||||
let assertionGenerators: AssertionGenerator[] = [];
|
||||
for (const { assertion, generator, weight } of weightedAssertionGenerators) {
|
||||
const weightedAssertions: AssertionGenerator[] = [];
|
||||
_.fill(weightedAssertions, { assertion, generator }, 0, weight || 1);
|
||||
assertionGenerators = assertionGenerators.concat(weightedAssertions);
|
||||
}
|
||||
|
||||
// The index generator simply needs to sample from a uniform distribution.
|
||||
const indexGenerator = () => Math.round(Math.random() * (assertionGenerators.length - 1));
|
||||
|
||||
return new MetaAssertion(assertionGenerators, indexGenerator);
|
||||
}
|
@ -11,9 +11,10 @@ import { BigNumber, logUtils } from '@0x/utils';
|
||||
import { TxData } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { FunctionAssertion } from '../../src/function_assertions';
|
||||
import { DeploymentManager } from '../deployment_manager';
|
||||
|
||||
import { FunctionAssertion } from './function_assertion';
|
||||
|
||||
function incrementNextEpochBalance(stakeBalance: StoredBalance, amount: BigNumber): void {
|
||||
_.update(stakeBalance, ['nextEpochBalance'], balance => (balance || constants.ZERO_AMOUNT).plus(amount));
|
||||
}
|
@ -1,12 +1,14 @@
|
||||
import { BlockchainBalanceStore, LocalBalanceStore } from '@0x/contracts-exchange';
|
||||
import { GlobalStakeByStatus, OwnerStakeByStatus, StakeStatus, StoredBalance } from '@0x/contracts-staking';
|
||||
import { expect } from '@0x/contracts-test-utils';
|
||||
import { BigNumber, logUtils } from '@0x/utils';
|
||||
import { TxData } from 'ethereum-types';
|
||||
|
||||
import { FunctionAssertion, FunctionResult } from '../../src/function_assertions';
|
||||
import { BlockchainBalanceStore } from '../balances/blockchain_balance_store';
|
||||
import { LocalBalanceStore } from '../balances/local_balance_store';
|
||||
import { DeploymentManager } from '../deployment_manager';
|
||||
|
||||
import { FunctionAssertion, FunctionResult } from './function_assertion';
|
||||
|
||||
function expectedUndelegatedStake(
|
||||
initStake: OwnerStakeByStatus | GlobalStakeByStatus,
|
||||
amount: BigNumber,
|
@ -1,12 +1,14 @@
|
||||
import { BlockchainBalanceStore, LocalBalanceStore } from '@0x/contracts-exchange';
|
||||
import { GlobalStakeByStatus, OwnerStakeByStatus, StakeStatus, StoredBalance } from '@0x/contracts-staking';
|
||||
import { expect } from '@0x/contracts-test-utils';
|
||||
import { BigNumber, logUtils } from '@0x/utils';
|
||||
import { TxData } from 'ethereum-types';
|
||||
|
||||
import { FunctionAssertion, FunctionResult } from '../../src/function_assertions';
|
||||
import { BlockchainBalanceStore } from '../balances/blockchain_balance_store';
|
||||
import { LocalBalanceStore } from '../balances/local_balance_store';
|
||||
import { DeploymentManager } from '../deployment_manager';
|
||||
|
||||
import { FunctionAssertion, FunctionResult } from './function_assertion';
|
||||
|
||||
function expectedUndelegatedStake(
|
||||
initStake: OwnerStakeByStatus | GlobalStakeByStatus,
|
||||
amount: BigNumber,
|
@ -1,9 +1,9 @@
|
||||
import { BlockchainBalanceStore } from '@0x/contracts-exchange';
|
||||
import { GlobalStakeByStatus, StakeStatus, StakingPoolById, StoredBalance } from '@0x/contracts-staking';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { AssertionResult } from '../../src/function_assertions';
|
||||
import { DeploymentManager } from '../deployment_manager';
|
||||
import { AssertionResult } from './assertions/function_assertion';
|
||||
import { BlockchainBalanceStore } from './balances/blockchain_balance_store';
|
||||
import { DeploymentManager } from './deployment_manager';
|
||||
|
||||
// tslint:disable:max-classes-per-file
|
||||
|
@ -2,10 +2,9 @@ import { blockchainTests, constants, expect, filterLogsToArguments, getRandomInt
|
||||
import { BigNumber, StringRevertError } from '@0x/utils';
|
||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
|
||||
import { FunctionAssertion, FunctionResult } from '../../src/function_assertions';
|
||||
|
||||
import { artifacts } from '../artifacts';
|
||||
import { TestFrameworkContract, TestFrameworkEventEventArgs, TestFrameworkEvents } from '../wrappers';
|
||||
import { artifacts } from '../../artifacts';
|
||||
import { TestFrameworkContract, TestFrameworkEventEventArgs, TestFrameworkEvents } from '../../wrappers';
|
||||
import { FunctionAssertion, FunctionResult } from '../assertions/function_assertion';
|
||||
|
||||
const { ZERO_AMOUNT, MAX_UINT256 } = constants;
|
||||
|
@ -1,5 +0,0 @@
|
||||
export * from './stake';
|
||||
export * from './unstake';
|
||||
export * from './createStakingPool';
|
||||
export * from './decreaseStakingPoolOperatorShare';
|
||||
export * from './moveStake';
|
@ -1,12 +1,11 @@
|
||||
import { BlockchainBalanceStore } from '@0x/contracts-exchange';
|
||||
import { blockchainTests } from '@0x/contracts-test-utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { AssertionResult } from '../../src/function_assertions';
|
||||
import { PoolOperator } from '../actors';
|
||||
import { DeploymentManager } from '../deployment_manager';
|
||||
|
||||
import { Simulation, SimulationEnvironment } from './simulation';
|
||||
import { PoolOperator } from '../framework/actors/pool_operator';
|
||||
import { AssertionResult } from '../framework/assertions/function_assertion';
|
||||
import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
|
||||
import { DeploymentManager } from '../framework/deployment_manager';
|
||||
import { Simulation, SimulationEnvironment } from '../framework/simulation';
|
||||
|
||||
export class PoolManagementSimulation extends Simulation {
|
||||
protected async *_assertionGenerator(): AsyncIterableIterator<AssertionResult | void> {
|
@ -1,13 +1,13 @@
|
||||
import { BlockchainBalanceStore } from '@0x/contracts-exchange';
|
||||
import { blockchainTests } from '@0x/contracts-test-utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { AssertionResult } from '../../src/function_assertions';
|
||||
import { Staker } from '../actors';
|
||||
import { DeploymentManager } from '../deployment_manager';
|
||||
import { Staker } from '../framework/actors/staker';
|
||||
import { AssertionResult } from '../framework/assertions/function_assertion';
|
||||
import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
|
||||
import { DeploymentManager } from '../framework/deployment_manager';
|
||||
import { Simulation, SimulationEnvironment } from '../framework/simulation';
|
||||
|
||||
import { PoolManagementSimulation } from './pool_management_test';
|
||||
import { Simulation, SimulationEnvironment } from './simulation';
|
||||
|
||||
export class StakeManagementSimulation extends Simulation {
|
||||
protected async *_assertionGenerator(): AsyncIterableIterator<AssertionResult | void> {
|
@ -57,6 +57,7 @@ export {
|
||||
TokenBalances,
|
||||
TransactionDataParams,
|
||||
ExchangeFunctionName,
|
||||
ValidatorWalletAction,
|
||||
} from './types';
|
||||
export { blockchainTests, BlockchainTestsEnvironment, describe } from './mocha_blockchain';
|
||||
export { chaiSetup, expect } from './chai_setup';
|
||||
|
@ -201,3 +201,14 @@ export enum ExchangeFunctionName {
|
||||
SetProtocolFeeCollectorAddress = 'setProtocolFeeCollectorAddress',
|
||||
DetachProtocolFeeCollector = 'detachProtocolFeeCollector',
|
||||
}
|
||||
|
||||
export enum ValidatorWalletAction {
|
||||
Reject = 0,
|
||||
Accept = 1,
|
||||
Revert = 2,
|
||||
UpdateState = 3,
|
||||
MatchSignatureHash = 4,
|
||||
ReturnTrue = 5,
|
||||
ReturnNothing = 6,
|
||||
NTypes = 7,
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user