Re-use order relevant state

This commit is contained in:
Jacob Evans
2019-03-22 15:59:57 +01:00
parent 8b8dc7ac78
commit 0bf46bfcb5
2 changed files with 8 additions and 111 deletions

View File

@@ -7,6 +7,7 @@ import {
ExchangeTransferSimulator,
orderCalculationUtils,
orderHashUtils,
OrderStateUtils,
OrderValidationUtils,
} from '@0x/order-utils';
import { AssetProxyId, Order, SignedOrder } from '@0x/types';
@@ -1158,46 +1159,27 @@ export class ExchangeWrapper extends ContractWrapper {
);
const balanceAllowanceStore = new BalanceAndProxyAllowanceLazyStore(balanceAllowanceFetcher);
const exchangeTradeSimulator = new ExchangeTransferSimulator(balanceAllowanceStore);
const filledCancelledFetcher = new OrderFilledCancelledFetcher(this, BlockParamLiteral.Latest);
let fillableTakerAssetAmount;
const shouldValidateRemainingOrderAmountIsFillable = _.isUndefined(opts.validateRemainingOrderAmountIsFillable)
? true
: opts.validateRemainingOrderAmountIsFillable;
const filledTakerTokenAmount = await this.getFilledTakerAssetAmountAsync(
orderHashUtils.getOrderHashHex(signedOrder),
);
if (opts.expectedFillTakerTokenAmount) {
// If the caller has specified a taker fill amount, we use this for all validation
fillableTakerAssetAmount = opts.expectedFillTakerTokenAmount;
} else if (shouldValidateRemainingOrderAmountIsFillable) {
// Historically if a fill amount was not specified we would default to the amount
// left on the order.
const filledTakerTokenAmount = await this.getFilledTakerAssetAmountAsync(
orderHashUtils.getOrderHashHex(signedOrder),
);
fillableTakerAssetAmount = signedOrder.takerAssetAmount.minus(filledTakerTokenAmount);
} else {
const makerAssetBalance = await balanceAllowanceStore.getBalanceAsync(
signedOrder.makerAssetData,
signedOrder.makerAddress,
);
const makerAssetAllowance = await balanceAllowanceStore.getProxyAllowanceAsync(
signedOrder.makerAssetData,
signedOrder.makerAddress,
);
const makerZRXBalance = await balanceAllowanceStore.getBalanceAsync(
this.getZRXAssetData(),
signedOrder.makerAddress,
);
const makerZRXAllowance = await balanceAllowanceStore.getProxyAllowanceAsync(
this.getZRXAssetData(),
signedOrder.makerAddress,
);
fillableTakerAssetAmount = orderCalculationUtils.calculateRemainingFillableTakerAssetAmount(
signedOrder,
filledTakerTokenAmount,
{ balance: makerAssetBalance, allowance: makerAssetAllowance },
{ balance: makerZRXBalance, allowance: makerZRXAllowance },
);
const orderStateUtils = new OrderStateUtils(balanceAllowanceStore, filledCancelledFetcher);
// Calculate the taker amount fillable given the maker balance and allowance
const orderRelevantState = await orderStateUtils.getOpenOrderRelevantStateAsync(signedOrder);
fillableTakerAssetAmount = orderRelevantState.remainingFillableTakerAssetAmount;
}
const orderValidationUtils = new OrderValidationUtils(filledCancelledFetcher, this._web3Wrapper.getProvider());

View File

@@ -97,89 +97,4 @@ export const orderCalculationUtils = {
const adjustedMakerFillAmount = orderCalculationUtils.getMakerFillAmount(order, adjustedTakerFillAmount);
return [adjustedTakerFillAmount, adjustedMakerFillAmount];
},
/**
* Calculates the remaining fillable amount for an order given:
* order filled amount
* asset balance/allowance (maker/taker)
* ZRX fee balance/allowance (maker/taker)
* Taker values are checked if specified in the order. For example, if the maker does not
* have sufficient ZRX allowance to pay the fee, then this function will return the maximum
* amount that can be filled given the maker's ZRX allowance
* @param order The order
* @param takerAssetFilledAmount The amount currently filled on the order
* @param makerAssetBalanceAllowance The makerAsset balance and allowance of the maker
* @param makerZRXBalanceAllowance The ZRX balance and allowance of the maker
* @param takerAssetBalanceAllowance The takerAsset balance and allowance of the taker
* @param takerZRXBalanceAllowance The ZRX balance and allowance of the taker
*/
calculateRemainingFillableTakerAssetAmount(
order: Order,
takerAssetFilledAmount: BigNumber,
makerAssetBalanceAllowance: BalanceAndAllowance,
makerZRXBalanceAllowance: BalanceAndAllowance,
takerAssetBalanceAllowance?: BalanceAndAllowance,
takerZRXBalanceAllowance?: BalanceAndAllowance,
): BigNumber {
const minSet = [];
// Calculate min of balance & allowance of taker's takerAsset
if (order.takerAddress !== constants.NULL_ADDRESS) {
if (takerAssetBalanceAllowance && takerZRXBalanceAllowance) {
const maxTakerAssetFillAmountGivenTakerConstraints = BigNumber.min(
takerAssetBalanceAllowance.balance,
takerAssetBalanceAllowance.allowance,
);
minSet.push(
maxTakerAssetFillAmountGivenTakerConstraints,
takerAssetBalanceAllowance.balance,
takerAssetBalanceAllowance.allowance,
);
}
}
// Calculate min of balance & allowance of maker's makerAsset -> translate into takerAsset amount
const maxMakerAssetFillAmount = BigNumber.min(
makerAssetBalanceAllowance.balance,
makerAssetBalanceAllowance.allowance,
);
const maxTakerAssetFillAmountGivenMakerConstraints = orderCalculationUtils.getTakerFillAmount(
order,
maxMakerAssetFillAmount,
);
minSet.push(maxTakerAssetFillAmountGivenMakerConstraints);
// Calculate min of balance & allowance of taker's ZRX -> translate into takerAsset amount
if (!order.takerFee.eq(0) && order.takerAddress !== constants.NULL_ADDRESS) {
if (takerAssetBalanceAllowance && takerZRXBalanceAllowance) {
const takerZRXAvailable = BigNumber.min(
takerZRXBalanceAllowance.balance,
takerZRXBalanceAllowance.allowance,
);
const maxTakerAssetFillAmountGivenTakerZRXConstraints = takerZRXAvailable
.multipliedBy(order.takerAssetAmount)
.div(order.takerFee)
.integerValue(BigNumber.ROUND_CEIL); // Should this round to ciel or floor?
minSet.push(maxTakerAssetFillAmountGivenTakerZRXConstraints);
}
}
// Calculate min of balance & allowance of maker's ZRX -> translate into takerAsset amount
if (!order.makerFee.eq(0)) {
const makerZRXAvailable = BigNumber.min(
makerZRXBalanceAllowance.balance,
makerZRXBalanceAllowance.allowance,
);
const maxTakerAssetFillAmountGivenMakerZRXConstraints = makerZRXAvailable
.multipliedBy(order.takerAssetAmount)
.div(order.makerFee)
.integerValue(BigNumber.ROUND_CEIL); // Should this round to ciel or floor?
minSet.push(maxTakerAssetFillAmountGivenMakerZRXConstraints);
}
const remainingTakerAssetFillAmount = order.takerAssetAmount.minus(takerAssetFilledAmount);
minSet.push(remainingTakerAssetFillAmount);
const maxTakerAssetFillAmount = BigNumber.min(...minSet);
return maxTakerAssetFillAmount;
},
};