UNPKG

@hikaru-fi/swap-router

Version:

Package for calculating optimal path for executing swaps

186 lines (176 loc) 4.85 kB
const BN = require('bn.js'); const { MathSol } = require('../utils/LogExpMath'); // The following function are BN versions implemented by Sergio. // BN was requested from integrators as it is more efficient. // Swap outcomes formulas should match exactly those from smart contracts. // PairType = 'token->token' // SwapType = 'swapExactIn' /** * * @param {BN} balanceIn * @param {BN} weightIn * @param {BN} balanceOut * @param {BN} weightOut * @param {BN} amountIn * @param {BN} fee * @returns {BN} */ function calcOutGivenIn( balanceIn, weightIn, balanceOut, weightOut, amountIn, fee ) { // is it necessary to check ranges of variables? same for the other functions amountIn = subtractFee(amountIn, fee); const exponent = MathSol.divDownFixed(weightIn, weightOut); const denominator = MathSol.add(balanceIn, amountIn); const base = MathSol.divUpFixed(balanceIn, denominator); const power = MathSol.powUpFixed(base, exponent); return MathSol.mulDownFixed(balanceOut, MathSol.complementFixed(power)); } // PairType = 'token->token' // SwapType = 'swapExactOut' /** * * @param {BN} balanceIn * @param {BN} weightIn * @param {BN} balanceOut * @param {BN} weightOut * @param {BN} amountOut * @param {BN} fee * @returns {BN} */ function calcInGivenOut( balanceIn, weightIn, balanceOut, weightOut, amountOut, fee ) { const base = MathSol.divUpFixed(balanceOut, balanceOut.sub(amountOut)); const exponent = MathSol.divUpFixed(weightOut, weightIn); const power = MathSol.powUpFixed(base, exponent); const ratio = MathSol.sub(power, MathSol.ONE); const amountIn = MathSol.mulUpFixed(balanceIn, ratio); return addFee(amountIn, fee); } /** * * @param {BN} amount * @param {BN} fee * @returns {BN} */ function subtractFee(amount, fee) { const feeAmount = MathSol.mulUpFixed(amount, fee); return amount.sub(feeAmount); } /** * * @param {BN} amount * @param {BN} fee * @returns {BN} */ function addFee(amount, fee) { return MathSol.divUpFixed(amount, MathSol.complementFixed(fee)); } /** * * @param {BN} amount * @param {BN} swapLimitCoefficient * @returns {BN} */ function swapLimit(amount, swapLimitCoefficient) { return MathSol.mulDownFixed(amount, swapLimitCoefficient); } // TO DO - Swap old versions of these in Pool for the BN version // PairType = 'token->token' // SwapType = 'swapExactIn' /** * * @param {BN} balanceIn * @param {BN} weightIn * @param {BN} balanceOut * @param {BN} weightOut * @param {BN} amountIn * @param {BN} fee * @returns {BN} */ function _spotPriceAfterSwapExactTokenInForTokenOutBN( balanceIn, weightIn, balanceOut, weightOut, amountIn, fee ) { const numerator = MathSol.mulUpFixed(balanceIn, weightOut); let denominator = MathSol.mulUpFixed(balanceOut, weightIn); const feeComplement = MathSol.complementFixed(fee); denominator = MathSol.mulUpFixed(denominator, feeComplement); const base = MathSol.divUpFixed( balanceIn, MathSol.add(MathSol.mulUpFixed(amountIn, feeComplement), balanceIn) ); const exponent = MathSol.divUpFixed(weightIn.add(weightOut), weightOut); denominator = MathSol.mulUpFixed( denominator, MathSol.powUpFixed(base, exponent) ); return MathSol.divUpFixed(numerator, denominator); // -( // (Bi * wo) / // (Bo * (-1 + f) * (Bi / (Ai + Bi - Ai * f)) ** ((wi + wo) / wo) * wi) // ) } // PairType = 'token->token' // SwapType = 'swapExactOut' /** * * @param {BN} balanceIn * @param {BN} weightIn * @param {BN} balanceOut * @param {BN} weightOut * @param {BN} amountOut * @param {BN} fee * @returns {BN} */ function _spotPriceAfterSwapTokenInForExactTokenOutBN( balanceIn, weightIn, balanceOut, weightOut, amountOut, fee ) { let numerator = MathSol.mulUpFixed(balanceIn, weightOut); const feeComplement = MathSol.complementFixed(fee); const base = MathSol.divUpFixed( balanceOut, MathSol.sub(balanceOut, amountOut) ); const exponent = MathSol.divUpFixed(weightIn.add(weightOut), weightIn); numerator = MathSol.mulUpFixed( numerator, MathSol.powUpFixed(base, exponent) ); const denominator = MathSol.mulUpFixed( MathSol.mulUpFixed(balanceOut, weightIn), feeComplement ); return MathSol.divUpFixed(numerator, denominator); // -( // (Bi * (Bo / (-Ao + Bo)) ** ((wi + wo) / wi) * wo) / // (Bo * (-1 + f) * wi) // ) } module.exports = { calcOutGivenIn, calcInGivenOut, swapLimit, _spotPriceAfterSwapExactTokenInForTokenOutBN, _spotPriceAfterSwapTokenInForExactTokenOutBN }