aboutsummaryrefslogtreecommitdiffstats
path: root/packages/fill-scenarios/src/index.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/fill-scenarios/src/index.ts')
-rw-r--r--packages/fill-scenarios/src/index.ts242
1 files changed, 242 insertions, 0 deletions
diff --git a/packages/fill-scenarios/src/index.ts b/packages/fill-scenarios/src/index.ts
new file mode 100644
index 000000000..9f1b68ef2
--- /dev/null
+++ b/packages/fill-scenarios/src/index.ts
@@ -0,0 +1,242 @@
+import { formatters, orderFactory } from '@0xproject/order-utils';
+import { Provider, SignedOrder, Token } from '@0xproject/types';
+import { BigNumber } from '@0xproject/utils';
+import { Web3Wrapper } from '@0xproject/web3-wrapper';
+import * as _ from 'lodash';
+
+import { artifacts } from './artifacts';
+import { constants } from './constants';
+import { DummyTokenContract } from './generated_contract_wrappers/dummy_token';
+import { ExchangeContract } from './generated_contract_wrappers/exchange';
+import { TokenContract } from './generated_contract_wrappers/token';
+
+const INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS = new BigNumber(100);
+
+export class FillScenarios {
+ private _web3Wrapper: Web3Wrapper;
+ private _userAddresses: string[];
+ private _tokens: Token[];
+ private _coinbase: string;
+ private _zrxTokenAddress: string;
+ private _exchangeContractAddress: string;
+ constructor(
+ provider: Provider,
+ userAddresses: string[],
+ tokens: Token[],
+ zrxTokenAddress: string,
+ exchangeContractAddress: string,
+ ) {
+ this._web3Wrapper = new Web3Wrapper(provider);
+ this._userAddresses = userAddresses;
+ this._tokens = tokens;
+ this._coinbase = userAddresses[0];
+ this._zrxTokenAddress = zrxTokenAddress;
+ this._exchangeContractAddress = exchangeContractAddress;
+ }
+ public async initTokenBalancesAsync() {
+ for (const token of this._tokens) {
+ if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') {
+ const dummyToken = new DummyTokenContract(
+ artifacts.DummyToken.abi,
+ token.address,
+ this._web3Wrapper.getProvider(),
+ this._web3Wrapper.getContractDefaults(),
+ );
+ const tokenSupply = Web3Wrapper.toBaseUnitAmount(
+ INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS,
+ token.decimals,
+ );
+ const txHash = await dummyToken.setBalance.sendTransactionAsync(this._coinbase, tokenSupply, {
+ from: this._coinbase,
+ });
+ await this._web3Wrapper.awaitTransactionMinedAsync(txHash);
+ }
+ }
+ }
+ public async createFillableSignedOrderAsync(
+ makerTokenAddress: string,
+ takerTokenAddress: string,
+ makerAddress: string,
+ takerAddress: string,
+ fillableAmount: BigNumber,
+ expirationUnixTimestampSec?: BigNumber,
+ ): Promise<SignedOrder> {
+ return this.createAsymmetricFillableSignedOrderAsync(
+ makerTokenAddress,
+ takerTokenAddress,
+ makerAddress,
+ takerAddress,
+ fillableAmount,
+ fillableAmount,
+ expirationUnixTimestampSec,
+ );
+ }
+ public async createFillableSignedOrderWithFeesAsync(
+ makerTokenAddress: string,
+ takerTokenAddress: string,
+ makerFee: BigNumber,
+ takerFee: BigNumber,
+ makerAddress: string,
+ takerAddress: string,
+ fillableAmount: BigNumber,
+ feeRecepient: string,
+ expirationUnixTimestampSec?: 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,
+ takerFillableAmount: BigNumber,
+ expirationUnixTimestampSec?: 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,
+ partialFillAmount: BigNumber,
+ ) {
+ const [makerAddress] = this._userAddresses;
+ const signedOrder = await this.createAsymmetricFillableSignedOrderAsync(
+ makerTokenAddress,
+ takerTokenAddress,
+ makerAddress,
+ takerAddress,
+ fillableAmount,
+ fillableAmount,
+ );
+ const shouldThrowOnInsufficientBalanceOrAllowance = false;
+ const exchangeInstance = new ExchangeContract(
+ artifacts.Exchange.abi,
+ signedOrder.exchangeContractAddress,
+ this._web3Wrapper.getProvider(),
+ this._web3Wrapper.getContractDefaults(),
+ );
+
+ const [orderAddresses, orderValues] = formatters.getOrderAddressesAndValues(signedOrder);
+
+ await exchangeInstance.fillOrder.sendTransactionAsync(
+ orderAddresses,
+ orderValues,
+ partialFillAmount,
+ shouldThrowOnInsufficientBalanceOrAllowance,
+ signedOrder.ecSignature.v,
+ signedOrder.ecSignature.r,
+ signedOrder.ecSignature.s,
+ { from: takerAddress },
+ );
+ return signedOrder;
+ }
+ private async _createAsymmetricFillableSignedOrderWithFeesAsync(
+ makerTokenAddress: string,
+ takerTokenAddress: string,
+ makerFee: BigNumber,
+ takerFee: BigNumber,
+ makerAddress: string,
+ takerAddress: string,
+ makerFillableAmount: BigNumber,
+ takerFillableAmount: BigNumber,
+ feeRecepient: string,
+ expirationUnixTimestampSec?: BigNumber,
+ ): Promise<SignedOrder> {
+ await Promise.all([
+ this._increaseBalanceAndAllowanceAsync(makerTokenAddress, makerAddress, makerFillableAmount),
+ this._increaseBalanceAndAllowanceAsync(takerTokenAddress, takerAddress, takerFillableAmount),
+ ]);
+ await Promise.all([
+ this._increaseBalanceAndAllowanceAsync(this._zrxTokenAddress, makerAddress, makerFee),
+ this._increaseBalanceAndAllowanceAsync(this._zrxTokenAddress, takerAddress, takerFee),
+ ]);
+
+ const signedOrder = await orderFactory.createSignedOrderAsync(
+ this._web3Wrapper.getProvider(),
+ makerAddress,
+ takerAddress,
+ makerFee,
+ takerFee,
+ makerFillableAmount,
+ makerTokenAddress,
+ takerFillableAmount,
+ takerTokenAddress,
+ this._exchangeContractAddress,
+ feeRecepient,
+ expirationUnixTimestampSec,
+ );
+ return signedOrder;
+ }
+ private async _increaseBalanceAndAllowanceAsync(
+ tokenAddress: string,
+ address: string,
+ amount: BigNumber,
+ ): Promise<void> {
+ if (amount.isZero() || address === constants.NULL_ADDRESS) {
+ return; // noop
+ }
+ await Promise.all([
+ this._increaseBalanceAsync(tokenAddress, address, amount),
+ this._increaseAllowanceAsync(tokenAddress, address, amount),
+ ]);
+ }
+ private async _increaseBalanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
+ const token = new TokenContract(
+ artifacts.Token.abi,
+ tokenAddress,
+ this._web3Wrapper.getProvider(),
+ this._web3Wrapper.getContractDefaults(),
+ );
+ await token.transfer.sendTransactionAsync(address, amount, {
+ from: this._coinbase,
+ });
+ }
+ private async _increaseAllowanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
+ const tokenInstance = new TokenContract(
+ artifacts.Token.abi,
+ tokenAddress,
+ this._web3Wrapper.getProvider(),
+ this._web3Wrapper.getContractDefaults(),
+ );
+ const networkId = await this._web3Wrapper.getNetworkIdAsync();
+ const networkArtifactsIfExists = artifacts.TokenTransferProxy.networks[networkId];
+ if (_.isUndefined(networkArtifactsIfExists)) {
+ throw new Error(`Did not find network artifacts for networkId: ${networkId}`);
+ }
+ const proxyAddress = networkArtifactsIfExists.address;
+ const oldMakerAllowance = await tokenInstance.allowance.callAsync(address, proxyAddress);
+ const newMakerAllowance = oldMakerAllowance.plus(amount);
+
+ await tokenInstance.approve.sendTransactionAsync(proxyAddress, newMakerAllowance, {
+ from: address,
+ });
+ }
+}