@0x/asset-swapper: Run prettier
This commit is contained in:
@@ -123,7 +123,7 @@ export interface CreateOrderFromPathOpts {
|
||||
export function createOrdersFromPath(path: Fill[], opts: CreateOrderFromPathOpts): OptimizedMarketOrder[] {
|
||||
const collapsedPath = collapsePath(path);
|
||||
const orders: OptimizedMarketOrder[] = [];
|
||||
for (let i = 0; i < collapsedPath.length;) {
|
||||
for (let i = 0; i < collapsedPath.length; ) {
|
||||
if (collapsedPath[i].source === ERC20BridgeSource.Native) {
|
||||
orders.push(createNativeOrder(collapsedPath[i]));
|
||||
++i;
|
||||
@@ -219,8 +219,9 @@ function createBatchedBridgeOrder(fills: CollapsedFill[], opts: CreateOrderFromP
|
||||
const bridgeOrder = createBridgeOrder(fill, opts);
|
||||
totalMakerAssetAmount = totalMakerAssetAmount.plus(bridgeOrder.makerAssetAmount);
|
||||
totalTakerAssetAmount = totalTakerAssetAmount.plus(bridgeOrder.takerAssetAmount);
|
||||
const { bridgeAddress, bridgeData: orderBridgeData } =
|
||||
assetDataUtils.decodeAssetDataOrThrow(bridgeOrder.makerAssetData) as ERC20BridgeAssetData;
|
||||
const { bridgeAddress, bridgeData: orderBridgeData } = assetDataUtils.decodeAssetDataOrThrow(
|
||||
bridgeOrder.makerAssetData,
|
||||
) as ERC20BridgeAssetData;
|
||||
batchedBridgeData.calls.push({
|
||||
target: bridgeAddress,
|
||||
bridgeData: orderBridgeData,
|
||||
@@ -290,7 +291,7 @@ type CommonBridgeOrderFields = Pick<
|
||||
OptimizedMarketOrder,
|
||||
Exclude<
|
||||
keyof OptimizedMarketOrder,
|
||||
'fills'
|
||||
| 'fills'
|
||||
| 'makerAddress'
|
||||
| 'makerAssetData'
|
||||
| 'takerAssetData'
|
||||
|
||||
@@ -174,14 +174,10 @@ export function fillQuoteOrders(
|
||||
const filledOutputFee = filledOutput.div(fo.totalOrderOutput).times(fo.totalOrderOutputFee);
|
||||
|
||||
result.inputBySource[source] = result.inputBySource[source].plus(filledInput);
|
||||
result.input = result.input
|
||||
.plus(filledInput);
|
||||
result.output = result.output
|
||||
.plus(filledOutput);
|
||||
result.inputFee = result.inputFee
|
||||
.plus(filledInputFee);
|
||||
result.outputFee = result.outputFee
|
||||
.plus(filledOutputFee);
|
||||
result.input = result.input.plus(filledInput);
|
||||
result.output = result.output.plus(filledOutput);
|
||||
result.inputFee = result.inputFee.plus(filledInputFee);
|
||||
result.outputFee = result.outputFee.plus(filledOutputFee);
|
||||
remainingInput = remainingInput.minus(filledInput.plus(filledInputFee));
|
||||
}
|
||||
}
|
||||
@@ -227,53 +223,48 @@ function createBestCaseFillOrderCalls(quoteInfo: QuoteFillInfo): QuoteFillOrderC
|
||||
order: o,
|
||||
...(side === MarketOperation.Sell
|
||||
? {
|
||||
totalOrderInput: o.takerAssetAmount,
|
||||
totalOrderOutput: o.makerAssetAmount,
|
||||
totalOrderInputFee: isOrderTakerFeePayableWithTakerAsset(o)
|
||||
? o.takerFee
|
||||
: ZERO_AMOUNT,
|
||||
totalOrderOutputFee: isOrderTakerFeePayableWithMakerAsset(o)
|
||||
? o.takerFee.negated()
|
||||
: ZERO_AMOUNT,
|
||||
}
|
||||
// Buy
|
||||
: {
|
||||
totalOrderInput: o.makerAssetAmount,
|
||||
totalOrderOutput: o.takerAssetAmount,
|
||||
totalOrderInputFee: isOrderTakerFeePayableWithMakerAsset(o)
|
||||
? o.takerFee.negated()
|
||||
: ZERO_AMOUNT,
|
||||
totalOrderOutputFee: isOrderTakerFeePayableWithTakerAsset(o)
|
||||
? o.takerFee
|
||||
: ZERO_AMOUNT,
|
||||
}
|
||||
),
|
||||
totalOrderInput: o.takerAssetAmount,
|
||||
totalOrderOutput: o.makerAssetAmount,
|
||||
totalOrderInputFee: isOrderTakerFeePayableWithTakerAsset(o) ? o.takerFee : ZERO_AMOUNT,
|
||||
totalOrderOutputFee: isOrderTakerFeePayableWithMakerAsset(o) ? o.takerFee.negated() : ZERO_AMOUNT,
|
||||
}
|
||||
: // Buy
|
||||
{
|
||||
totalOrderInput: o.makerAssetAmount,
|
||||
totalOrderOutput: o.takerAssetAmount,
|
||||
totalOrderInputFee: isOrderTakerFeePayableWithMakerAsset(o) ? o.takerFee.negated() : ZERO_AMOUNT,
|
||||
totalOrderOutputFee: isOrderTakerFeePayableWithTakerAsset(o) ? o.takerFee : ZERO_AMOUNT,
|
||||
}),
|
||||
}));
|
||||
}
|
||||
|
||||
function createWorstCaseFillOrderCalls(quoteInfo: QuoteFillInfo): QuoteFillOrderCall[] {
|
||||
// Reuse best case fill orders.
|
||||
return createBestCaseFillOrderCalls(quoteInfo).map(fo => ({
|
||||
...fo,
|
||||
order: {
|
||||
...fo.order,
|
||||
// Apply slippage to order fills and reverse them.
|
||||
fills: getSlippedOrderFills(fo.order, quoteInfo.side).reverse(),
|
||||
},
|
||||
// Reverse the orders.
|
||||
})).reverse();
|
||||
return createBestCaseFillOrderCalls(quoteInfo)
|
||||
.map(fo => ({
|
||||
...fo,
|
||||
order: {
|
||||
...fo.order,
|
||||
// Apply slippage to order fills and reverse them.
|
||||
fills: getSlippedOrderFills(fo.order, quoteInfo.side).reverse(),
|
||||
},
|
||||
// Reverse the orders.
|
||||
}))
|
||||
.reverse();
|
||||
}
|
||||
|
||||
// Apply order slippage to its fill paths.
|
||||
function getSlippedOrderFills(order: OptimizedMarketOrder, side: MarketOperation): CollapsedFill[] {
|
||||
const totalInput = BigNumber.sum(...order.fills.map(f => f.input));
|
||||
const totalOutput = BigNumber.sum(...order.fills.map(f => f.output));
|
||||
const inputScaling = side === MarketOperation.Sell
|
||||
? order.fillableTakerAssetAmount.div(totalInput)
|
||||
: order.fillableMakerAssetAmount.div(totalInput);
|
||||
const outputScaling = side === MarketOperation.Sell
|
||||
? order.fillableMakerAssetAmount.div(totalOutput)
|
||||
: order.fillableTakerAssetAmount.div(totalOutput);
|
||||
const inputScaling =
|
||||
side === MarketOperation.Sell
|
||||
? order.fillableTakerAssetAmount.div(totalInput)
|
||||
: order.fillableMakerAssetAmount.div(totalInput);
|
||||
const outputScaling =
|
||||
side === MarketOperation.Sell
|
||||
? order.fillableMakerAssetAmount.div(totalOutput)
|
||||
: order.fillableTakerAssetAmount.div(totalOutput);
|
||||
return order.fills.map(f => ({
|
||||
...f,
|
||||
input: f.input.times(inputScaling),
|
||||
@@ -307,39 +298,34 @@ function roundIntermediateFillResult(
|
||||
gas: Math.ceil(ir.gas),
|
||||
inputBySource: Object.assign(
|
||||
{},
|
||||
...Object.entries(ir.inputBySource)
|
||||
.map(([k, v]) => ({ [k]: roundInputAmount(v, side) })),
|
||||
...Object.entries(ir.inputBySource).map(([k, v]) => ({ [k]: roundInputAmount(v, side) })),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
function fromIntermediateQuoteFillResult(
|
||||
ir: IntermediateQuoteFillResult,
|
||||
quoteInfo: QuoteFillInfo,
|
||||
): QuoteFillResult {
|
||||
function fromIntermediateQuoteFillResult(ir: IntermediateQuoteFillResult, quoteInfo: QuoteFillInfo): QuoteFillResult {
|
||||
const { side } = quoteInfo;
|
||||
const _ir = roundIntermediateFillResult(ir, side);
|
||||
return {
|
||||
...(side === MarketOperation.Sell
|
||||
// Sell
|
||||
? {
|
||||
makerAssetAmount: _ir.output,
|
||||
takerAssetAmount: _ir.input,
|
||||
takerFeeMakerAssetAmount: _ir.outputFee,
|
||||
takerFeeTakerAssetAmount: _ir.inputFee,
|
||||
totalMakerAssetAmount: _ir.output.plus(_ir.outputFee),
|
||||
totalTakerAssetAmount: _ir.input.plus(_ir.inputFee),
|
||||
}
|
||||
// Buy
|
||||
: {
|
||||
makerAssetAmount: _ir.input,
|
||||
takerAssetAmount: _ir.output,
|
||||
takerFeeMakerAssetAmount: _ir.inputFee,
|
||||
takerFeeTakerAssetAmount: _ir.outputFee,
|
||||
totalMakerAssetAmount: _ir.input.plus(_ir.inputFee),
|
||||
totalTakerAssetAmount: _ir.output.plus(_ir.outputFee),
|
||||
}
|
||||
),
|
||||
? // Sell
|
||||
{
|
||||
makerAssetAmount: _ir.output,
|
||||
takerAssetAmount: _ir.input,
|
||||
takerFeeMakerAssetAmount: _ir.outputFee,
|
||||
takerFeeTakerAssetAmount: _ir.inputFee,
|
||||
totalMakerAssetAmount: _ir.output.plus(_ir.outputFee),
|
||||
totalTakerAssetAmount: _ir.input.plus(_ir.inputFee),
|
||||
}
|
||||
: // Buy
|
||||
{
|
||||
makerAssetAmount: _ir.input,
|
||||
takerAssetAmount: _ir.output,
|
||||
takerFeeMakerAssetAmount: _ir.inputFee,
|
||||
takerFeeTakerAssetAmount: _ir.outputFee,
|
||||
totalMakerAssetAmount: _ir.input.plus(_ir.inputFee),
|
||||
totalTakerAssetAmount: _ir.output.plus(_ir.outputFee),
|
||||
}),
|
||||
protocolFeeAmount: _ir.protocolFee,
|
||||
gas: _ir.gas,
|
||||
fillAmountBySource: _ir.inputBySource,
|
||||
@@ -354,10 +340,7 @@ export function getFlattenedFillsFromOrders(orders: OptimizedMarketOrder[]): Col
|
||||
return fills;
|
||||
}
|
||||
|
||||
function getTotalGasUsedBySources(
|
||||
sources: ERC20BridgeSource[],
|
||||
gasSchedule: { [source: string]: number },
|
||||
): number {
|
||||
function getTotalGasUsedBySources(sources: ERC20BridgeSource[], gasSchedule: { [source: string]: number }): number {
|
||||
let gasUsed = 0;
|
||||
for (const s of sources) {
|
||||
gasUsed += gasSchedule[s] || 0;
|
||||
|
||||
@@ -19,15 +19,9 @@ import {
|
||||
import { MarketOperationUtils } from './market_operation_utils';
|
||||
import { convertNativeOrderToFullyFillableOptimizedOrders } from './market_operation_utils/orders';
|
||||
import { GetMarketOrdersOpts, OptimizedMarketOrder } from './market_operation_utils/types';
|
||||
import {
|
||||
isSupportedAssetDataInOrders,
|
||||
} from './utils';
|
||||
import { isSupportedAssetDataInOrders } from './utils';
|
||||
|
||||
import {
|
||||
QuoteFillResult,
|
||||
simulateBestCaseFill,
|
||||
simulateWorstCaseFill,
|
||||
} from './quote_simulation';
|
||||
import { QuoteFillResult, simulateBestCaseFill, simulateWorstCaseFill } from './quote_simulation';
|
||||
|
||||
// TODO(dave4506) How do we want to reintroduce InsufficientAssetLiquidityError?
|
||||
export class SwapQuoteCalculator {
|
||||
@@ -225,9 +219,7 @@ function createSwapQuote(
|
||||
}
|
||||
}
|
||||
|
||||
function getSwapQuoteOrdersBreakdown(
|
||||
fillAmountBySource: { [source: string]: BigNumber },
|
||||
): SwapQuoteOrdersBreakdown {
|
||||
function getSwapQuoteOrdersBreakdown(fillAmountBySource: { [source: string]: BigNumber }): SwapQuoteOrdersBreakdown {
|
||||
const totalFillAmount = BigNumber.sum(...Object.values(fillAmountBySource));
|
||||
const breakdown: SwapQuoteOrdersBreakdown = {};
|
||||
Object.entries(fillAmountBySource).forEach(([source, fillAmount]) => {
|
||||
|
||||
@@ -701,10 +701,7 @@ describe('MarketOperationUtils tests', () => {
|
||||
expect(orderFillSources).to.deep.eq([
|
||||
[ERC20BridgeSource.Uniswap],
|
||||
[ERC20BridgeSource.Native],
|
||||
[
|
||||
ERC20BridgeSource.Eth2Dai,
|
||||
ERC20BridgeSource.CurveUsdcDai,
|
||||
],
|
||||
[ERC20BridgeSource.Eth2Dai, ERC20BridgeSource.CurveUsdcDai],
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -1010,10 +1007,7 @@ describe('MarketOperationUtils tests', () => {
|
||||
const orderFillSources = improvedOrders.map(o => o.fills.map(f => f.source));
|
||||
expect(orderFillSources).to.deep.eq([
|
||||
[ERC20BridgeSource.Native],
|
||||
[
|
||||
ERC20BridgeSource.Eth2Dai,
|
||||
ERC20BridgeSource.Uniswap,
|
||||
],
|
||||
[ERC20BridgeSource.Eth2Dai, ERC20BridgeSource.Uniswap],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,7 +11,12 @@ import * as _ from 'lodash';
|
||||
|
||||
import { MarketOperation } from '../src/types';
|
||||
import { CollapsedFill, ERC20BridgeSource, OptimizedMarketOrder } from '../src/utils/market_operation_utils/types';
|
||||
import { fillQuoteOrders, QuoteFillOrderCall, simulateBestCaseFill, simulateWorstCaseFill } from '../src/utils/quote_simulation';
|
||||
import {
|
||||
fillQuoteOrders,
|
||||
QuoteFillOrderCall,
|
||||
simulateBestCaseFill,
|
||||
simulateWorstCaseFill,
|
||||
} from '../src/utils/quote_simulation';
|
||||
|
||||
// tslint:disable: custom-no-magic-numbers
|
||||
const { NULL_ADDRESS } = constants;
|
||||
@@ -19,7 +24,6 @@ const ZERO = new BigNumber(0);
|
||||
const ONE = new BigNumber(1);
|
||||
|
||||
describe('quote_simulation tests', async () => {
|
||||
|
||||
const MAKER_TOKEN = randomAddress();
|
||||
const TAKER_TOKEN = randomAddress();
|
||||
const DEFAULT_MAKER_ASSET_DATA = assetDataUtils.encodeERC20AssetData(MAKER_TOKEN);
|
||||
@@ -27,15 +31,17 @@ describe('quote_simulation tests', async () => {
|
||||
const EPS = 1e6;
|
||||
const GAS_SCHEDULE = { [ERC20BridgeSource.Native]: 1 };
|
||||
|
||||
function createQuoteFillOrders(opts: Partial<{
|
||||
fillableInput: BigNumber;
|
||||
fillableOutput: BigNumber;
|
||||
inputFeeRate: number;
|
||||
outputFeeRate: number;
|
||||
count: number;
|
||||
fillsCount: number;
|
||||
side: MarketOperation;
|
||||
}> = {}): QuoteFillOrderCall[] {
|
||||
function createQuoteFillOrders(
|
||||
opts: Partial<{
|
||||
fillableInput: BigNumber;
|
||||
fillableOutput: BigNumber;
|
||||
inputFeeRate: number;
|
||||
outputFeeRate: number;
|
||||
count: number;
|
||||
fillsCount: number;
|
||||
side: MarketOperation;
|
||||
}> = {},
|
||||
): QuoteFillOrderCall[] {
|
||||
const { fillableInput, fillableOutput, inputFeeRate, outputFeeRate, count, fillsCount, side } = {
|
||||
fillableInput: getRandomOrderSize(),
|
||||
fillableOutput: getRandomOrderSize(),
|
||||
@@ -46,12 +52,10 @@ describe('quote_simulation tests', async () => {
|
||||
side: MarketOperation.Sell,
|
||||
...opts,
|
||||
};
|
||||
const _inputFeeRate = side === MarketOperation.Sell
|
||||
? inputFeeRate : -inputFeeRate;
|
||||
const _outputFeeRate = side === MarketOperation.Sell
|
||||
? -outputFeeRate : outputFeeRate;
|
||||
const _inputFeeRate = side === MarketOperation.Sell ? inputFeeRate : -inputFeeRate;
|
||||
const _outputFeeRate = side === MarketOperation.Sell ? -outputFeeRate : outputFeeRate;
|
||||
|
||||
const fillableInputs = subdivideAmount(fillableInput, count);
|
||||
const fillableInputs = subdivideAmount(fillableInput, count);
|
||||
const fillableOutputs = subdivideAmount(fillableOutput, count);
|
||||
const filledInputs = subdivideAmount(fillableInput.times(0.5), count);
|
||||
const filledOutputs: BigNumber[] = [];
|
||||
@@ -61,10 +65,7 @@ describe('quote_simulation tests', async () => {
|
||||
const outputFees: BigNumber[] = [];
|
||||
_.times(count).forEach(i => {
|
||||
const f = filledInputs[i].div(fillableInputs[i]);
|
||||
filledOutputs.push(fillableOutputs[i]
|
||||
.times(f)
|
||||
.integerValue(BigNumber.ROUND_DOWN),
|
||||
);
|
||||
filledOutputs.push(fillableOutputs[i].times(f).integerValue(BigNumber.ROUND_DOWN));
|
||||
totalInputs.push(fillableInputs[i].plus(filledInputs[i]));
|
||||
totalOutputs.push(fillableOutputs[i].plus(filledOutputs[i]));
|
||||
inputFees.push(totalInputs[i].times(_inputFeeRate).integerValue());
|
||||
@@ -72,17 +73,13 @@ describe('quote_simulation tests', async () => {
|
||||
});
|
||||
return _.times(count, i => {
|
||||
return {
|
||||
order: createQuoteFillOrderOrder(
|
||||
totalInputs[i],
|
||||
totalOutputs[i],
|
||||
{
|
||||
side,
|
||||
fillsCount,
|
||||
filledInput: filledInputs[i],
|
||||
takerInputFee: inputFees[i].abs(),
|
||||
takerOutputFee: outputFees[i].abs(),
|
||||
},
|
||||
),
|
||||
order: createQuoteFillOrderOrder(totalInputs[i], totalOutputs[i], {
|
||||
side,
|
||||
fillsCount,
|
||||
filledInput: filledInputs[i],
|
||||
takerInputFee: inputFees[i].abs(),
|
||||
takerOutputFee: outputFees[i].abs(),
|
||||
}),
|
||||
totalOrderInput: totalInputs[i],
|
||||
totalOrderOutput: totalOutputs[i],
|
||||
totalOrderInputFee: inputFees[i],
|
||||
@@ -100,14 +97,9 @@ describe('quote_simulation tests', async () => {
|
||||
side: MarketOperation;
|
||||
takerInputFee: BigNumber;
|
||||
takerOutputFee: BigNumber;
|
||||
}> = {}): OptimizedMarketOrder {
|
||||
const {
|
||||
filledInput,
|
||||
fillsCount,
|
||||
side,
|
||||
takerInputFee,
|
||||
takerOutputFee,
|
||||
} = {
|
||||
}> = {},
|
||||
): OptimizedMarketOrder {
|
||||
const { filledInput, fillsCount, side, takerInputFee, takerOutputFee } = {
|
||||
side: MarketOperation.Sell,
|
||||
filledInput: ZERO,
|
||||
fillsCount: 3,
|
||||
@@ -115,25 +107,22 @@ describe('quote_simulation tests', async () => {
|
||||
takerOutputFee: ZERO,
|
||||
...opts,
|
||||
};
|
||||
const filledOutput = filledInput.div(input).times(output).integerValue(BigNumber.ROUND_DOWN);
|
||||
const filledOutput = filledInput
|
||||
.div(input)
|
||||
.times(output)
|
||||
.integerValue(BigNumber.ROUND_DOWN);
|
||||
const fillableInput = input.minus(filledInput);
|
||||
const fillableOutput = output.minus(filledOutput);
|
||||
const makerAssetAmount = side === MarketOperation.Sell
|
||||
? output : input;
|
||||
const takerAssetAmount = side === MarketOperation.Sell
|
||||
? input : output;
|
||||
const fillableMakerAssetAmount = side === MarketOperation.Sell
|
||||
? fillableOutput : fillableInput;
|
||||
const fillableTakerAssetAmount = side === MarketOperation.Sell
|
||||
? fillableInput : fillableOutput;
|
||||
const makerAssetAmount = side === MarketOperation.Sell ? output : input;
|
||||
const takerAssetAmount = side === MarketOperation.Sell ? input : output;
|
||||
const fillableMakerAssetAmount = side === MarketOperation.Sell ? fillableOutput : fillableInput;
|
||||
const fillableTakerAssetAmount = side === MarketOperation.Sell ? fillableInput : fillableOutput;
|
||||
const takerFee = BigNumber.max(takerInputFee, takerOutputFee);
|
||||
let takerFeeAssetData = '0x';
|
||||
if (!takerInputFee.eq(0)) {
|
||||
takerFeeAssetData = side === MarketOperation.Sell
|
||||
? DEFAULT_TAKER_ASSET_DATA : DEFAULT_MAKER_ASSET_DATA;
|
||||
takerFeeAssetData = side === MarketOperation.Sell ? DEFAULT_TAKER_ASSET_DATA : DEFAULT_MAKER_ASSET_DATA;
|
||||
} else if (!takerOutputFee.eq(0)) {
|
||||
takerFeeAssetData = side === MarketOperation.Sell
|
||||
? DEFAULT_MAKER_ASSET_DATA : DEFAULT_TAKER_ASSET_DATA;
|
||||
takerFeeAssetData = side === MarketOperation.Sell ? DEFAULT_MAKER_ASSET_DATA : DEFAULT_TAKER_ASSET_DATA;
|
||||
}
|
||||
const fillableTakerFeeAmount = fillableTakerAssetAmount
|
||||
.div(takerAssetAmount)
|
||||
@@ -164,11 +153,7 @@ describe('quote_simulation tests', async () => {
|
||||
};
|
||||
}
|
||||
|
||||
function createOrderCollapsedFills(
|
||||
input: BigNumber,
|
||||
output: BigNumber,
|
||||
count: number,
|
||||
): CollapsedFill[] {
|
||||
function createOrderCollapsedFills(input: BigNumber, output: BigNumber, count: number): CollapsedFill[] {
|
||||
const inputs = subdivideAmount(input, count);
|
||||
const outputs = subdivideAmount(output, count);
|
||||
return _.times(count, i => {
|
||||
@@ -189,12 +174,12 @@ describe('quote_simulation tests', async () => {
|
||||
function countCollapsedFills(fillOrders: QuoteFillOrderCall[] | OptimizedMarketOrder[]): number {
|
||||
let count = 0;
|
||||
if ((fillOrders as any)[0].fills) {
|
||||
const orders = fillOrders as any as OptimizedMarketOrder[];
|
||||
const orders = (fillOrders as any) as OptimizedMarketOrder[];
|
||||
for (const o of orders) {
|
||||
count += o.fills.length;
|
||||
}
|
||||
} else {
|
||||
const orders = fillOrders as any as QuoteFillOrderCall[];
|
||||
const orders = (fillOrders as any) as QuoteFillOrderCall[];
|
||||
for (const fo of orders) {
|
||||
count += fo.order.fills.length;
|
||||
}
|
||||
@@ -215,8 +200,9 @@ describe('quote_simulation tests', async () => {
|
||||
}
|
||||
|
||||
function assertEqualRates(actual: number | BigNumber, expected: number | BigNumber): void {
|
||||
expect(new BigNumber(actual).times(1e4).integerValue())
|
||||
.to.bignumber.eq(new BigNumber(expected).times(1e4).integerValue());
|
||||
expect(new BigNumber(actual).times(1e4).integerValue()).to.bignumber.eq(
|
||||
new BigNumber(expected).times(1e4).integerValue(),
|
||||
);
|
||||
}
|
||||
|
||||
function subdivideAmount(amount: BigNumber, count: number): BigNumber[] {
|
||||
|
||||
Reference in New Issue
Block a user