UNPKG

@bayswap/sdk

Version:

SDK for BaySwap smart contract

116 lines 4.05 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.calReturnedCoinsAfterBurnt = exports.convertWithCurrentPrice = exports.calcOptimalValues = exports.getAmountOut = void 0; const curve_1 = require("./curve"); const BigZero = BigInt(0); const OneE8 = BigInt(10 ** 8); // mimic function get_amount_out<X, Y, Curve> from smart contract const getAmountOut = (pool, amtIn, reverse) => { let [reserveIn, reserveOut, scaleIn, scaleOut] = [ pool.coinXReserve, pool.coinYReserve, pool.xScale, pool.yScale, ]; if (reverse) { reserveIn = pool.coinYReserve; reserveOut = pool.coinXReserve; scaleIn = pool.yScale; scaleOut = pool.xScale; } const [feePercent, feeScale] = [pool.feePercent, BigInt(10000)]; // uncorrelated curve if ((0, curve_1.isUncorrelated)(pool.curve)) { const actualFeeScale = feeScale - feePercent; const coinInAfterFees = amtIn * actualFeeScale; const newReserveIn = reserveIn * feeScale + coinInAfterFees; return (coinInAfterFees * reserveOut) / newReserveIn; } else { return stableCoinOut(amtIn, scaleIn, scaleOut, reserveIn, reserveOut); } }; exports.getAmountOut = getAmountOut; const stableLpValue = (xCoin, xScale, yCoin, yScale) => { const _x = (xCoin * OneE8) / xScale; const _y = (yCoin * OneE8) / yScale; const _a = _x * _y; const _b = _x * _x + _y * _y; return _a * _b; }; const stableF = (x, y) => { const yyy = y * y * y; const a = x * yyy; const xxx = x * x * x; const b = xxx * y; return a + b; }; const stableD = (x0, y) => { const three = BigInt(3); // 3 * x0 * (y * y / 1e8) / 1e8 const x3 = three * x0; const yy = y * y; const xyy3 = x3 * yy; const xx = x0 * x0; // x0 * x0 / 1e8 * x0 / 1e8 const xxx = xx * x0; return xyy3 + xxx; }; const stableGetY = (x0, xy, y) => { let i = 0; const One = BigInt(1); while (i < 256) { const k = stableF(x0, y); let _dy = BigInt(0); if (k < xy) { _dy = (xy - k) / stableD(x0, y) + BigInt(1); y = y + _dy; } else { _dy = (k - xy) / stableD(x0, y); y = y - _dy; } if (_dy == One || _dy < One) { return y; } i = i + 1; } return y; }; const stableCoinOut = (coinIn, scaleIn, scaleOut, reserveIn, reserveOut) => { const lpValue = stableLpValue(reserveIn, scaleIn, reserveOut, scaleOut); const reserveInScale = (reserveIn * OneE8) / scaleIn; const reserveOutScale = (reserveOut * OneE8) / scaleOut; const amountIn = (coinIn * OneE8) / scaleIn; const totalReserve = amountIn + reserveInScale; const y = reserveOutScale - stableGetY(totalReserve, lpValue, reserveOutScale); return (y * scaleOut) / OneE8; }; const calcOptimalValues = (pool, amtX, amtY) => { if (pool.coinXReserve == BigZero && pool.coinXReserve == BigZero) { return [amtX, amtY]; } const yReturned = (0, exports.convertWithCurrentPrice)(amtX, pool.coinXReserve, pool.coinYReserve); if (yReturned <= amtY) { return [amtX, yReturned]; } else { const xReturned = (0, exports.convertWithCurrentPrice)(amtY, pool.coinYReserve, pool.coinXReserve); if (xReturned <= amtX) { return [xReturned, amtY]; } throw new Error('invalid amt x or amt y'); } }; exports.calcOptimalValues = calcOptimalValues; const convertWithCurrentPrice = (coinIn, reserveIn, reserveOut) => { return (coinIn * reserveOut) / reserveIn; }; exports.convertWithCurrentPrice = convertWithCurrentPrice; const calReturnedCoinsAfterBurnt = (xReserve, yReserve, curSupply, burntLp) => { const xToReturned = (burntLp * xReserve) / curSupply; const yToReturned = (burntLp * yReserve) / curSupply; return [xToReturned, yToReturned]; }; exports.calReturnedCoinsAfterBurnt = calReturnedCoinsAfterBurnt; //# sourceMappingURL=math.js.map