UNPKG

fbonds-core

Version:

Banx protocol sdk

609 lines (608 loc) • 39 kB
"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;