aboutsummaryrefslogblamecommitdiffstats
path: root/packages/order-utils/test/remaining_fillable_calculator_test.ts
blob: a5a3b7fc6354088198bfb31b2c2ac392cd232346 (plain) (tree)
1
2
3
4
5
6
7
8
9
                                               
                                             
                                                      


                             
                                                                                   
 
                                               



                           
                                               

                                                
                                                
                                                    
                                            

                               
                                  


                                         
                               

                                             

                                                                                                                                                 
                            
                                                      


                                                                      
          
                                                                            

                                                                      
          

                                              
                





                                             

                                     



                                          
                       
                                        
          
     
                                              
                            
                                   


                                                                                     
                                                                    
                                                         

                                             

                                             
                                                 
                                         
              
                                                                                                          


                                                                                             
                                                                                                
                                                         

                                             

                                             
                                                 
                                         
              
                                                                                                          

                                                                                      
                                             
                                                    
                                                                    
                                                         

                                             

                                             
                                                 
                                         
              
                                                                                      
           

                                                                                                
                                                                                                   

                                                                                                 
                                                         

                                             

                                             
                                                 
                                         
              
                                                                                                              
           

                                                     
                                                              


                                                                             
                  


                                                                              
                                                                        
                                                                                                   
                                                                                                 
                                                             

                                                 

                                                 
                                                     
                                             
                  
                                                                                                                  



                                                        
                                                              


                                                                             
                  


                                                                              
                                                                        
                                                                                                   
                                                                                                 
                                                             

                                                 

                                                 
                                                     
                                             
                  

                                                                                                              
                                                                                               
                                                                                                     



                                                                                                       


                                          
                                  
           

                                                                                     


                                                                            
                                                         

                                             

                                             
                                                 
                                         
              
                                                                                                          
           

                                                                                             
                                                                                                
                                                         

                                             

                                             
                                                 
                                         
              
                                                                                                          
           
                                                                                      
                                             
                                                
                                                    
                                                                    
                                                         

                                             

                                             
                                                 
                                         
              
                                                                                      
           

                                                                                                
                                                                                                   


                                                                                                 
 
                                                                                                          
                                                                 
                                                         

                                             

                                             
                                                 
                                         
              
                                                                                   
                                                                                                      
                                                                                                         

                                                                                                            

                                                                                           
           

       
import { SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/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);
        });
    });
});