Refactor ExchangeTransferSimulator public interface to accet an AbstractBalanceAndProxyAllowanceLazyStore so that this module could be re-used in different contexts.
This commit is contained in:
@@ -0,0 +1,11 @@
|
|||||||
|
import { BigNumber } from '@0xproject/utils';
|
||||||
|
|
||||||
|
export abstract class AbstractBalanceAndProxyAllowanceLazyStore {
|
||||||
|
public abstract async getBalanceAsync(tokenAddress: string, userAddress: string): Promise<BigNumber>;
|
||||||
|
public abstract async getProxyAllowanceAsync(tokenAddress: string, userAddress: string): Promise<BigNumber>;
|
||||||
|
public abstract setBalance(tokenAddress: string, userAddress: string, balance: BigNumber): void;
|
||||||
|
public abstract deleteBalance(tokenAddress: string, userAddress: string): void;
|
||||||
|
public abstract setProxyAllowance(tokenAddress: string, userAddress: string, proxyAllowance: BigNumber): void;
|
||||||
|
public abstract deleteProxyAllowance(tokenAddress: string, userAddress: string): void;
|
||||||
|
public abstract deleteAll(): void;
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ import * as _ from 'lodash';
|
|||||||
import { artifacts } from '../artifacts';
|
import { artifacts } from '../artifacts';
|
||||||
import { SimpleBalanceAndProxyAllowanceFetcher } from '../fetchers/simple_balance_and_proxy_allowance_fetcher';
|
import { SimpleBalanceAndProxyAllowanceFetcher } from '../fetchers/simple_balance_and_proxy_allowance_fetcher';
|
||||||
import { SimpleOrderFilledCancelledFetcher } from '../fetchers/simple_order_filled_cancelled_fetcher';
|
import { SimpleOrderFilledCancelledFetcher } from '../fetchers/simple_order_filled_cancelled_fetcher';
|
||||||
|
import { BalanceAndProxyAllowanceLazyStore } from '../stores/balance_proxy_allowance_lazy_store';
|
||||||
import {
|
import {
|
||||||
BlockRange,
|
BlockRange,
|
||||||
EventCallback,
|
EventCallback,
|
||||||
@@ -177,7 +178,11 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
: orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
|
||||||
|
this._tokenWrapper,
|
||||||
|
BlockParamLiteral.Latest,
|
||||||
|
);
|
||||||
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore);
|
||||||
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
signedOrder,
|
signedOrder,
|
||||||
@@ -252,7 +257,11 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
let filledTakerTokenAmount = new BigNumber(0);
|
let filledTakerTokenAmount = new BigNumber(0);
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
|
||||||
|
this._tokenWrapper,
|
||||||
|
BlockParamLiteral.Latest,
|
||||||
|
);
|
||||||
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore);
|
||||||
for (const signedOrder of signedOrders) {
|
for (const signedOrder of signedOrders) {
|
||||||
const singleFilledTakerTokenAmount = await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
const singleFilledTakerTokenAmount = await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
@@ -345,7 +354,11 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
: orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
|
||||||
|
this._tokenWrapper,
|
||||||
|
BlockParamLiteral.Latest,
|
||||||
|
);
|
||||||
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore);
|
||||||
for (const orderFillRequest of orderFillRequests) {
|
for (const orderFillRequest of orderFillRequests) {
|
||||||
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
@@ -421,7 +434,11 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
: orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
|
||||||
|
this._tokenWrapper,
|
||||||
|
BlockParamLiteral.Latest,
|
||||||
|
);
|
||||||
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore);
|
||||||
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
signedOrder,
|
signedOrder,
|
||||||
@@ -483,7 +500,11 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
: orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
|
||||||
|
this._tokenWrapper,
|
||||||
|
BlockParamLiteral.Latest,
|
||||||
|
);
|
||||||
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore);
|
||||||
for (const orderFillRequest of orderFillRequests) {
|
for (const orderFillRequest of orderFillRequests) {
|
||||||
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
@@ -733,7 +754,11 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const expectedFillTakerTokenAmount = !_.isUndefined(opts) ? opts.expectedFillTakerTokenAmount : undefined;
|
const expectedFillTakerTokenAmount = !_.isUndefined(opts) ? opts.expectedFillTakerTokenAmount : undefined;
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
|
||||||
|
this._tokenWrapper,
|
||||||
|
BlockParamLiteral.Latest,
|
||||||
|
);
|
||||||
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore);
|
||||||
await this._orderValidationUtils.validateOrderFillableOrThrowAsync(
|
await this._orderValidationUtils.validateOrderFillableOrThrowAsync(
|
||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
signedOrder,
|
signedOrder,
|
||||||
@@ -759,7 +784,11 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
const normalizedTakerAddress = takerAddress.toLowerCase();
|
const normalizedTakerAddress = takerAddress.toLowerCase();
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
|
||||||
|
this._tokenWrapper,
|
||||||
|
BlockParamLiteral.Latest,
|
||||||
|
);
|
||||||
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore);
|
||||||
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
signedOrder,
|
signedOrder,
|
||||||
@@ -806,7 +835,11 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
const normalizedTakerAddress = takerAddress.toLowerCase();
|
const normalizedTakerAddress = takerAddress.toLowerCase();
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
|
||||||
|
this._tokenWrapper,
|
||||||
|
BlockParamLiteral.Latest,
|
||||||
|
);
|
||||||
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore);
|
||||||
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
signedOrder,
|
signedOrder,
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { AbstractBalanceAndProxyAllowanceFetcher } from '@0xproject/order-utils';
|
|
||||||
import { BlockParamLiteral } from '@0xproject/types';
|
import { BlockParamLiteral } from '@0xproject/types';
|
||||||
import { BigNumber } from '@0xproject/utils';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
|
import { AbstractBalanceAndProxyAllowanceLazyStore } from '../abstract/abstract_balance_and_proxy_allowance_lazy_store';
|
||||||
import { TokenWrapper } from '../contract_wrappers/token_wrapper';
|
import { TokenWrapper } from '../contract_wrappers/token_wrapper';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy on read store for balances/proxyAllowances of tokens/accounts
|
* Copy on read store for balances/proxyAllowances of tokens/accounts
|
||||||
*/
|
*/
|
||||||
export class BalanceAndProxyAllowanceLazyStore implements AbstractBalanceAndProxyAllowanceFetcher {
|
export class BalanceAndProxyAllowanceLazyStore implements AbstractBalanceAndProxyAllowanceLazyStore {
|
||||||
private _tokenWrapper: TokenWrapper;
|
private _tokenWrapper: TokenWrapper;
|
||||||
private _defaultBlock: BlockParamLiteral;
|
private _defaultBlock: BlockParamLiteral;
|
||||||
private _balance: {
|
private _balance: {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { BlockParamLiteral, ExchangeContractErrs } from '@0xproject/types';
|
import { BlockParamLiteral, ExchangeContractErrs } from '@0xproject/types';
|
||||||
import { BigNumber } from '@0xproject/utils';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
|
|
||||||
|
import { AbstractBalanceAndProxyAllowanceLazyStore } from '../abstract/abstract_balance_and_proxy_allowance_lazy_store';
|
||||||
import { TokenWrapper } from '../contract_wrappers/token_wrapper';
|
import { TokenWrapper } from '../contract_wrappers/token_wrapper';
|
||||||
import { BalanceAndProxyAllowanceLazyStore } from '../stores/balance_proxy_allowance_lazy_store';
|
|
||||||
import { TradeSide, TransferType } from '../types';
|
import { TradeSide, TransferType } from '../types';
|
||||||
import { constants } from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
|
|
||||||
@@ -35,8 +35,7 @@ const ERR_MSG_MAPPING = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export class ExchangeTransferSimulator {
|
export class ExchangeTransferSimulator {
|
||||||
private _store: BalanceAndProxyAllowanceLazyStore;
|
private _store: AbstractBalanceAndProxyAllowanceLazyStore;
|
||||||
private _UNLIMITED_ALLOWANCE_IN_BASE_UNITS: BigNumber;
|
|
||||||
private static _throwValidationError(
|
private static _throwValidationError(
|
||||||
failureReason: FailureReason,
|
failureReason: FailureReason,
|
||||||
tradeSide: TradeSide,
|
tradeSide: TradeSide,
|
||||||
@@ -45,9 +44,8 @@ export class ExchangeTransferSimulator {
|
|||||||
const errMsg = ERR_MSG_MAPPING[failureReason][tradeSide][transferType];
|
const errMsg = ERR_MSG_MAPPING[failureReason][tradeSide][transferType];
|
||||||
throw new Error(errMsg);
|
throw new Error(errMsg);
|
||||||
}
|
}
|
||||||
constructor(token: TokenWrapper, defaultBlock: BlockParamLiteral) {
|
constructor(store: AbstractBalanceAndProxyAllowanceLazyStore) {
|
||||||
this._store = new BalanceAndProxyAllowanceLazyStore(token, defaultBlock);
|
this._store = store;
|
||||||
this._UNLIMITED_ALLOWANCE_IN_BASE_UNITS = token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Simulates transferFrom call performed by a proxy
|
* Simulates transferFrom call performed by a proxy
|
||||||
@@ -91,7 +89,7 @@ export class ExchangeTransferSimulator {
|
|||||||
amountInBaseUnits: BigNumber,
|
amountInBaseUnits: BigNumber,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const proxyAllowance = await this._store.getProxyAllowanceAsync(tokenAddress, userAddress);
|
const proxyAllowance = await this._store.getProxyAllowanceAsync(tokenAddress, userAddress);
|
||||||
if (!proxyAllowance.eq(this._UNLIMITED_ALLOWANCE_IN_BASE_UNITS)) {
|
if (!proxyAllowance.eq(constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS)) {
|
||||||
this._store.setProxyAllowance(tokenAddress, userAddress, proxyAllowance.minus(amountInBaseUnits));
|
this._store.setProxyAllowance(tokenAddress, userAddress, proxyAllowance.minus(amountInBaseUnits));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import * as chai from 'chai';
|
|||||||
import 'make-promises-safe';
|
import 'make-promises-safe';
|
||||||
|
|
||||||
import { ContractWrappers, ExchangeContractErrs } from '../src';
|
import { ContractWrappers, ExchangeContractErrs } from '../src';
|
||||||
|
import { BalanceAndProxyAllowanceLazyStore } from '../src/stores/balance_proxy_allowance_lazy_store';
|
||||||
import { TradeSide, TransferType } from '../src/types';
|
import { TradeSide, TransferType } from '../src/types';
|
||||||
import { ExchangeTransferSimulator } from '../src/utils/exchange_transfer_simulator';
|
import { ExchangeTransferSimulator } from '../src/utils/exchange_transfer_simulator';
|
||||||
|
|
||||||
@@ -44,7 +45,11 @@ describe('ExchangeTransferSimulator', () => {
|
|||||||
});
|
});
|
||||||
describe('#transferFromAsync', () => {
|
describe('#transferFromAsync', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
exchangeTransferSimulator = new ExchangeTransferSimulator(contractWrappers.token, BlockParamLiteral.Latest);
|
const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
|
||||||
|
contractWrappers.token,
|
||||||
|
BlockParamLiteral.Latest,
|
||||||
|
);
|
||||||
|
exchangeTransferSimulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore);
|
||||||
});
|
});
|
||||||
it("throws if the user doesn't have enough allowance", async () => {
|
it("throws if the user doesn't have enough allowance", async () => {
|
||||||
return expect(
|
return expect(
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'make-promises-safe';
|
|||||||
import * as Sinon from 'sinon';
|
import * as Sinon from 'sinon';
|
||||||
|
|
||||||
import { ContractWrappers, ExchangeContractErrs, SignedOrder, Token } from '../src';
|
import { ContractWrappers, ExchangeContractErrs, SignedOrder, Token } from '../src';
|
||||||
|
import { BalanceAndProxyAllowanceLazyStore } from '../src/stores/balance_proxy_allowance_lazy_store';
|
||||||
import { TradeSide, TransferType } from '../src/types';
|
import { TradeSide, TransferType } from '../src/types';
|
||||||
import { ExchangeTransferSimulator } from '../src/utils/exchange_transfer_simulator';
|
import { ExchangeTransferSimulator } from '../src/utils/exchange_transfer_simulator';
|
||||||
import { OrderValidationUtils } from '../src/utils/order_validation_utils';
|
import { OrderValidationUtils } from '../src/utils/order_validation_utils';
|
||||||
@@ -332,7 +333,11 @@ describe('OrderValidation', () => {
|
|||||||
return Sinon.match((value: BigNumber) => value.eq(expected));
|
return Sinon.match((value: BigNumber) => value.eq(expected));
|
||||||
};
|
};
|
||||||
beforeEach('create exchangeTransferSimulator', async () => {
|
beforeEach('create exchangeTransferSimulator', async () => {
|
||||||
exchangeTransferSimulator = new ExchangeTransferSimulator(contractWrappers.token, BlockParamLiteral.Latest);
|
const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
|
||||||
|
contractWrappers.token,
|
||||||
|
BlockParamLiteral.Latest,
|
||||||
|
);
|
||||||
|
exchangeTransferSimulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore);
|
||||||
transferFromAsync = Sinon.spy();
|
transferFromAsync = Sinon.spy();
|
||||||
exchangeTransferSimulator.transferFromAsync = transferFromAsync as any;
|
exchangeTransferSimulator.transferFromAsync = transferFromAsync as any;
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user