247 lines
12 KiB
TypeScript
247 lines
12 KiB
TypeScript
import { SignedOrder } from '@0x/types';
|
|
import { BigNumber } from '@0x/utils';
|
|
import { Web3Wrapper } from '@0x/web3-wrapper';
|
|
import * as chai from 'chai';
|
|
import 'mocha';
|
|
|
|
import { RemainingFillableCalculator } from '../src/remaining_fillable_calculator';
|
|
|
|
import { chaiSetup } from './utils/chai_setup';
|
|
|
|
chaiSetup.configure();
|
|
const expect = chai.expect;
|
|
|
|
describe('RemainingFillableCalculator', () => {
|
|
let calculator: RemainingFillableCalculator;
|
|
let signedOrder: SignedOrder;
|
|
let transferrableMakeAssetAmount: BigNumber;
|
|
let transferrableMakerFeeTokenAmount: BigNumber;
|
|
let remainingMakeAssetAmount: BigNumber;
|
|
let makerAmount: BigNumber;
|
|
let takerAmount: BigNumber;
|
|
let makerFeeAmount: BigNumber;
|
|
let isMakeAssetZRX: boolean;
|
|
const makerAssetData: string = '0x1';
|
|
const takerAssetData: string = '0x2';
|
|
const decimals: number = 4;
|
|
const zero: BigNumber = new BigNumber(0);
|
|
const zeroAddress = '0x0';
|
|
const signature: string =
|
|
'0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace225403';
|
|
beforeEach(async () => {
|
|
[makerAmount, takerAmount, makerFeeAmount] = [
|
|
Web3Wrapper.toBaseUnitAmount(new BigNumber(50), decimals),
|
|
Web3Wrapper.toBaseUnitAmount(new BigNumber(5), decimals),
|
|
Web3Wrapper.toBaseUnitAmount(new BigNumber(1), decimals),
|
|
];
|
|
[transferrableMakeAssetAmount, transferrableMakerFeeTokenAmount] = [
|
|
Web3Wrapper.toBaseUnitAmount(new BigNumber(50), decimals),
|
|
Web3Wrapper.toBaseUnitAmount(new BigNumber(5), decimals),
|
|
];
|
|
});
|
|
function buildSignedOrder(): SignedOrder {
|
|
return {
|
|
signature,
|
|
exchangeAddress: zeroAddress,
|
|
feeRecipientAddress: zeroAddress,
|
|
senderAddress: zeroAddress,
|
|
makerAddress: zeroAddress,
|
|
takerAddress: zeroAddress,
|
|
makerFee: makerFeeAmount,
|
|
takerFee: zero,
|
|
makerAssetAmount: makerAmount,
|
|
takerAssetAmount: takerAmount,
|
|
makerAssetData,
|
|
takerAssetData,
|
|
salt: zero,
|
|
expirationTimeSeconds: zero,
|
|
};
|
|
}
|
|
describe('Maker token is NOT ZRX', () => {
|
|
before(async () => {
|
|
isMakeAssetZRX = false;
|
|
});
|
|
it('calculates the correct amount when unfilled and funds available', () => {
|
|
signedOrder = buildSignedOrder();
|
|
remainingMakeAssetAmount = signedOrder.makerAssetAmount;
|
|
calculator = new RemainingFillableCalculator(
|
|
signedOrder.makerFee,
|
|
signedOrder.makerAssetAmount,
|
|
isMakeAssetZRX,
|
|
transferrableMakeAssetAmount,
|
|
transferrableMakerFeeTokenAmount,
|
|
remainingMakeAssetAmount,
|
|
);
|
|
expect(calculator.computeRemainingFillable()).to.be.bignumber.equal(remainingMakeAssetAmount);
|
|
});
|
|
it('calculates the correct amount when partially filled and funds available', () => {
|
|
signedOrder = buildSignedOrder();
|
|
remainingMakeAssetAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(1), decimals);
|
|
calculator = new RemainingFillableCalculator(
|
|
signedOrder.makerFee,
|
|
signedOrder.makerAssetAmount,
|
|
isMakeAssetZRX,
|
|
transferrableMakeAssetAmount,
|
|
transferrableMakerFeeTokenAmount,
|
|
remainingMakeAssetAmount,
|
|
);
|
|
expect(calculator.computeRemainingFillable()).to.be.bignumber.equal(remainingMakeAssetAmount);
|
|
});
|
|
it('calculates the amount to be 0 when all fee funds are transferred', () => {
|
|
signedOrder = buildSignedOrder();
|
|
transferrableMakerFeeTokenAmount = zero;
|
|
remainingMakeAssetAmount = signedOrder.makerAssetAmount;
|
|
calculator = new RemainingFillableCalculator(
|
|
signedOrder.makerFee,
|
|
signedOrder.makerAssetAmount,
|
|
isMakeAssetZRX,
|
|
transferrableMakeAssetAmount,
|
|
transferrableMakerFeeTokenAmount,
|
|
remainingMakeAssetAmount,
|
|
);
|
|
expect(calculator.computeRemainingFillable()).to.be.bignumber.equal(zero);
|
|
});
|
|
it('calculates the correct amount when balance is less than remaining fillable', () => {
|
|
signedOrder = buildSignedOrder();
|
|
const partiallyFilledAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(2), decimals);
|
|
remainingMakeAssetAmount = signedOrder.makerAssetAmount.minus(partiallyFilledAmount);
|
|
transferrableMakeAssetAmount = remainingMakeAssetAmount.minus(partiallyFilledAmount);
|
|
calculator = new RemainingFillableCalculator(
|
|
signedOrder.makerFee,
|
|
signedOrder.makerAssetAmount,
|
|
isMakeAssetZRX,
|
|
transferrableMakeAssetAmount,
|
|
transferrableMakerFeeTokenAmount,
|
|
remainingMakeAssetAmount,
|
|
);
|
|
expect(calculator.computeRemainingFillable()).to.be.bignumber.equal(transferrableMakeAssetAmount);
|
|
});
|
|
describe('Order to Fee Ratio is < 1', () => {
|
|
beforeEach(async () => {
|
|
[makerAmount, takerAmount, makerFeeAmount] = [
|
|
Web3Wrapper.toBaseUnitAmount(new BigNumber(3), decimals),
|
|
Web3Wrapper.toBaseUnitAmount(new BigNumber(6), decimals),
|
|
Web3Wrapper.toBaseUnitAmount(new BigNumber(6), decimals),
|
|
];
|
|
});
|
|
it('calculates the correct amount when funds unavailable', () => {
|
|
signedOrder = buildSignedOrder();
|
|
remainingMakeAssetAmount = signedOrder.makerAssetAmount;
|
|
const transferredAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(2), decimals);
|
|
transferrableMakeAssetAmount = remainingMakeAssetAmount.minus(transferredAmount);
|
|
calculator = new RemainingFillableCalculator(
|
|
signedOrder.makerFee,
|
|
signedOrder.makerAssetAmount,
|
|
isMakeAssetZRX,
|
|
transferrableMakeAssetAmount,
|
|
transferrableMakerFeeTokenAmount,
|
|
remainingMakeAssetAmount,
|
|
);
|
|
expect(calculator.computeRemainingFillable()).to.be.bignumber.equal(transferrableMakeAssetAmount);
|
|
});
|
|
});
|
|
describe('Ratio is not evenly divisble', () => {
|
|
beforeEach(async () => {
|
|
[makerAmount, takerAmount, makerFeeAmount] = [
|
|
Web3Wrapper.toBaseUnitAmount(new BigNumber(3), decimals),
|
|
Web3Wrapper.toBaseUnitAmount(new BigNumber(7), decimals),
|
|
Web3Wrapper.toBaseUnitAmount(new BigNumber(7), decimals),
|
|
];
|
|
});
|
|
it('calculates the correct amount when funds unavailable', () => {
|
|
signedOrder = buildSignedOrder();
|
|
remainingMakeAssetAmount = signedOrder.makerAssetAmount;
|
|
const transferredAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(2), decimals);
|
|
transferrableMakeAssetAmount = remainingMakeAssetAmount.minus(transferredAmount);
|
|
calculator = new RemainingFillableCalculator(
|
|
signedOrder.makerFee,
|
|
signedOrder.makerAssetAmount,
|
|
isMakeAssetZRX,
|
|
transferrableMakeAssetAmount,
|
|
transferrableMakerFeeTokenAmount,
|
|
remainingMakeAssetAmount,
|
|
);
|
|
const calculatedFillableAmount = calculator.computeRemainingFillable();
|
|
expect(calculatedFillableAmount.lessThanOrEqualTo(transferrableMakeAssetAmount)).to.be.true();
|
|
expect(calculatedFillableAmount).to.be.bignumber.greaterThan(new BigNumber(0));
|
|
const orderToFeeRatio = signedOrder.makerAssetAmount.dividedBy(signedOrder.makerFee);
|
|
const calculatedFeeAmount = calculatedFillableAmount.dividedBy(orderToFeeRatio);
|
|
expect(calculatedFeeAmount).to.be.bignumber.lessThan(transferrableMakerFeeTokenAmount);
|
|
});
|
|
});
|
|
});
|
|
describe('Maker Token is ZRX', () => {
|
|
before(async () => {
|
|
isMakeAssetZRX = true;
|
|
});
|
|
it('calculates the correct amount when unfilled and funds available', () => {
|
|
signedOrder = buildSignedOrder();
|
|
transferrableMakeAssetAmount = makerAmount.plus(makerFeeAmount);
|
|
transferrableMakerFeeTokenAmount = transferrableMakeAssetAmount;
|
|
remainingMakeAssetAmount = signedOrder.makerAssetAmount;
|
|
calculator = new RemainingFillableCalculator(
|
|
signedOrder.makerFee,
|
|
signedOrder.makerAssetAmount,
|
|
isMakeAssetZRX,
|
|
transferrableMakeAssetAmount,
|
|
transferrableMakerFeeTokenAmount,
|
|
remainingMakeAssetAmount,
|
|
);
|
|
expect(calculator.computeRemainingFillable()).to.be.bignumber.equal(remainingMakeAssetAmount);
|
|
});
|
|
it('calculates the correct amount when partially filled and funds available', () => {
|
|
signedOrder = buildSignedOrder();
|
|
remainingMakeAssetAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(1), decimals);
|
|
calculator = new RemainingFillableCalculator(
|
|
signedOrder.makerFee,
|
|
signedOrder.makerAssetAmount,
|
|
isMakeAssetZRX,
|
|
transferrableMakeAssetAmount,
|
|
transferrableMakerFeeTokenAmount,
|
|
remainingMakeAssetAmount,
|
|
);
|
|
expect(calculator.computeRemainingFillable()).to.be.bignumber.equal(remainingMakeAssetAmount);
|
|
});
|
|
it('calculates the amount to be 0 when all fee funds are transferred', () => {
|
|
signedOrder = buildSignedOrder();
|
|
transferrableMakeAssetAmount = zero;
|
|
transferrableMakerFeeTokenAmount = zero;
|
|
remainingMakeAssetAmount = signedOrder.makerAssetAmount;
|
|
calculator = new RemainingFillableCalculator(
|
|
signedOrder.makerFee,
|
|
signedOrder.makerAssetAmount,
|
|
isMakeAssetZRX,
|
|
transferrableMakeAssetAmount,
|
|
transferrableMakerFeeTokenAmount,
|
|
remainingMakeAssetAmount,
|
|
);
|
|
expect(calculator.computeRemainingFillable()).to.be.bignumber.equal(zero);
|
|
});
|
|
it('calculates the correct amount when balance is less than remaining fillable', () => {
|
|
signedOrder = buildSignedOrder();
|
|
const partiallyFilledAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(2), decimals);
|
|
remainingMakeAssetAmount = signedOrder.makerAssetAmount.minus(partiallyFilledAmount);
|
|
transferrableMakeAssetAmount = remainingMakeAssetAmount.minus(partiallyFilledAmount);
|
|
transferrableMakerFeeTokenAmount = transferrableMakeAssetAmount;
|
|
|
|
const orderToFeeRatio = signedOrder.makerAssetAmount.dividedToIntegerBy(signedOrder.makerFee);
|
|
const expectedFillableAmount = new BigNumber(450980);
|
|
calculator = new RemainingFillableCalculator(
|
|
signedOrder.makerFee,
|
|
signedOrder.makerAssetAmount,
|
|
isMakeAssetZRX,
|
|
transferrableMakeAssetAmount,
|
|
transferrableMakerFeeTokenAmount,
|
|
remainingMakeAssetAmount,
|
|
);
|
|
const calculatedFillableAmount = calculator.computeRemainingFillable();
|
|
const numberOfFillsInRatio = calculatedFillableAmount.dividedToIntegerBy(orderToFeeRatio);
|
|
const calculatedFillableAmountPlusFees = calculatedFillableAmount.plus(numberOfFillsInRatio);
|
|
expect(calculatedFillableAmountPlusFees).to.be.bignumber.lessThan(transferrableMakeAssetAmount);
|
|
expect(calculatedFillableAmountPlusFees).to.be.bignumber.lessThan(remainingMakeAssetAmount);
|
|
expect(calculatedFillableAmount).to.be.bignumber.equal(expectedFillableAmount);
|
|
expect(numberOfFillsInRatio.decimalPlaces()).to.be.equal(0);
|
|
});
|
|
});
|
|
});
|