Merge branch 'master' into unavailableFilledCancelled
# Conflicts: # src/contract_wrappers/exchange_wrapper.ts # src/types.ts # test/exchange_wrapper_test.ts
This commit is contained in:
@@ -10,8 +10,9 @@ import {web3Factory} from './utils/web3_factory';
|
||||
import {ZeroEx} from '../src/0x.js';
|
||||
import {BlockchainLifecycle} from './utils/blockchain_lifecycle';
|
||||
import {orderFactory} from './utils/order_factory';
|
||||
import {FillOrderValidationErrs, Token, SignedOrder} from '../src/types';
|
||||
import {Token, SignedOrder, ExchangeContractErrs} from '../src/types';
|
||||
import {FillScenarios} from './utils/fill_scenarios';
|
||||
import {TokenUtils} from './utils/token_utils';
|
||||
|
||||
chai.use(dirtyChai);
|
||||
chai.use(ChaiBigNumber());
|
||||
@@ -21,17 +22,21 @@ const blockchainLifecycle = new BlockchainLifecycle();
|
||||
const NON_EXISTENT_ORDER_HASH = '0x79370342234e7acd6bbeac335bd3bb1d368383294b64b8160a00f4060e4d3777';
|
||||
|
||||
describe('ExchangeWrapper', () => {
|
||||
let zeroEx: ZeroEx;
|
||||
let userAddresses: string[];
|
||||
let web3: Web3;
|
||||
let zeroEx: ZeroEx;
|
||||
let tokenUtils: TokenUtils;
|
||||
let tokens: Token[];
|
||||
let userAddresses: string[];
|
||||
let zrxTokenAddress: string;
|
||||
let fillScenarios: FillScenarios;
|
||||
before(async () => {
|
||||
web3 = web3Factory.create();
|
||||
zeroEx = new ZeroEx(web3);
|
||||
userAddresses = await promisify(web3.eth.getAccounts)();
|
||||
tokens = await zeroEx.tokenRegistry.getTokensAsync();
|
||||
fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens);
|
||||
tokenUtils = new TokenUtils(tokens);
|
||||
zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
|
||||
fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress);
|
||||
});
|
||||
beforeEach(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
@@ -112,14 +117,15 @@ describe('ExchangeWrapper', () => {
|
||||
describe('#fillOrderAsync', () => {
|
||||
let makerTokenAddress: string;
|
||||
let takerTokenAddress: string;
|
||||
let coinBase: string;
|
||||
let coinbase: string;
|
||||
let makerAddress: string;
|
||||
let takerAddress: string;
|
||||
const fillTakerAmountInBaseUnits = new BigNumber(5);
|
||||
let feeRecipient: string;
|
||||
const fillTakerAmount = new BigNumber(5);
|
||||
const shouldCheckTransfer = false;
|
||||
before('fetch tokens', async () => {
|
||||
[coinBase, makerAddress, takerAddress] = userAddresses;
|
||||
const [makerToken, takerToken] = tokens;
|
||||
before(async () => {
|
||||
[coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
|
||||
const [makerToken, takerToken] = tokenUtils.getNonProtocolTokens();
|
||||
makerTokenAddress = makerToken.address;
|
||||
takerTokenAddress = takerToken.address;
|
||||
});
|
||||
@@ -129,92 +135,149 @@ describe('ExchangeWrapper', () => {
|
||||
describe('failed fills', () => {
|
||||
it('should throw when the fill amount is zero', async () => {
|
||||
const fillableAmount = new BigNumber(5);
|
||||
const signedOrder = await fillScenarios.createAFillableSignedOrderAsync(
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
||||
);
|
||||
const zeroFillAmount = new BigNumber(0);
|
||||
zeroEx.setTransactionSenderAccount(takerAddress);
|
||||
return expect(zeroEx.exchange.fillOrderAsync(
|
||||
signedOrder, zeroFillAmount, shouldCheckTransfer,
|
||||
)).to.be.rejectedWith(FillOrderValidationErrs.FILL_AMOUNT_IS_ZERO);
|
||||
)).to.be.rejectedWith(ExchangeContractErrs.ORDER_REMAINING_FILL_AMOUNT_ZERO);
|
||||
});
|
||||
it('should throw when sender is not a taker', async () => {
|
||||
const fillableAmount = new BigNumber(5);
|
||||
const signedOrder = await fillScenarios.createAFillableSignedOrderAsync(
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
||||
);
|
||||
return expect(zeroEx.exchange.fillOrderAsync(
|
||||
signedOrder, fillTakerAmountInBaseUnits, shouldCheckTransfer,
|
||||
)).to.be.rejectedWith(FillOrderValidationErrs.NOT_A_TAKER);
|
||||
signedOrder, fillTakerAmount, shouldCheckTransfer,
|
||||
)).to.be.rejectedWith(ExchangeContractErrs.TRANSACTION_SENDER_IS_NOT_FILL_ORDER_TAKER);
|
||||
});
|
||||
it('should throw when order is expired', async () => {
|
||||
const expirationInPast = new BigNumber(42);
|
||||
const fillableAmount = new BigNumber(5);
|
||||
const signedOrder = await fillScenarios.createAFillableSignedOrderAsync(
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount, expirationInPast,
|
||||
);
|
||||
zeroEx.setTransactionSenderAccount(takerAddress);
|
||||
return expect(zeroEx.exchange.fillOrderAsync(
|
||||
signedOrder, fillTakerAmountInBaseUnits, shouldCheckTransfer,
|
||||
)).to.be.rejectedWith(FillOrderValidationErrs.EXPIRED);
|
||||
signedOrder, fillTakerAmount, shouldCheckTransfer,
|
||||
)).to.be.rejectedWith(ExchangeContractErrs.ORDER_FILL_EXPIRED);
|
||||
});
|
||||
it('should throw when taker balance is less than fill amount', async () => {
|
||||
describe('should throw when not enough balance or allowance to fulfill the order', () => {
|
||||
const fillableAmount = new BigNumber(5);
|
||||
const signedOrder = await fillScenarios.createAFillableSignedOrderAsync(
|
||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
||||
);
|
||||
zeroEx.setTransactionSenderAccount(takerAddress);
|
||||
const moreThanTheBalance = new BigNumber(6);
|
||||
return expect(zeroEx.exchange.fillOrderAsync(
|
||||
signedOrder, moreThanTheBalance, shouldCheckTransfer,
|
||||
)).to.be.rejectedWith(FillOrderValidationErrs.NOT_ENOUGH_TAKER_BALANCE);
|
||||
const balanceToSubtractFromMaker = new BigNumber(3);
|
||||
const lackingAllowance = new BigNumber(3);
|
||||
let signedOrder: SignedOrder;
|
||||
beforeEach('create fillable signed order', async () => {
|
||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
||||
);
|
||||
});
|
||||
it('should throw when taker balance is less than fill amount', async () => {
|
||||
await zeroEx.token.transferAsync(
|
||||
takerTokenAddress, takerAddress, coinbase, balanceToSubtractFromMaker,
|
||||
);
|
||||
zeroEx.setTransactionSenderAccount(takerAddress);
|
||||
return expect(zeroEx.exchange.fillOrderAsync(
|
||||
signedOrder, fillTakerAmount, shouldCheckTransfer,
|
||||
)).to.be.rejectedWith(ExchangeContractErrs.INSUFFICIENT_TAKER_BALANCE);
|
||||
});
|
||||
it('should throw when taker allowance is less than fill amount', async () => {
|
||||
const newAllowanceWhichIsLessThanFillAmount = fillTakerAmount.minus(lackingAllowance);
|
||||
await zeroEx.token.setProxyAllowanceAsync(takerTokenAddress, takerAddress,
|
||||
newAllowanceWhichIsLessThanFillAmount);
|
||||
zeroEx.setTransactionSenderAccount(takerAddress);
|
||||
return expect(zeroEx.exchange.fillOrderAsync(
|
||||
signedOrder, fillTakerAmount, shouldCheckTransfer,
|
||||
)).to.be.rejectedWith(ExchangeContractErrs.INSUFFICIENT_TAKER_ALLOWANCE);
|
||||
});
|
||||
it('should throw when maker balance is less than maker fill amount', async () => {
|
||||
await zeroEx.token.transferAsync(
|
||||
makerTokenAddress, makerAddress, coinbase, balanceToSubtractFromMaker,
|
||||
);
|
||||
zeroEx.setTransactionSenderAccount(takerAddress);
|
||||
return expect(zeroEx.exchange.fillOrderAsync(
|
||||
signedOrder, fillTakerAmount, shouldCheckTransfer,
|
||||
)).to.be.rejectedWith(ExchangeContractErrs.INSUFFICIENT_MAKER_BALANCE);
|
||||
});
|
||||
it('should throw when maker allowance is less than maker fill amount', async () => {
|
||||
const newAllowanceWhichIsLessThanFillAmount = fillTakerAmount.minus(lackingAllowance);
|
||||
await zeroEx.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress,
|
||||
newAllowanceWhichIsLessThanFillAmount);
|
||||
zeroEx.setTransactionSenderAccount(takerAddress);
|
||||
return expect(zeroEx.exchange.fillOrderAsync(
|
||||
signedOrder, fillTakerAmount, shouldCheckTransfer,
|
||||
)).to.be.rejectedWith(ExchangeContractErrs.INSUFFICIENT_MAKER_ALLOWANCE);
|
||||
});
|
||||
});
|
||||
it('should throw when taker allowance is less than fill amount', async () => {
|
||||
const fillableAmount = new BigNumber(5);
|
||||
const signedOrder = await fillScenarios.createAFillableSignedOrderAsync(
|
||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
||||
it('should throw when there a rounding error would have occurred', async () => {
|
||||
const makerAmount = new BigNumber(3);
|
||||
const takerAmount = new BigNumber(5);
|
||||
const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
|
||||
makerAmount, takerAmount,
|
||||
);
|
||||
const newAllowanceWhichIsLessThanFillAmount = fillTakerAmountInBaseUnits.minus(1);
|
||||
await zeroEx.token.setProxyAllowanceAsync(takerTokenAddress, takerAddress,
|
||||
newAllowanceWhichIsLessThanFillAmount);
|
||||
const fillTakerAmountThatCausesRoundingError = new BigNumber(3);
|
||||
zeroEx.setTransactionSenderAccount(takerAddress);
|
||||
return expect(zeroEx.exchange.fillOrderAsync(
|
||||
signedOrder, fillTakerAmountInBaseUnits, shouldCheckTransfer,
|
||||
)).to.be.rejectedWith(FillOrderValidationErrs.NOT_ENOUGH_TAKER_ALLOWANCE);
|
||||
signedOrder, fillTakerAmountThatCausesRoundingError, shouldCheckTransfer,
|
||||
)).to.be.rejectedWith(ExchangeContractErrs.ORDER_FILL_ROUNDING_ERROR);
|
||||
});
|
||||
it('should throw when maker balance is less than maker fill amount', async () => {
|
||||
describe('should throw when not enough balance or allowance to pay fees', () => {
|
||||
const fillableAmount = new BigNumber(5);
|
||||
const signedOrder = await fillScenarios.createAFillableSignedOrderAsync(
|
||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
||||
);
|
||||
const lackingMakerBalance = new BigNumber(3);
|
||||
await zeroEx.token.transferAsync(makerTokenAddress, makerAddress, coinBase, lackingMakerBalance);
|
||||
zeroEx.setTransactionSenderAccount(takerAddress);
|
||||
return expect(zeroEx.exchange.fillOrderAsync(
|
||||
signedOrder, fillTakerAmountInBaseUnits, shouldCheckTransfer,
|
||||
)).to.be.rejectedWith(FillOrderValidationErrs.NOT_ENOUGH_MAKER_BALANCE);
|
||||
});
|
||||
it('should throw when maker allowance is less than maker fill amount', async () => {
|
||||
const fillableAmount = new BigNumber(5);
|
||||
const signedOrder = await fillScenarios.createAFillableSignedOrderAsync(
|
||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
||||
);
|
||||
const newAllowanceWhichIsLessThanFillAmount = fillTakerAmountInBaseUnits.minus(1);
|
||||
await zeroEx.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress,
|
||||
newAllowanceWhichIsLessThanFillAmount);
|
||||
zeroEx.setTransactionSenderAccount(takerAddress);
|
||||
return expect(zeroEx.exchange.fillOrderAsync(
|
||||
signedOrder, fillTakerAmountInBaseUnits, shouldCheckTransfer,
|
||||
)).to.be.rejectedWith(FillOrderValidationErrs.NOT_ENOUGH_MAKER_ALLOWANCE);
|
||||
const makerFee = new BigNumber(2);
|
||||
const takerFee = new BigNumber(2);
|
||||
let signedOrder: SignedOrder;
|
||||
beforeEach('setup', async () => {
|
||||
signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||
makerTokenAddress, takerTokenAddress, makerFee, takerFee,
|
||||
makerAddress, takerAddress, fillableAmount, feeRecipient,
|
||||
);
|
||||
zeroEx.setTransactionSenderAccount(takerAddress);
|
||||
});
|
||||
it('should throw when maker doesn\'t have enough balance to pay fees', async () => {
|
||||
const balanceToSubtractFromMaker = new BigNumber(1);
|
||||
await zeroEx.token.transferAsync(
|
||||
zrxTokenAddress, makerAddress, coinbase, balanceToSubtractFromMaker,
|
||||
);
|
||||
return expect(zeroEx.exchange.fillOrderAsync(
|
||||
signedOrder, fillTakerAmount, shouldCheckTransfer,
|
||||
)).to.be.rejectedWith(ExchangeContractErrs.INSUFFICIENT_MAKER_FEE_BALANCE);
|
||||
});
|
||||
it('should throw when maker doesn\'t have enough allowance to pay fees', async () => {
|
||||
const newAllowanceWhichIsLessThanFees = makerFee.minus(1);
|
||||
await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, makerAddress,
|
||||
newAllowanceWhichIsLessThanFees);
|
||||
return expect(zeroEx.exchange.fillOrderAsync(
|
||||
signedOrder, fillTakerAmount, shouldCheckTransfer,
|
||||
)).to.be.rejectedWith(ExchangeContractErrs.INSUFFICIENT_MAKER_FEE_ALLOWANCE);
|
||||
});
|
||||
it('should throw when taker doesn\'t have enough balance to pay fees', async () => {
|
||||
const balanceToSubtractFromTaker = new BigNumber(1);
|
||||
await zeroEx.token.transferAsync(
|
||||
zrxTokenAddress, takerAddress, coinbase, balanceToSubtractFromTaker,
|
||||
);
|
||||
return expect(zeroEx.exchange.fillOrderAsync(
|
||||
signedOrder, fillTakerAmount, shouldCheckTransfer,
|
||||
)).to.be.rejectedWith(ExchangeContractErrs.INSUFFICIENT_TAKER_FEE_BALANCE);
|
||||
});
|
||||
it('should throw when taker doesn\'t have enough allowance to pay fees', async () => {
|
||||
const newAllowanceWhichIsLessThanFees = makerFee.minus(1);
|
||||
await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, takerAddress,
|
||||
newAllowanceWhichIsLessThanFees);
|
||||
return expect(zeroEx.exchange.fillOrderAsync(
|
||||
signedOrder, fillTakerAmount, shouldCheckTransfer,
|
||||
)).to.be.rejectedWith(ExchangeContractErrs.INSUFFICIENT_TAKER_FEE_ALLOWANCE);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('successful fills', () => {
|
||||
it('should fill the valid order', async () => {
|
||||
it('should fill a valid order', async () => {
|
||||
const fillableAmount = new BigNumber(5);
|
||||
const signedOrder = await fillScenarios.createAFillableSignedOrderAsync(
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
||||
);
|
||||
|
||||
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress))
|
||||
.to.be.bignumber.equal(fillableAmount);
|
||||
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress))
|
||||
@@ -224,19 +287,19 @@ describe('ExchangeWrapper', () => {
|
||||
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress))
|
||||
.to.be.bignumber.equal(fillableAmount);
|
||||
zeroEx.setTransactionSenderAccount(takerAddress);
|
||||
await zeroEx.exchange.fillOrderAsync(signedOrder, fillTakerAmountInBaseUnits, shouldCheckTransfer);
|
||||
await zeroEx.exchange.fillOrderAsync(signedOrder, fillTakerAmount, shouldCheckTransfer);
|
||||
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress))
|
||||
.to.be.bignumber.equal(fillableAmount.minus(fillTakerAmountInBaseUnits));
|
||||
.to.be.bignumber.equal(fillableAmount.minus(fillTakerAmount));
|
||||
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress))
|
||||
.to.be.bignumber.equal(fillTakerAmountInBaseUnits);
|
||||
.to.be.bignumber.equal(fillTakerAmount);
|
||||
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress))
|
||||
.to.be.bignumber.equal(fillTakerAmountInBaseUnits);
|
||||
.to.be.bignumber.equal(fillTakerAmount);
|
||||
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress))
|
||||
.to.be.bignumber.equal(fillableAmount.minus(fillTakerAmountInBaseUnits));
|
||||
.to.be.bignumber.equal(fillableAmount.minus(fillTakerAmount));
|
||||
});
|
||||
it('should partially fill the valid order', async () => {
|
||||
const fillableAmount = new BigNumber(5);
|
||||
const signedOrder = await fillScenarios.createAFillableSignedOrderAsync(
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
||||
);
|
||||
const partialFillAmount = new BigNumber(3);
|
||||
@@ -251,6 +314,19 @@ describe('ExchangeWrapper', () => {
|
||||
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress))
|
||||
.to.be.bignumber.equal(fillableAmount.minus(partialFillAmount));
|
||||
});
|
||||
it('should fill the valid orders with fees', async () => {
|
||||
const fillableAmount = new BigNumber(5);
|
||||
const makerFee = new BigNumber(1);
|
||||
const takerFee = new BigNumber(2);
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||
makerTokenAddress, takerTokenAddress, makerFee, takerFee,
|
||||
makerAddress, takerAddress, fillableAmount, feeRecipient,
|
||||
);
|
||||
zeroEx.setTransactionSenderAccount(takerAddress);
|
||||
await zeroEx.exchange.fillOrderAsync(signedOrder, fillTakerAmount, shouldCheckTransfer);
|
||||
expect(await zeroEx.token.getBalanceAsync(zrxTokenAddress, feeRecipient))
|
||||
.to.be.bignumber.equal(makerFee.plus(takerFee));
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('tests that require partially filled order', () => {
|
||||
|
@@ -2,47 +2,64 @@ import * as BigNumber from 'bignumber.js';
|
||||
import {ZeroEx} from '../../src/0x.js';
|
||||
import {Token, SignedOrder} from '../../src/types';
|
||||
import {orderFactory} from '../utils/order_factory';
|
||||
import {constants} from './constants';
|
||||
|
||||
export class FillScenarios {
|
||||
private zeroEx: ZeroEx;
|
||||
private userAddresses: string[];
|
||||
private tokens: Token[];
|
||||
private coinBase: string;
|
||||
constructor(zeroEx: ZeroEx, userAddresses: string[], tokens: Token[]) {
|
||||
private coinbase: string;
|
||||
private zrxTokenAddress: string;
|
||||
constructor(zeroEx: ZeroEx, userAddresses: string[], tokens: Token[], zrxTokenAddress: string) {
|
||||
this.zeroEx = zeroEx;
|
||||
this.userAddresses = userAddresses;
|
||||
this.tokens = tokens;
|
||||
this.coinBase = userAddresses[0];
|
||||
this.coinbase = userAddresses[0];
|
||||
this.zrxTokenAddress = zrxTokenAddress;
|
||||
}
|
||||
public async createAFillableSignedOrderAsync(makerTokenAddress: string, takerTokenAddress: string,
|
||||
makerAddress: string, takerAddress: string,
|
||||
fillableAmount: BigNumber.BigNumber,
|
||||
expirationUnixTimestampSec?: BigNumber.BigNumber):
|
||||
public async createFillableSignedOrderAsync(makerTokenAddress: string, takerTokenAddress: string,
|
||||
makerAddress: string, takerAddress: string,
|
||||
fillableAmount: BigNumber.BigNumber,
|
||||
expirationUnixTimestampSec?: BigNumber.BigNumber):
|
||||
Promise<SignedOrder> {
|
||||
await this.zeroEx.token.transferAsync(makerTokenAddress, this.coinBase, makerAddress, fillableAmount);
|
||||
await this.zeroEx.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, fillableAmount);
|
||||
await this.zeroEx.token.transferAsync(takerTokenAddress, this.coinBase, takerAddress, fillableAmount);
|
||||
await this.zeroEx.token.setProxyAllowanceAsync(takerTokenAddress, takerAddress, fillableAmount);
|
||||
|
||||
const transactionSenderAccount = await this.zeroEx.getTransactionSenderAccountIfExistsAsync();
|
||||
this.zeroEx.setTransactionSenderAccount(makerAddress);
|
||||
const signedOrder = await orderFactory.createSignedOrderAsync(this.zeroEx, makerAddress,
|
||||
takerAddress, fillableAmount, makerTokenAddress, fillableAmount, takerTokenAddress,
|
||||
expirationUnixTimestampSec);
|
||||
this.zeroEx.setTransactionSenderAccount(transactionSenderAccount as string);
|
||||
return signedOrder;
|
||||
return this.createAsymmetricFillableSignedOrderAsync(
|
||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
|
||||
fillableAmount, fillableAmount, expirationUnixTimestampSec,
|
||||
);
|
||||
}
|
||||
public async createFillableSignedOrderWithFeesAsync(
|
||||
makerTokenAddress: string, takerTokenAddress: string,
|
||||
makerFee: BigNumber.BigNumber, takerFee: BigNumber.BigNumber,
|
||||
makerAddress: string, takerAddress: string,
|
||||
fillableAmount: BigNumber.BigNumber,
|
||||
feeRecepient: string, expirationUnixTimestampSec?: BigNumber.BigNumber,
|
||||
): Promise<SignedOrder> {
|
||||
return this.createAsymmetricFillableSignedOrderWithFeesAsync(
|
||||
makerTokenAddress, takerTokenAddress, makerFee, takerFee, makerAddress, takerAddress,
|
||||
fillableAmount, fillableAmount, feeRecepient, expirationUnixTimestampSec,
|
||||
);
|
||||
}
|
||||
public async createAsymmetricFillableSignedOrderAsync(
|
||||
makerTokenAddress: string, takerTokenAddress: string, makerAddress: string, takerAddress: string,
|
||||
makerFillableAmount: BigNumber.BigNumber, takerFillableAmount: BigNumber.BigNumber,
|
||||
expirationUnixTimestampSec?: BigNumber.BigNumber): Promise<SignedOrder> {
|
||||
const makerFee = new BigNumber(0);
|
||||
const takerFee = new BigNumber(0);
|
||||
const feeRecepient = constants.NULL_ADDRESS;
|
||||
return this.createAsymmetricFillableSignedOrderWithFeesAsync(
|
||||
makerTokenAddress, takerTokenAddress, makerFee, takerFee, makerAddress, takerAddress,
|
||||
makerFillableAmount, takerFillableAmount, feeRecepient, expirationUnixTimestampSec,
|
||||
);
|
||||
}
|
||||
public async createPartiallyFilledSignedOrderAsync(makerTokenAddress: string, takerTokenAddress: string,
|
||||
takerAddress: string, fillableAmount: BigNumber.BigNumber,
|
||||
partialFillAmount: BigNumber.BigNumber) {
|
||||
const prevSenderAccount = await this.zeroEx.getTransactionSenderAccountIfExistsAsync();
|
||||
const [makerAddress] = this.userAddresses;
|
||||
await this.zeroEx.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, fillableAmount);
|
||||
await this.zeroEx.token.transferAsync(takerTokenAddress, makerAddress, takerAddress, fillableAmount);
|
||||
await this.zeroEx.token.setProxyAllowanceAsync(takerTokenAddress, takerAddress, fillableAmount);
|
||||
|
||||
const signedOrder = await orderFactory.createSignedOrderAsync(this.zeroEx, makerAddress,
|
||||
takerAddress, fillableAmount, makerTokenAddress, fillableAmount, takerTokenAddress);
|
||||
const signedOrder = await this.createAsymmetricFillableSignedOrderAsync(
|
||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
|
||||
fillableAmount, fillableAmount,
|
||||
);
|
||||
|
||||
this.zeroEx.setTransactionSenderAccount(takerAddress);
|
||||
const shouldCheckTransfer = false;
|
||||
@@ -52,4 +69,34 @@ export class FillScenarios {
|
||||
this.zeroEx.setTransactionSenderAccount(prevSenderAccount as string);
|
||||
return signedOrder;
|
||||
}
|
||||
private async createAsymmetricFillableSignedOrderWithFeesAsync(
|
||||
makerTokenAddress: string, takerTokenAddress: string,
|
||||
makerFee: BigNumber.BigNumber, takerFee: BigNumber.BigNumber,
|
||||
makerAddress: string, takerAddress: string,
|
||||
makerFillableAmount: BigNumber.BigNumber, takerFillableAmount: BigNumber.BigNumber,
|
||||
feeRecepient: string, expirationUnixTimestampSec?: BigNumber.BigNumber): Promise<SignedOrder> {
|
||||
await this.zeroEx.token.transferAsync(makerTokenAddress, this.coinbase, makerAddress, makerFillableAmount);
|
||||
await this.zeroEx.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, makerFillableAmount);
|
||||
await this.zeroEx.token.transferAsync(takerTokenAddress, this.coinbase, takerAddress, takerFillableAmount);
|
||||
await this.zeroEx.token.setProxyAllowanceAsync(takerTokenAddress, takerAddress, takerFillableAmount);
|
||||
|
||||
if (!makerFee.isZero()) {
|
||||
await this.zeroEx.token.transferAsync(this.zrxTokenAddress, this.coinbase, makerAddress, makerFee);
|
||||
await this.zeroEx.token.setProxyAllowanceAsync(this.zrxTokenAddress, makerAddress, makerFee);
|
||||
}
|
||||
if (!takerFee.isZero()) {
|
||||
await this.zeroEx.token.transferAsync(this.zrxTokenAddress, this.coinbase, takerAddress, takerFee);
|
||||
await this.zeroEx.token.setProxyAllowanceAsync(this.zrxTokenAddress, takerAddress, takerFee);
|
||||
}
|
||||
|
||||
const prevTransactionSenderAccount = await this.zeroEx.getTransactionSenderAccountIfExistsAsync();
|
||||
this.zeroEx.setTransactionSenderAccount(makerAddress);
|
||||
const signedOrder = await orderFactory.createSignedOrderAsync(this.zeroEx,
|
||||
makerAddress, takerAddress, makerFee, takerFee,
|
||||
makerFillableAmount, makerTokenAddress, takerFillableAmount, takerTokenAddress,
|
||||
feeRecepient, expirationUnixTimestampSec);
|
||||
// We re-set the transactionSender to avoid introducing side-effects
|
||||
this.zeroEx.setTransactionSenderAccount(prevTransactionSenderAccount as string);
|
||||
return signedOrder;
|
||||
}
|
||||
}
|
||||
|
@@ -10,10 +10,13 @@ export const orderFactory = {
|
||||
zeroEx: ZeroEx,
|
||||
maker: string,
|
||||
taker: string,
|
||||
makerTokenAmount: BigNumber.BigNumber|number,
|
||||
makerFee: BigNumber.BigNumber,
|
||||
takerFee: BigNumber.BigNumber,
|
||||
makerTokenAmount: BigNumber.BigNumber,
|
||||
makerTokenAddress: string,
|
||||
takerTokenAmount: BigNumber.BigNumber|number,
|
||||
takerTokenAmount: BigNumber.BigNumber,
|
||||
takerTokenAddress: string,
|
||||
feeRecipient: string,
|
||||
expirationUnixTimestampSec?: BigNumber.BigNumber): Promise<SignedOrder> {
|
||||
const defaultExpirationUnixTimestampSec = new BigNumber(2524604400); // Close to infinite
|
||||
expirationUnixTimestampSec = _.isUndefined(expirationUnixTimestampSec) ?
|
||||
@@ -22,14 +25,14 @@ export const orderFactory = {
|
||||
const order = {
|
||||
maker,
|
||||
taker,
|
||||
makerFee: new BigNumber(0),
|
||||
takerFee: new BigNumber(0),
|
||||
makerTokenAmount: _.isNumber(makerTokenAmount) ? new BigNumber(makerTokenAmount) : makerTokenAmount,
|
||||
takerTokenAmount: _.isNumber(takerTokenAmount) ? new BigNumber(takerTokenAmount) : takerTokenAmount,
|
||||
makerFee,
|
||||
takerFee,
|
||||
makerTokenAmount,
|
||||
takerTokenAmount,
|
||||
makerTokenAddress,
|
||||
takerTokenAddress,
|
||||
salt: ZeroEx.generatePseudoRandomSalt(),
|
||||
feeRecipient: constants.NULL_ADDRESS,
|
||||
feeRecipient,
|
||||
expirationUnixTimestampSec,
|
||||
};
|
||||
const orderHash = await zeroEx.getOrderHashHexAsync(order);
|
||||
|
24
test/utils/token_utils.ts
Normal file
24
test/utils/token_utils.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import * as _ from 'lodash';
|
||||
import {Token, ZeroExError} from '../../src/types';
|
||||
|
||||
const PROTOCOL_TOKEN_SYMBOL = 'ZRX';
|
||||
|
||||
export class TokenUtils {
|
||||
private tokens: Token[];
|
||||
constructor(tokens: Token[]) {
|
||||
this.tokens = tokens;
|
||||
}
|
||||
public getProtocolTokenOrThrow(): Token {
|
||||
const zrxToken = _.find(this.tokens, {symbol: PROTOCOL_TOKEN_SYMBOL});
|
||||
if (_.isUndefined(zrxToken)) {
|
||||
throw new Error(ZeroExError.ZRX_NOT_IN_TOKEN_REGISTRY);
|
||||
}
|
||||
return zrxToken;
|
||||
}
|
||||
public getNonProtocolTokens(): Token[] {
|
||||
const nonProtocolTokens = _.filter(this.tokens, token => {
|
||||
return token.symbol !== PROTOCOL_TOKEN_SYMBOL;
|
||||
});
|
||||
return nonProtocolTokens;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user