UNPKG

@hikaru-fi/sc-calculators

Version:

Package for pool calculations

251 lines (239 loc) 6.72 kB
import BN from 'bn.js'; import { MathSol } from '../utils/LogExpMath.mjs'; // 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} */ export 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} */ export 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} amountOut * @param {BN} balance * @param {BN} weight * @param {BN} lpTotalSupply * @param {BN} swapFeePercentage * @returns {BN} */ export function calculateLPAmountForTokenOut( amountOut, balance, weight, lpTotalSupply, swapFeePercentage ) { let denominator = MathSol.mulDownFixed(swapFeePercentage, MathSol.complementFixed(weight)); denominator = MathSol.sub(MathSol.ONE, denominator); denominator = MathSol.mulDownFixed(balance, denominator); let fraction = MathSol.divDownFixed(amountOut, denominator); fraction = MathSol.sub(MathSol.ONE, fraction); fraction = MathSol.powUpFixed(fraction, weight); return MathSol.sub(lpTotalSupply, MathSol.mulDownFixed(lpTotalSupply, fraction)); } /** * * @param {BN} amount * @param {BN} fee * @returns {BN} */ export function subtractFee(amount, fee) { const feeAmount = MathSol.mulUpFixed(amount, fee); return amount.sub(feeAmount); } /** * * @param {BN} amount * @param {BN} fee * @returns {BN} */ export function addFee(amount, fee) { return MathSol.divUpFixed(amount, MathSol.complementFixed(fee)); } /** * * @param {BN} amount * @param {BN} swapLimitCoefficient * @returns {BN} */ export function swapLimit(amount, swapLimitCoefficient) { return MathSol.mulDownFixed(amount, swapLimitCoefficient); } /** * * @param {BN} balanceIn * @param {BN} weightIn * @param {BN} balanceOut * @param {BN} weightOut * @param {BN} swapFee */ export function spotPrice( balanceIn, weightIn, balanceOut, weightOut, swapFee ) { const numerator = MathSol.mulUpFixed(balanceIn, weightOut); let denominator = MathSol.mulUpFixed(balanceOut, weightIn); denominator = MathSol.mulUpFixed(denominator, MathSol.complementFixed(swapFee)); return MathSol.divDownFixed(numerator, denominator); } /** * * @param {BN} bn * @returns {Number} */ export function bnToNum(bn) { return Number(bn.toString(10)); } /** * * @param {BN} balanceIn * @param {BN} weightIn * @param {BN} balanceOut * @param {BN} weightOut * @param {BN} swapFee * @returns {Number} */ export function spotPriceNumeric( balanceIn, weightIn, balanceOut, weightOut, swapFee ) { return (balanceIn * weightOut) / (balanceOut * weighdIn * (1 - swapFee)); } // 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} */ export 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} */ export 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) // ) }