@bayswap/sdk
Version:
SDK for BaySwap smart contract
116 lines • 4.05 kB
JavaScript
;
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