@renec-foundation/redex-sdk
Version:
Typescript SDK to interact with Orca's Whirlpool program.
101 lines (100 loc) • 4.34 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculatePositionAPR = exports.calculateTokenPositionRewardAPR = exports.calculatePoolAPR = void 0;
const decimal_js_1 = __importDefault(require("decimal.js"));
/**
* @param emissionPerWeek : reward for weekly emission
* @param tokenPrice : price of token in USDT
* @param tvl : Liquidity is TVL
* @returns : Reward APR for token
*/
function calculateTokenPoolRewardAPR(emissionPerWeek, tokenPrice, tvl) {
// reward = emissionPerWeek x tokenPrice x (365/7) / TVL
return new decimal_js_1.default(emissionPerWeek)
.mul(tokenPrice)
.mul(new decimal_js_1.default(365).div(7))
.div(tvl)
.toNumber();
}
/**
*
* @param vol24H : volumn 24h of pool
* @param feeRate : fee rate in raw value Eg: 0.001% -> 0.00001
* @param tvl : Liquidity is TVL
* @param rewards : rewards tokens APR maybe contain one or more or nothing reward token
* @param toPercent : APR result in percentage or not
* @returns see: PoolAPRReward
*/
function calculatePoolAPR(vol24H, feeRate, tvl, rewards, toPercent = true) {
// feeAPR = vol24H x feeRate x 365 / TVL
const feeAPR = new decimal_js_1.default(vol24H).mul(feeRate).mul(365).div(tvl).toNumber();
// compute reward for each token
if (!rewards || Object.keys(rewards).length === 0) {
return {
apr: toPercent ? new decimal_js_1.default(feeAPR).mul(100).toNumber() : feeAPR,
rewards: null,
};
}
const rewardEachToken = {};
let totalReward = new decimal_js_1.default(0);
// compute reward for each token
Object.entries(rewards).forEach(([key, value]) => {
const rewardApr = calculateTokenPoolRewardAPR(value.emissionPerWeek, value.tokenPrice, tvl);
totalReward = totalReward.add(rewardApr);
rewardEachToken[key] = toPercent ? new decimal_js_1.default(rewardApr).mul(100).toNumber() : rewardApr;
});
// totalAPR = feeAPR + totalReward
const totalAPR = new decimal_js_1.default(feeAPR).add(totalReward).toNumber();
return {
apr: toPercent ? new decimal_js_1.default(totalAPR).mul(100).toNumber() : totalAPR,
rewards: rewardEachToken,
};
}
exports.calculatePoolAPR = calculatePoolAPR;
function calculateTokenPositionRewardAPR(emissionPerWeek, tokenPrice, share, positionBalance) {
// rewardAPR = emissionPerWeek x tokenPrice x (365/7) x share / positionBalance
return new decimal_js_1.default(emissionPerWeek)
.mul(tokenPrice)
.mul(new decimal_js_1.default(365).div(7))
.mul(share)
.div(positionBalance)
.toNumber();
}
exports.calculateTokenPositionRewardAPR = calculateTokenPositionRewardAPR;
function calculatePositionAPR(vol24H, feeRate, lp, lpInRange, positionBalance, rewards, toPercent = true) {
// share of position's liquidity
// share = lp / LP
const share = new decimal_js_1.default(lp).div(lpInRange).toNumber();
// feeAPR = vol24H x feeRate x 365 x share / balance
const feeAPR = new decimal_js_1.default(vol24H)
.mul(feeRate)
.mul(365)
.mul(share)
.div(positionBalance)
.toNumber();
// compute reward for each token
if (!rewards || Object.keys(rewards).length === 0) {
return {
apr: toPercent ? new decimal_js_1.default(feeAPR).mul(100).toNumber() : feeAPR,
rewards: null,
};
}
const rewardEachToken = {};
let totalReward = new decimal_js_1.default(0);
// compute reward for each token
Object.entries(rewards).forEach(([key, value]) => {
const rewardApr = calculateTokenPositionRewardAPR(value.emissionPerWeek, value.tokenPrice, share, positionBalance);
totalReward = totalReward.add(rewardApr);
rewardEachToken[key] = toPercent ? rewardApr * 100 : rewardApr;
});
// totalAPR = feeAPR + totalRewardToken
const totalAPR = new decimal_js_1.default(feeAPR).add(totalReward).toNumber();
return {
apr: toPercent ? new decimal_js_1.default(totalAPR).mul(100).toNumber() : totalAPR,
rewards: rewardEachToken,
};
}
exports.calculatePositionAPR = calculatePositionAPR;