Update fill-scenarios for V2 and add CHANGELOG entry

This commit is contained in:
Fabio Berger
2018-06-04 20:54:39 +01:00
parent 321c0a8537
commit 6cd5bf31c9
2 changed files with 91 additions and 64 deletions

View File

@@ -1,4 +1,12 @@
[ [
{
"version": "0.1.0",
"changes": [
{
"note": "Make fill-scenarios compatible with V2 of 0x protocol"
}
]
},
{ {
"timestamp": 1527008544, "timestamp": 1527008544,
"version": "0.0.2", "version": "0.0.2",

View File

@@ -1,14 +1,15 @@
import { formatters, orderFactory } from '@0xproject/order-utils'; import { assetProxyUtils, orderFactory } from '@0xproject/order-utils';
import { Provider, SignedOrder, Token } from '@0xproject/types'; import { SignedOrder, Token } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils'; import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper'; import { Web3Wrapper } from '@0xproject/web3-wrapper';
import { Provider } from 'ethereum-types';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { artifacts } from './artifacts'; import { artifacts } from './artifacts';
import { constants } from './constants'; import { constants } from './constants';
import { DummyTokenContract } from './generated_contract_wrappers/dummy_token'; import { DummyERC20TokenContract } from './generated_contract_wrappers/dummy_e_r_c20_token';
import { ERC20TokenContract } from './generated_contract_wrappers/e_r_c20_token';
import { ExchangeContract } from './generated_contract_wrappers/exchange'; import { ExchangeContract } from './generated_contract_wrappers/exchange';
import { TokenContract } from './generated_contract_wrappers/token';
const INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS = new BigNumber(100); const INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS = new BigNumber(100);
@@ -18,25 +19,25 @@ export class FillScenarios {
private _tokens: Token[]; private _tokens: Token[];
private _coinbase: string; private _coinbase: string;
private _zrxTokenAddress: string; private _zrxTokenAddress: string;
private _exchangeContractAddress: string; private _exchangeAddress: string;
constructor( constructor(
provider: Provider, provider: Provider,
userAddresses: string[], userAddresses: string[],
tokens: Token[], tokens: Token[],
zrxTokenAddress: string, zrxTokenAddress: string,
exchangeContractAddress: string, exchangeAddress: string,
) { ) {
this._web3Wrapper = new Web3Wrapper(provider); this._web3Wrapper = new Web3Wrapper(provider);
this._userAddresses = userAddresses; this._userAddresses = userAddresses;
this._tokens = tokens; this._tokens = tokens;
this._coinbase = userAddresses[0]; this._coinbase = userAddresses[0];
this._zrxTokenAddress = zrxTokenAddress; this._zrxTokenAddress = zrxTokenAddress;
this._exchangeContractAddress = exchangeContractAddress; this._exchangeAddress = exchangeAddress;
} }
public async initTokenBalancesAsync(): Promise<void> { public async initTokenBalancesAsync(): Promise<void> {
for (const token of this._tokens) { for (const token of this._tokens) {
if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') { if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') {
const dummyToken = new DummyTokenContract( const dummyERC20Token = new DummyERC20TokenContract(
artifacts.DummyToken.abi, artifacts.DummyToken.abi,
token.address, token.address,
this._web3Wrapper.getProvider(), this._web3Wrapper.getProvider(),
@@ -46,7 +47,7 @@ export class FillScenarios {
INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS, INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS,
token.decimals, token.decimals,
); );
const txHash = await dummyToken.setBalance.sendTransactionAsync(this._coinbase, tokenSupply, { const txHash = await dummyERC20Token.setBalance.sendTransactionAsync(this._coinbase, tokenSupply, {
from: this._coinbase, from: this._coinbase,
}); });
await this._web3Wrapper.awaitTransactionSuccessAsync(txHash); await this._web3Wrapper.awaitTransactionSuccessAsync(txHash);
@@ -54,148 +55,162 @@ export class FillScenarios {
} }
} }
public async createFillableSignedOrderAsync( public async createFillableSignedOrderAsync(
makerTokenAddress: string, makerAssetData: string,
takerTokenAddress: string, takerAssetData: string,
makerAddress: string, makerAddress: string,
takerAddress: string, takerAddress: string,
fillableAmount: BigNumber, fillableAmount: BigNumber,
expirationUnixTimestampSec?: BigNumber, expirationTimeSeconds?: BigNumber,
): Promise<SignedOrder> { ): Promise<SignedOrder> {
return this.createAsymmetricFillableSignedOrderAsync( return this.createAsymmetricFillableSignedOrderAsync(
makerTokenAddress, makerAssetData,
takerTokenAddress, takerAssetData,
makerAddress, makerAddress,
takerAddress, takerAddress,
fillableAmount, fillableAmount,
fillableAmount, fillableAmount,
expirationUnixTimestampSec, expirationTimeSeconds,
); );
} }
public async createFillableSignedOrderWithFeesAsync( public async createFillableSignedOrderWithFeesAsync(
makerTokenAddress: string, makerAssetData: string,
takerTokenAddress: string, takerAssetData: string,
makerFee: BigNumber, makerFee: BigNumber,
takerFee: BigNumber, takerFee: BigNumber,
makerAddress: string, makerAddress: string,
takerAddress: string, takerAddress: string,
fillableAmount: BigNumber, fillableAmount: BigNumber,
feeRecepient: string, feeRecepientAddress: string,
expirationUnixTimestampSec?: BigNumber, expirationTimeSeconds?: BigNumber,
): Promise<SignedOrder> { ): Promise<SignedOrder> {
return this._createAsymmetricFillableSignedOrderWithFeesAsync( return this._createAsymmetricFillableSignedOrderWithFeesAsync(
makerTokenAddress, makerAssetData,
takerTokenAddress, takerAssetData,
makerFee, makerFee,
takerFee, takerFee,
makerAddress, makerAddress,
takerAddress, takerAddress,
fillableAmount, fillableAmount,
fillableAmount, fillableAmount,
feeRecepient, feeRecepientAddress,
expirationUnixTimestampSec, expirationTimeSeconds,
); );
} }
public async createAsymmetricFillableSignedOrderAsync( public async createAsymmetricFillableSignedOrderAsync(
makerTokenAddress: string, makerAssetData: string,
takerTokenAddress: string, takerAssetData: string,
makerAddress: string, makerAddress: string,
takerAddress: string, takerAddress: string,
makerFillableAmount: BigNumber, makerFillableAmount: BigNumber,
takerFillableAmount: BigNumber, takerFillableAmount: BigNumber,
expirationUnixTimestampSec?: BigNumber, expirationTimeSeconds?: BigNumber,
): Promise<SignedOrder> { ): Promise<SignedOrder> {
const makerFee = new BigNumber(0); const makerFee = new BigNumber(0);
const takerFee = new BigNumber(0); const takerFee = new BigNumber(0);
const feeRecepient = constants.NULL_ADDRESS; const feeRecepientAddress = constants.NULL_ADDRESS;
return this._createAsymmetricFillableSignedOrderWithFeesAsync( return this._createAsymmetricFillableSignedOrderWithFeesAsync(
makerTokenAddress, makerAssetData,
takerTokenAddress, takerAssetData,
makerFee, makerFee,
takerFee, takerFee,
makerAddress, makerAddress,
takerAddress, takerAddress,
makerFillableAmount, makerFillableAmount,
takerFillableAmount, takerFillableAmount,
feeRecepient, feeRecepientAddress,
expirationUnixTimestampSec, expirationTimeSeconds,
); );
} }
public async createPartiallyFilledSignedOrderAsync( public async createPartiallyFilledSignedOrderAsync(
makerTokenAddress: string, makerAssetData: string,
takerTokenAddress: string, takerAssetData: string,
takerAddress: string, takerAddress: string,
fillableAmount: BigNumber, fillableAmount: BigNumber,
partialFillAmount: BigNumber, partialFillAmount: BigNumber,
): Promise<SignedOrder> { ): Promise<SignedOrder> {
const [makerAddress] = this._userAddresses; const [makerAddress] = this._userAddresses;
const signedOrder = await this.createAsymmetricFillableSignedOrderAsync( const signedOrder = await this.createAsymmetricFillableSignedOrderAsync(
makerTokenAddress, makerAssetData,
takerTokenAddress, takerAssetData,
makerAddress, makerAddress,
takerAddress, takerAddress,
fillableAmount, fillableAmount,
fillableAmount, fillableAmount,
); );
const shouldThrowOnInsufficientBalanceOrAllowance = false;
const exchangeInstance = new ExchangeContract( const exchangeInstance = new ExchangeContract(
artifacts.Exchange.abi, artifacts.Exchange.abi,
signedOrder.exchangeContractAddress, signedOrder.exchangeAddress,
this._web3Wrapper.getProvider(), this._web3Wrapper.getProvider(),
this._web3Wrapper.getContractDefaults(), this._web3Wrapper.getContractDefaults(),
); );
const [orderAddresses, orderValues] = formatters.getOrderAddressesAndValues(signedOrder); const orderWithoutExchangeAddress = {
senderAddress: signedOrder.senderAddress,
makerAddress: signedOrder.makerAddress,
takerAddress: signedOrder.takerAddress,
feeRecipientAddress: signedOrder.feeRecipientAddress,
makerAssetAmount: signedOrder.makerAssetAmount,
takerAssetAmount: signedOrder.takerAssetAmount,
makerFee: signedOrder.makerFee,
takerFee: signedOrder.takerFee,
expirationTimeSeconds: signedOrder.expirationTimeSeconds,
salt: signedOrder.salt,
makerAssetData: signedOrder.makerAssetData,
takerAssetData: signedOrder.takerAssetData,
};
await exchangeInstance.fillOrder.sendTransactionAsync( await exchangeInstance.fillOrder.sendTransactionAsync(
orderAddresses, orderWithoutExchangeAddress,
orderValues,
partialFillAmount, partialFillAmount,
shouldThrowOnInsufficientBalanceOrAllowance, signedOrder.signature,
signedOrder.ecSignature.v,
signedOrder.ecSignature.r,
signedOrder.ecSignature.s,
{ from: takerAddress }, { from: takerAddress },
); );
return signedOrder; return signedOrder;
} }
private async _createAsymmetricFillableSignedOrderWithFeesAsync( private async _createAsymmetricFillableSignedOrderWithFeesAsync(
makerTokenAddress: string, makerAssetData: string,
takerTokenAddress: string, takerAssetData: string,
makerFee: BigNumber, makerFee: BigNumber,
takerFee: BigNumber, takerFee: BigNumber,
makerAddress: string, makerAddress: string,
takerAddress: string, takerAddress: string,
makerFillableAmount: BigNumber, makerFillableAmount: BigNumber,
takerFillableAmount: BigNumber, takerFillableAmount: BigNumber,
feeRecepient: string, feeRecepientAddress: string,
expirationUnixTimestampSec?: BigNumber, expirationTimeSeconds?: BigNumber,
): Promise<SignedOrder> { ): Promise<SignedOrder> {
const makerERC20ProxyData = assetProxyUtils.decodeERC20ProxyData(makerAssetData);
const makerTokenAddress = makerERC20ProxyData.tokenAddress;
const takerERC20ProxyData = assetProxyUtils.decodeERC20ProxyData(takerAssetData);
const takerTokenAddress = takerERC20ProxyData.tokenAddress;
await Promise.all([ await Promise.all([
this._increaseBalanceAndAllowanceAsync(makerTokenAddress, makerAddress, makerFillableAmount), this._increaseERC20BalanceAndAllowanceAsync(makerTokenAddress, makerAddress, makerFillableAmount),
this._increaseBalanceAndAllowanceAsync(takerTokenAddress, takerAddress, takerFillableAmount), this._increaseERC20BalanceAndAllowanceAsync(takerTokenAddress, takerAddress, takerFillableAmount),
]); ]);
await Promise.all([ await Promise.all([
this._increaseBalanceAndAllowanceAsync(this._zrxTokenAddress, makerAddress, makerFee), this._increaseERC20BalanceAndAllowanceAsync(this._zrxTokenAddress, makerAddress, makerFee),
this._increaseBalanceAndAllowanceAsync(this._zrxTokenAddress, takerAddress, takerFee), this._increaseERC20BalanceAndAllowanceAsync(this._zrxTokenAddress, takerAddress, takerFee),
]); ]);
const senderAddress = constants.NULL_ADDRESS;
const signedOrder = await orderFactory.createSignedOrderAsync( const signedOrder = await orderFactory.createSignedOrderAsync(
this._web3Wrapper.getProvider(), this._web3Wrapper.getProvider(),
makerAddress, makerAddress,
takerAddress, takerAddress,
senderAddress,
makerFee, makerFee,
takerFee, takerFee,
makerFillableAmount, makerFillableAmount,
makerTokenAddress, makerAssetData,
takerFillableAmount, takerFillableAmount,
takerTokenAddress, takerAssetData,
this._exchangeContractAddress, this._exchangeAddress,
feeRecepient, feeRecepientAddress,
expirationUnixTimestampSec, expirationTimeSeconds,
); );
return signedOrder; return signedOrder;
} }
private async _increaseBalanceAndAllowanceAsync( private async _increaseERC20BalanceAndAllowanceAsync(
tokenAddress: string, tokenAddress: string,
address: string, address: string,
amount: BigNumber, amount: BigNumber,
@@ -204,12 +219,12 @@ export class FillScenarios {
return; // noop return; // noop
} }
await Promise.all([ await Promise.all([
this._increaseBalanceAsync(tokenAddress, address, amount), this._increaseERC20BalanceAsync(tokenAddress, address, amount),
this._increaseAllowanceAsync(tokenAddress, address, amount), this._increaseERC20AllowanceAsync(tokenAddress, address, amount),
]); ]);
} }
private async _increaseBalanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> { private async _increaseERC20BalanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
const token = new TokenContract( const token = new ERC20TokenContract(
artifacts.Token.abi, artifacts.Token.abi,
tokenAddress, tokenAddress,
this._web3Wrapper.getProvider(), this._web3Wrapper.getProvider(),
@@ -219,8 +234,12 @@ export class FillScenarios {
from: this._coinbase, from: this._coinbase,
}); });
} }
private async _increaseAllowanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> { private async _increaseERC20AllowanceAsync(
const tokenInstance = new TokenContract( tokenAddress: string,
address: string,
amount: BigNumber,
): Promise<void> {
const tokenInstance = new ERC20TokenContract(
artifacts.Token.abi, artifacts.Token.abi,
tokenAddress, tokenAddress,
this._web3Wrapper.getProvider(), this._web3Wrapper.getProvider(),