fbonds-core
Version:
Banx protocol sdk
609 lines (608 loc) • 39 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculateBanxSolStakingRewards = exports.calculateCollateralPerTokens = exports.getTokenMintFromLendingTokenType = exports.getFullLoanBodyFromBorrowerSendedAmount = exports.getBondingCurveTypeFromLendingToken = exports.calculateInputFeeWhenBorrow = exports.calculatePartOfLoanBodyFromInterest = exports.getRepaymentDestination = exports.calculateLoanRepayValue = exports.calculateDynamicApr = exports.calculateAccruedInterestOfRepaidBondTradeTransaction = exports.checkIsTestDev = exports.checkIsHadomarketSponsored = exports.getPerpetualOfferSizeBonding = exports.getPerpetualOfferSize = exports.getPerpetualBorrowerActivity = exports.getPerpetualBorrowerActivityV3 = exports.getPerpetualLenderActivity = exports.getPerpetualLenderActivityV3 = exports.calculateCurrentInterestSolPureBN = exports.calculateCurrentInterestSolPure = exports.basePointsToWads = exports.basePointsToWadsBN = exports.wadDivBN = exports.wadMulBN = exports.wadDiv = exports.wadMul = exports.nowInSeconds = exports.getRepayAmountOfBondTradeTransaction = exports.optimisticInitializeBondOffer = exports.optimisticInitializeBondTradeTransaction = void 0;
const helpers_1 = require("../../../helpers");
const bond_trade_transaction_calculators_1 = require("../../../calculators/bond_trade_transaction_calculators");
const constants_1 = require("../../../constants");
const types_1 = require("../../../types");
const amm_helpers_1 = require("./amm_helpers");
const anchor_1 = require("@coral-xyz/anchor");
const lodash_1 = require("lodash");
// TODO: Gleb - Change defaults after migration
const optimisticInitializeBondTradeTransaction = (args) => {
const feeAmount = (0, exports.calculateInputFeeWhenBorrow)({
amountToGet: args.loanValue,
previousDebt: args.previousDebt,
inputFee: args.inputFee,
isRefinance: args.isRefinance,
isBorrower: args.isBorrower,
inputFeeBp: args.protocolInputFee,
});
const solAmount = args.loanValue.sub(feeAmount);
return {
publicKey: args.bondTradeTransaction,
protocolInterestFee: args.protocolInterestFee,
bondTradeTransactionState: args.isStakedBanx
? types_1.BondTradeTransactionV2State.PerpetualManualTerminating
: args.isRefinance
? types_1.BondTradeTransactionV2State.PerpetualRefinancedActive
: types_1.BondTradeTransactionV2State.PerpetualActive,
bondOffer: args.bondOffer,
user: args.assetReceiver,
amountOfBonds: args.marketApr,
solAmount: solAmount,
feeAmount: feeAmount,
bondTradeTransactionType: args.isSplCollateral
? types_1.BondTradeTransactionV2Type.AutoReceiveAndReceiveSpl
: types_1.BondTradeTransactionV2Type.AutoReceiveAndReceiveNft,
fbondTokenMint: args.fraktBond,
soldAt: new anchor_1.BN(new anchor_1.BN((0, exports.nowInSeconds)())),
redeemedAt: new anchor_1.BN(0),
redeemResult: args.redeemResult,
seller: args.borrower,
isDirectSell: args.isBorrower,
lendingToken: args.lendingToken,
lenderOriginalLent: (0, bond_trade_transaction_calculators_1.calculateOriginalLent)(solAmount, feeAmount),
lenderFullRepaidAmount: (0, bond_trade_transaction_calculators_1.calculateFullRepaidAmount)(args),
currentRemainingLent: (0, bond_trade_transaction_calculators_1.calculateCurrentRemainingLent)(args),
terminationStartedAt: (0, bond_trade_transaction_calculators_1.getTerminationStartedAt)(args),
interestSnapshot: new anchor_1.BN(0),
partialRepaySnapshot: new anchor_1.BN(0),
borrowerOriginalLent: args.isRefinance && !args.isBorrower ? args.borrowerOriginalLent : (0, bond_trade_transaction_calculators_1.calculateOriginalLent)(solAmount, feeAmount),
borrowerFullRepaidAmount: args.isRefinance && !args.isBorrower ? args.borrowerOriginalLent : new anchor_1.BN(0),
repayDestination: types_1.RepayDestination.None,
repaymentCallAmount: new anchor_1.BN(0),
terminationFreeze: new anchor_1.BN(0),
redeemResultNext: types_1.RedeemResult.None,
collateralAmountSnapshot: new anchor_1.BN(0),
};
};
exports.optimisticInitializeBondTradeTransaction = optimisticInitializeBondTradeTransaction;
const optimisticInitializeBondOffer = (args) => ({
hadoMarket: args.hadoMarket,
pairState: types_1.PairState.PerpetualOnMarket,
bondingCurve: { delta: new anchor_1.BN(0), bondingType: types_1.BondingCurveType.Linear },
baseSpotPrice: args.loanValue,
mathCounter: new anchor_1.BN(0),
currentSpotPrice: args.loanValue,
concentrationIndex: new anchor_1.BN(0),
bidCap: new anchor_1.BN(0),
bidSettlement: new anchor_1.BN(0),
edgeSettlement: new anchor_1.BN(0),
fundsSolOrTokenBalance: new anchor_1.BN(0),
buyOrdersQuantity: new anchor_1.BN(1),
lastTransactedAt: new anchor_1.BN(new anchor_1.BN((0, exports.nowInSeconds)())),
assetReceiver: args.assetReceiver,
validation: {
loanToValueFilter: new anchor_1.BN(0),
collateralsPerToken: new anchor_1.BN(0),
maxReturnAmountFilter: new anchor_1.BN(0),
bondFeatures: types_1.BondFeatures.AutoReceiveAndReceiveNft,
},
publicKey: args.bondOffer,
loanApr: new anchor_1.BN(0),
liquidationLtvBp: new anchor_1.BN(0),
offerLtvBp: new anchor_1.BN(0),
});
exports.optimisticInitializeBondOffer = optimisticInitializeBondOffer;
const getRepayAmountOfBondTradeTransaction = (bondTradeTransaction) => {
const fullLoanBody = bondTradeTransaction.solAmount.add(bondTradeTransaction.feeAmount);
const now = new anchor_1.BN(new anchor_1.BN((0, exports.nowInSeconds)()));
const interestSol = (0, exports.calculateCurrentInterestSolPureBN)({
loanValue: fullLoanBody,
startTime: bondTradeTransaction.soldAt,
currentTime: now,
rateBasePoints: bondTradeTransaction.amountOfBonds.add(new anchor_1.BN((0, helpers_1.calcRepayFeeAprFromBondTradeTransaction)(bondTradeTransaction, constants_1.EMPTY_PUBKEY))),
});
return fullLoanBody.add(interestSol);
};
exports.getRepayAmountOfBondTradeTransaction = getRepayAmountOfBondTradeTransaction;
const nowInSeconds = () => Math.floor((0, lodash_1.now)() / 1000);
exports.nowInSeconds = nowInSeconds;
const wadMul = (x, y) => Math.floor((x * y) / constants_1.SOL_WAD);
exports.wadMul = wadMul;
const wadDiv = (x, y) => Math.floor((x * constants_1.SOL_WAD) / y);
exports.wadDiv = wadDiv;
const wadMulBN = (x, y) => x.mul(y).div(new anchor_1.BN(constants_1.SOL_WAD));
exports.wadMulBN = wadMulBN;
const wadDivBN = (x, y) => x.mul(new anchor_1.BN(constants_1.SOL_WAD)).div(y);
exports.wadDivBN = wadDivBN;
const basePointsToWadsBN = (basePoints) => basePoints.mul(new anchor_1.BN(constants_1.SOL_WAD)).div(new anchor_1.BN(constants_1.BASE_POINTS));
exports.basePointsToWadsBN = basePointsToWadsBN;
const basePointsToWads = (basePoints) => Math.floor((basePoints * constants_1.SOL_WAD) / constants_1.BASE_POINTS);
exports.basePointsToWads = basePointsToWads;
const calculateCurrentInterestSolPure = ({ loanValue, startTime, currentTime, rateBasePoints, }) => {
const loanTime = currentTime - startTime;
const secondsInYearWad = constants_1.SECONDS_IN_YEAR * constants_1.SOL_WAD;
const yearsWad = (0, exports.wadDiv)(loanTime * constants_1.SOL_WAD, secondsInYearWad);
const result = (0, exports.wadMul)(loanValue, (0, exports.wadMul)(yearsWad, (0, exports.basePointsToWads)(rateBasePoints)));
return result;
};
exports.calculateCurrentInterestSolPure = calculateCurrentInterestSolPure;
const calculateCurrentInterestSolPureBN = ({ loanValue, startTime, currentTime, rateBasePoints, }) => {
const loanTime = currentTime.sub(startTime);
const secondsInYearWad = new anchor_1.BN(constants_1.SECONDS_IN_YEAR).mul(new anchor_1.BN(constants_1.SOL_WAD));
const yearsWad = (0, exports.wadDivBN)(loanTime.mul(new anchor_1.BN(constants_1.SOL_WAD)), secondsInYearWad);
const result = (0, exports.wadMulBN)(loanValue, (0, exports.wadMulBN)(yearsWad, (0, exports.basePointsToWadsBN)(rateBasePoints)));
return result;
};
exports.calculateCurrentInterestSolPureBN = calculateCurrentInterestSolPureBN;
const getPerpetualLenderActivityV3 = (args) => {
const loanValue = args.bondTradeTransaction.solAmount.add(args.bondTradeTransaction.feeAmount);
const initializeActivity = {
lent: args.bondTradeTransaction.lenderOriginalLent,
currentRemainingLentAmount: args.bondTradeTransaction.currentRemainingLent,
isNewLoan: args.bondTradeTransaction.isDirectSell,
interest: new anchor_1.BN(0),
apr: args.bondTradeTransaction.amountOfBonds,
status: types_1.BondTradeTransactionV2State.PerpetualActive,
duration: new anchor_1.BN(0),
received: new anchor_1.BN(0),
nftMint: args.fraktBond.fbondTokenMint,
lender: args.bondTradeTransaction.user,
borrower: args.fraktBond.fbondIssuer,
timestamp: args.bondTradeTransaction.soldAt,
publicKey: args.bondTradeTransaction.publicKey,
};
const initializeActivityToAdd = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualActive
? [initializeActivity]
: [];
const manualTerminationActivity = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualManualTerminating ||
args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualLiquidatedByClaim
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualManualTerminating, duration: args.fraktBond.refinanceAuctionStartedAt.sub(args.bondTradeTransaction.soldAt), timestamp: args.fraktBond.refinanceAuctionStartedAt || new anchor_1.BN((0, exports.nowInSeconds)()) }),
]
: [];
const liquidatingAt = args.fraktBond.refinanceAuctionStartedAt &&
args.fraktBond.refinanceAuctionStartedAt.add(new anchor_1.BN(constants_1.TERMINATION_PERIOD));
const liquidationActivity = (args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualManualTerminating &&
args.fraktBond.refinanceAuctionStartedAt &&
liquidatingAt < new anchor_1.BN(new anchor_1.BN((0, exports.nowInSeconds)()))) ||
args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualLiquidatedByClaim
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualLiquidatedByClaim, duration: liquidatingAt.sub(args.bondTradeTransaction.soldAt), timestamp: liquidatingAt }),
]
: [];
const interestRepaid = args.bondTradeTransaction.redeemedAt &&
(0, exports.calculateCurrentInterestSolPureBN)({
loanValue: loanValue,
startTime: args.bondTradeTransaction.soldAt,
currentTime: args.bondTradeTransaction.redeemedAt,
rateBasePoints: args.bondTradeTransaction.amountOfBonds,
});
const repayActivity = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualRepaid
? [
Object.assign(Object.assign({}, initializeActivity), { status: args.bondTradeTransaction.bondTradeTransactionState, timestamp: args.bondTradeTransaction.redeemedAt, interest: interestRepaid, received: loanValue.add(interestRepaid), duration: args.bondTradeTransaction.redeemedAt.sub(args.fraktBond.activatedAt) }),
]
: [];
const refinanceActivity = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualRefinancedActive
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualRefinancedActive }),
]
: [];
const refinanceRepaidActivity = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualRefinanceRepaid
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualRefinanceRepaid, timestamp: args.bondTradeTransaction.redeemedAt, interest: interestRepaid, received: loanValue.add(interestRepaid), duration: args.bondTradeTransaction.redeemedAt.sub(args.fraktBond.activatedAt) }),
]
: [];
const partialRepayActivity = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualPartialRepaid
? [
Object.assign(Object.assign({}, initializeActivity), { currentRemainingLentAmount: args.bondTradeTransaction.currentRemainingLent.sub(args.bondTradeTransaction.partialRepaySnapshot), status: types_1.BondTradeTransactionV2State.PerpetualPartialRepaid, timestamp: args.bondTradeTransaction.redeemedAt, interest: interestRepaid, received: args.bondTradeTransaction.partialRepaySnapshot.add(interestRepaid), duration: args.bondTradeTransaction.redeemedAt.sub(args.fraktBond.activatedAt) }),
]
: [];
return [
...initializeActivityToAdd,
...manualTerminationActivity,
...liquidationActivity,
...repayActivity,
...refinanceActivity,
...refinanceRepaidActivity,
...partialRepayActivity,
];
};
exports.getPerpetualLenderActivityV3 = getPerpetualLenderActivityV3;
const getPerpetualLenderActivity = (args) => {
const loanValue = args.bondTradeTransaction.solAmount.add(args.bondTradeTransaction.feeAmount);
const initializeActivity = {
lent: args.fraktBond.currentPerpetualBorrowed,
currentRemainingLentAmount: loanValue,
isNewLoan: args.bondTradeTransaction.isDirectSell,
interest: new anchor_1.BN(0),
apr: args.bondTradeTransaction.amountOfBonds,
status: types_1.BondTradeTransactionV2State.PerpetualActive,
duration: new anchor_1.BN(0),
received: new anchor_1.BN(0),
nftMint: args.fraktBond.fbondTokenMint,
lender: args.bondTradeTransaction.user,
borrower: args.fraktBond.fbondIssuer,
timestamp: args.bondTradeTransaction.soldAt,
publicKey: args.bondTradeTransaction.publicKey,
};
const initializeActivityToAdd = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualActive
? [initializeActivity]
: [];
const manualTerminationActivity = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualManualTerminating ||
args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualLiquidatedByClaim
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualManualTerminating, duration: args.fraktBond.refinanceAuctionStartedAt.sub(args.bondTradeTransaction.soldAt), timestamp: args.fraktBond.refinanceAuctionStartedAt || new anchor_1.BN((0, exports.nowInSeconds)()) }),
]
: [];
const liquidatingAt = args.fraktBond.refinanceAuctionStartedAt &&
args.fraktBond.refinanceAuctionStartedAt.add(new anchor_1.BN(constants_1.TERMINATION_PERIOD));
const liquidationActivity = (args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualManualTerminating &&
args.fraktBond.refinanceAuctionStartedAt &&
liquidatingAt < new anchor_1.BN(new anchor_1.BN((0, exports.nowInSeconds)()))) ||
args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualLiquidatedByClaim
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualLiquidatedByClaim, duration: liquidatingAt.sub(args.bondTradeTransaction.soldAt), timestamp: liquidatingAt }),
]
: [];
const interestRepaid = args.bondTradeTransaction.redeemedAt &&
(0, exports.calculateCurrentInterestSolPureBN)({
loanValue: loanValue,
startTime: args.bondTradeTransaction.soldAt,
currentTime: args.bondTradeTransaction.redeemedAt,
rateBasePoints: args.bondTradeTransaction.amountOfBonds,
});
const repayActivity = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualRepaid
? [
Object.assign(Object.assign({}, initializeActivity), { status: args.bondTradeTransaction.bondTradeTransactionState, timestamp: args.bondTradeTransaction.redeemedAt, interest: interestRepaid, received: loanValue.add(interestRepaid), duration: args.bondTradeTransaction.redeemedAt.sub(args.fraktBond.activatedAt) }),
]
: [];
const refinanceActivity = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualRefinancedActive
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualRefinancedActive }),
]
: [];
const refinanceRepaidActivity = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualRefinanceRepaid
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualRefinanceRepaid, timestamp: args.bondTradeTransaction.redeemedAt, interest: interestRepaid, received: loanValue.add(interestRepaid), duration: args.bondTradeTransaction.redeemedAt.sub(args.fraktBond.activatedAt) }),
]
: [];
const partialRepayActivity = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualPartialRepaid
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualPartialRepaid, timestamp: args.bondTradeTransaction.redeemedAt, interest: interestRepaid, received: loanValue.add(interestRepaid), duration: args.bondTradeTransaction.redeemedAt.sub(args.fraktBond.activatedAt) }),
]
: [];
return [
...initializeActivityToAdd,
...manualTerminationActivity,
...liquidationActivity,
...repayActivity,
...refinanceActivity,
...refinanceRepaidActivity,
...partialRepayActivity,
];
};
exports.getPerpetualLenderActivity = getPerpetualLenderActivity;
const getPerpetualBorrowerActivityV3 = (args) => {
const remainingLentAmount = args.bondTradeTransaction.solAmount.add(args.bondTradeTransaction.feeAmount);
const initializeActivity = {
borrowed: args.bondTradeTransaction.borrowerOriginalLent,
currentLentAmount: args.fraktBond.currentPerpetualBorrowed,
currentRemainingLentAmount: args.bondTradeTransaction.currentRemainingLent,
interest: args.bondTradeTransaction.interestSnapshot,
apr: args.bondTradeTransaction.amountOfBonds,
status: types_1.BondTradeTransactionV2State.PerpetualActive,
duration: new anchor_1.BN(0),
repaid: new anchor_1.BN(0),
borrower: args.fraktBond.fbondIssuer,
nftMint: args.fraktBond.fbondTokenMint,
timestamp: args.fraktBond.activatedAt,
publicKey: args.fraktBond.publicKey,
bondTradeTransaction: args.bondTradeTransaction.publicKey,
};
const initializeActivityToAdd = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualActive
? [initializeActivity]
: [];
const manualTerminationActivity = args.fraktBond.refinanceAuctionStartedAt > new anchor_1.BN(0) &&
(args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualManualTerminating ||
args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualLiquidatedByClaim ||
args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualRefinanceRepaid)
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualManualTerminating, duration: args.fraktBond.refinanceAuctionStartedAt.sub(args.bondTradeTransaction.soldAt), timestamp: args.fraktBond.refinanceAuctionStartedAt || new anchor_1.BN((0, exports.nowInSeconds)()) }),
]
: [];
const liquidatingAt = args.fraktBond.refinanceAuctionStartedAt &&
args.fraktBond.refinanceAuctionStartedAt.add(new anchor_1.BN(constants_1.TERMINATION_PERIOD));
const liquidationActivity = args.fraktBond.refinanceAuctionStartedAt &&
liquidatingAt < new anchor_1.BN((0, exports.nowInSeconds)()) &&
args.fraktBond.fraktBondState !== types_1.FraktBondState.PerpetualRepaid
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualLiquidatedByClaim, duration: liquidatingAt.sub(args.fraktBond.activatedAt), timestamp: liquidatingAt }),
]
: [];
// const interestRepaid = args.fraktBond.actualReturnedAmount - args.fraktBond.borrowedAmount;
const currentLoanValue = args.bondTradeTransaction.solAmount.add(args.bondTradeTransaction.feeAmount);
const interestRepaid = args.bondTradeTransaction.redeemedAt &&
(0, exports.calculateCurrentInterestSolPureBN)({
loanValue: currentLoanValue,
startTime: args.bondTradeTransaction.soldAt,
currentTime: args.bondTradeTransaction.redeemedAt,
rateBasePoints: args.bondTradeTransaction.amountOfBonds,
});
const repayActivity = args.fraktBond.fraktBondState == types_1.FraktBondState.PerpetualRepaid &&
args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualRepaid
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualRepaid, timestamp: args.fraktBond.repaidOrLiquidatedAt, repaid: currentLoanValue.add(interestRepaid), duration: args.fraktBond.repaidOrLiquidatedAt.sub(args.fraktBond.activatedAt) }),
]
: [];
const refinanceActivity = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualRefinancedActive ||
(args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualManualTerminating &&
args.bondTradeTransaction.redeemResult == types_1.RedeemResult.RefinancedByAuction)
? [
Object.assign(Object.assign({}, initializeActivity), { timestamp: args.bondTradeTransaction.soldAt, status: types_1.BondTradeTransactionV2State.PerpetualRefinancedActive }),
]
: [];
const refinanceRepaidActivity = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualRefinanceRepaid
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualRefinanceRepaid, timestamp: args.bondTradeTransaction.redeemedAt, repaid: currentLoanValue.add(interestRepaid), duration: args.fraktBond.repaidOrLiquidatedAt.sub(args.fraktBond.activatedAt) }),
]
: [];
// const interestPartialRepaid = args.fraktBond.actualReturnedAmount - args.fraktBond.borrowedAmount;
const partialRepayActivity = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualPartialRepaid
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualPartialRepaid, timestamp: args.bondTradeTransaction.redeemedAt, currentRemainingLentAmount: args.bondTradeTransaction.currentRemainingLent.sub(args.bondTradeTransaction.partialRepaySnapshot), repaid: currentLoanValue.add(interestRepaid), duration: args.fraktBond.repaidOrLiquidatedAt.sub(args.fraktBond.activatedAt) }),
]
: [];
return [
...initializeActivityToAdd,
...manualTerminationActivity,
...liquidationActivity,
...repayActivity,
...refinanceRepaidActivity,
...refinanceActivity,
...partialRepayActivity,
];
};
exports.getPerpetualBorrowerActivityV3 = getPerpetualBorrowerActivityV3;
const getPerpetualBorrowerActivity = (args) => {
const remainingLentAmount = args.bondTradeTransaction.solAmount.add(args.bondTradeTransaction.feeAmount);
// const loanValue = args.fraktBond.borrowedAmount;
const initializeActivity = {
borrowed: args.fraktBond.borrowedAmount,
currentLentAmount: args.fraktBond.currentPerpetualBorrowed,
currentRemainingLentAmount: remainingLentAmount,
interest: new anchor_1.BN(0),
apr: args.bondTradeTransaction.amountOfBonds,
status: types_1.BondTradeTransactionV2State.PerpetualActive,
duration: new anchor_1.BN(0),
repaid: new anchor_1.BN(0),
borrower: args.fraktBond.fbondIssuer,
nftMint: args.fraktBond.fbondTokenMint,
timestamp: args.fraktBond.activatedAt,
publicKey: args.fraktBond.publicKey,
bondTradeTransaction: args.bondTradeTransaction.publicKey,
};
const initializeActivityToAdd = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualActive
? [initializeActivity]
: [];
const manualTerminationActivity = args.fraktBond.refinanceAuctionStartedAt > new anchor_1.BN(0) &&
(args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualManualTerminating ||
args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualLiquidatedByClaim)
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualManualTerminating, duration: args.fraktBond.refinanceAuctionStartedAt.sub(args.bondTradeTransaction.soldAt), timestamp: args.fraktBond.refinanceAuctionStartedAt || new anchor_1.BN((0, exports.nowInSeconds)()) }),
]
: [];
const liquidatingAt = args.fraktBond.refinanceAuctionStartedAt &&
args.fraktBond.refinanceAuctionStartedAt.add(new anchor_1.BN(constants_1.TERMINATION_PERIOD));
const liquidationActivity = args.fraktBond.refinanceAuctionStartedAt &&
liquidatingAt < new anchor_1.BN((0, exports.nowInSeconds)()) &&
args.fraktBond.fraktBondState !== types_1.FraktBondState.PerpetualRepaid
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualLiquidatedByClaim, duration: liquidatingAt.sub(args.fraktBond.activatedAt), timestamp: liquidatingAt }),
]
: [];
// const interestRepaid = args.fraktBond.actualReturnedAmount - args.fraktBond.borrowedAmount;
const currentLoanValue = args.bondTradeTransaction.solAmount.add(args.bondTradeTransaction.feeAmount);
const interestRepaid = args.bondTradeTransaction.redeemedAt &&
(0, exports.calculateCurrentInterestSolPureBN)({
loanValue: currentLoanValue,
startTime: args.bondTradeTransaction.soldAt,
currentTime: args.bondTradeTransaction.redeemedAt,
rateBasePoints: args.bondTradeTransaction.amountOfBonds,
});
const repayActivity = args.fraktBond.fraktBondState == types_1.FraktBondState.PerpetualRepaid &&
args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualRepaid
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualRepaid, timestamp: args.fraktBond.repaidOrLiquidatedAt, interest: interestRepaid, repaid: currentLoanValue.add(interestRepaid), duration: args.fraktBond.repaidOrLiquidatedAt.sub(args.fraktBond.activatedAt) }),
]
: [];
const refinanceActivity = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualRefinancedActive
? [
Object.assign(Object.assign({}, initializeActivity), { timestamp: args.bondTradeTransaction.soldAt, status: types_1.BondTradeTransactionV2State.PerpetualRefinancedActive }),
]
: [];
const refinanceRepaidActivity = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualRefinanceRepaid
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualRefinanceRepaid, timestamp: args.bondTradeTransaction.redeemedAt, interest: interestRepaid, repaid: currentLoanValue.add(interestRepaid), duration: args.fraktBond.repaidOrLiquidatedAt.sub(args.fraktBond.activatedAt) }),
]
: [];
// const interestPartialRepaid = args.fraktBond.actualReturnedAmount - args.fraktBond.borrowedAmount;
const partialRepayActivity = args.bondTradeTransaction.bondTradeTransactionState == types_1.BondTradeTransactionV2State.PerpetualPartialRepaid
? [
Object.assign(Object.assign({}, initializeActivity), { status: types_1.BondTradeTransactionV2State.PerpetualPartialRepaid, timestamp: args.bondTradeTransaction.redeemedAt, interest: interestRepaid, repaid: currentLoanValue.add(interestRepaid), duration: args.fraktBond.repaidOrLiquidatedAt.sub(args.fraktBond.activatedAt) }),
]
: [];
return [
...initializeActivityToAdd,
...manualTerminationActivity,
...liquidationActivity,
...repayActivity,
...refinanceRepaidActivity,
...refinanceActivity,
...partialRepayActivity,
];
};
exports.getPerpetualBorrowerActivity = getPerpetualBorrowerActivity;
const getPerpetualOfferSize = (bondOffer) => {
return anchor_1.BN.min(bondOffer.fundsSolOrTokenBalance, bondOffer.currentSpotPrice);
};
exports.getPerpetualOfferSize = getPerpetualOfferSize;
const getPerpetualOfferSizeBonding = (bondOffer) => {
if (bondOffer.pairState === types_1.PairState.PerpetualOnMarket || bondOffer.pairState === types_1.PairState.PerpetualClosed)
return anchor_1.BN.min(bondOffer.fundsSolOrTokenBalance, bondOffer.currentSpotPrice);
const { baseSpotPrice, mathCounter, validation, currentSpotPrice, bidSettlement, bondingCurve } = bondOffer;
const prevSpotPrice = (0, amm_helpers_1.calculateNextSpotPriceBN)({
bondingCurveType: bondingCurve.bondingType,
delta: bondingCurve.delta,
spotPrice: baseSpotPrice,
counter: new anchor_1.BN(mathCounter).add(new anchor_1.BN(2)),
});
return anchor_1.BN.min(anchor_1.BN.min(validation.loanToValueFilter, currentSpotPrice.add(bidSettlement)), prevSpotPrice);
};
exports.getPerpetualOfferSizeBonding = getPerpetualOfferSizeBonding;
const checkIsHadomarketSponsored = (hadoMarket) => {
return constants_1.SPONSORED_HADOMARKETS_LIST.find((market) => market == hadoMarket);
};
exports.checkIsHadomarketSponsored = checkIsHadomarketSponsored;
const checkIsTestDev = (user) => {
return constants_1.TEST_DEVS.find((dev) => dev == user) ? true : false;
};
exports.checkIsTestDev = checkIsTestDev;
const calculateAccruedInterestOfRepaidBondTradeTransaction = (bondTradeTransaction, repayFee) => {
const accruedInterest = (0, exports.calculateCurrentInterestSolPureBN)({
loanValue: bondTradeTransaction.solAmount.add(bondTradeTransaction.feeAmount),
startTime: bondTradeTransaction.soldAt,
currentTime: bondTradeTransaction.redeemedAt || new anchor_1.BN((0, exports.nowInSeconds)()),
rateBasePoints: bondTradeTransaction.amountOfBonds.add(repayFee),
});
return accruedInterest;
};
exports.calculateAccruedInterestOfRepaidBondTradeTransaction = calculateAccruedInterestOfRepaidBondTradeTransaction;
const calculateDynamicApr = (loanToValue, turnDynamicAprOn) => {
const minApr = 3380;
const maxApr = 10400;
const minLtv = 5000;
const maxLtv = 9000;
if (turnDynamicAprOn === false)
return minApr;
// If loanToValue is less than or equal to minLtv, return minApr
if (loanToValue <= minLtv) {
return minApr;
}
// If loanToValue is greater than or equal to maxLtv, return maxApr
else if (loanToValue >= maxLtv) {
return maxApr;
}
// Calculate APR for values between minLtv and maxLtv
else {
const aprStep = (maxApr - minApr) / (maxLtv - minLtv); // Calculate the APR step value
return minApr + Math.round(((loanToValue - minLtv) * aprStep) / 100) * 100; // Calculate and round to nearest 100
}
};
exports.calculateDynamicApr = calculateDynamicApr;
const calculateLoanRepayValue = (bondTradeTransaction, repayFee) => {
const { solAmount, feeAmount, soldAt, amountOfBonds } = bondTradeTransaction || {};
const loanValueWithFee = solAmount.add(feeAmount);
const calculatedInterest = (0, exports.calculateCurrentInterestSolPureBN)({
loanValue: loanValueWithFee,
startTime: soldAt,
currentTime: bondTradeTransaction.redeemedAt || new anchor_1.BN((0, exports.nowInSeconds)()),
rateBasePoints: amountOfBonds.add(repayFee),
});
return loanValueWithFee.add(calculatedInterest);
};
exports.calculateLoanRepayValue = calculateLoanRepayValue;
const getRepaymentDestination = (pairState, shouldCompound) => {
if (pairState &&
(pairState == types_1.PairState.PerpetualOnMarket ||
pairState == types_1.PairState.PerpetualClosed ||
pairState == types_1.PairState.PerpetualMigrated ||
pairState == types_1.PairState.PerpetualBondingCurveClosed ||
shouldCompound == false)) {
return types_1.RepayDestination.Wallet;
}
else if (pairState == types_1.PairState.PerpetualBondingCurveOnMarket) {
return types_1.RepayDestination.Offer;
}
return types_1.RepayDestination.Wallet;
};
exports.getRepaymentDestination = getRepaymentDestination;
const calculatePartOfLoanBodyFromInterest = (args) => {
const loanTime = (0, exports.nowInSeconds)() - args.soldAt;
const partOfYear = loanTime / constants_1.SECONDS_IN_YEAR;
return Math.ceil(args.iterestToPay / ((partOfYear * args.rateBasePoints) / constants_1.BASE_POINTS + 1));
};
exports.calculatePartOfLoanBodyFromInterest = calculatePartOfLoanBodyFromInterest;
const calculateInputFeeWhenBorrow = (args) => {
if (args.inputFee === true) {
if (args.isRefinance && args.isBorrower) {
if (args.amountToGet > args.previousDebt) {
return args.amountToGet.sub(args.previousDebt).mul(new anchor_1.BN(args.inputFeeBp)).div(new anchor_1.BN(constants_1.BASE_POINTS));
}
else {
return new anchor_1.BN(0);
}
}
else {
return args.amountToGet.mul(new anchor_1.BN(args.inputFeeBp)).div(new anchor_1.BN(constants_1.BASE_POINTS));
}
}
else {
return new anchor_1.BN(0);
}
};
exports.calculateInputFeeWhenBorrow = calculateInputFeeWhenBorrow;
const getBondingCurveTypeFromLendingToken = (lendingToken) => {
switch (lendingToken) {
case types_1.LendingTokenType.NativeSol:
return types_1.BondingCurveType.LinearBanxSol;
case types_1.LendingTokenType.Usdc:
return types_1.BondingCurveType.LinearUsdc;
case types_1.LendingTokenType.BanxSol:
return types_1.BondingCurveType.LinearBanxSol;
}
};
exports.getBondingCurveTypeFromLendingToken = getBondingCurveTypeFromLendingToken;
const getFullLoanBodyFromBorrowerSendedAmount = (args) => {
return Math.floor(args.borrowerSendedAmount / (1 - args.upfrontFeeBasePoints / constants_1.BASE_POINTS));
};
exports.getFullLoanBodyFromBorrowerSendedAmount = getFullLoanBodyFromBorrowerSendedAmount;
const getTokenMintFromLendingTokenType = (lendingToken) => {
switch (lendingToken) {
case types_1.LendingTokenType.NativeSol:
return constants_1.BANX_SOL_MINT;
case types_1.LendingTokenType.Usdc:
return constants_1.USDC_MINT;
case types_1.LendingTokenType.BanxSol:
return constants_1.BANX_SOL_MINT;
}
};
exports.getTokenMintFromLendingTokenType = getTokenMintFromLendingTokenType;
const calculateCollateralPerTokens = (amountToGet, collateralPerToken, tokenDecimals) => {
return Math.floor((amountToGet * collateralPerToken) / tokenDecimals);
};
exports.calculateCollateralPerTokens = calculateCollateralPerTokens;
const calculateBanxSolStakingRewards = (args) => {
let reward = new anchor_1.BN(args.userVault.rewardsToHarvest);
const lastCalculatedEpcoh = args.userVault.lastCalculatedSlot.div(new anchor_1.BN(constants_1.DEFAULT_SLOTS_PER_EPOCH));
const nowEpoch = args.nowSlot.div(new anchor_1.BN(constants_1.DEFAULT_SLOTS_PER_EPOCH));
if (nowEpoch > lastCalculatedEpcoh &&
!args.userVault.lastCalculatedSlot.isZero() &&
!args.userVault.lastCalculatedTimestamp.isZero()) {
const slotDif = args.nowSlot.sub(new anchor_1.BN(args.userVault.lastCalculatedSlot));
const unixTimeDif = new anchor_1.BN(new anchor_1.BN((0, exports.nowInSeconds)())).sub(new anchor_1.BN(args.userVault.lastCalculatedTimestamp));
const avgSlotPerMs = unixTimeDif.mul(new anchor_1.BN(1000)).div(slotDif);
reward = reward.add(new anchor_1.BN((0, exports.calculateCurrentInterestSolPureBN)({
loanValue: args.userVault.fundsInCurrentEpoch,
currentTime: args.currentEpochStartAt,
rateBasePoints: new anchor_1.BN(constants_1.BANX_SOL_STAKING_YEILD_APR),
startTime: args.userVault.lastCalculatedTimestamp,
})));
if (lastCalculatedEpcoh.add(new anchor_1.BN(1)) < nowEpoch) {
const lastCalculatedEpochEndsAt = new anchor_1.BN(args.userVault.lastCalculatedTimestamp).add(new anchor_1.BN(constants_1.DEFAULT_SLOTS_PER_EPOCH)
.sub(new anchor_1.BN(args.userVault.lastCalculatedSlot).mod(new anchor_1.BN(constants_1.DEFAULT_SLOTS_PER_EPOCH)))
.mul(avgSlotPerMs)
.div(new anchor_1.BN(1000)));
reward = reward.add(new anchor_1.BN((0, exports.calculateCurrentInterestSolPureBN)({
loanValue: args.userVault.fundsInNextEpoch,
currentTime: args.currentEpochStartAt,
rateBasePoints: new anchor_1.BN(constants_1.BANX_SOL_STAKING_YEILD_APR),
startTime: lastCalculatedEpochEndsAt,
})));
}
}
return reward;
};
exports.calculateBanxSolStakingRewards = calculateBanxSolStakingRewards;