UNPKG

fbonds-core

Version:

Banx protocol sdk

173 lines (172 loc) • 8.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.calcOptimisticBasedOnBulkSimulation = exports.optimisticUpdateBondOfferBonding = exports.calculateLenderPartialPartFromBorrowerBN = exports.calculateLenderPartialPartFromBorrower = exports.getLendingTokenType = exports.optimisticInitializeBondOfferBonding = exports.calculateNextSpotPriceBN = exports.calculateNextSpotPrice = void 0; const constants_1 = require("../../../constants"); const types_1 = require("../../../types"); const helpers_1 = require("./helpers"); const anchor_1 = require("@coral-xyz/anchor"); const lodash_1 = require("lodash"); const calculateNextSpotPrice = ({ spotPrice, delta, bondingCurveType, counter, }) => { if (bondingCurveType === types_1.BondingCurveType.Linear || bondingCurveType === types_1.BondingCurveType.LinearUsdc || bondingCurveType === types_1.BondingCurveType.LinearBanxSol) { let current_price = spotPrice; // 1 const targetCounter = counter + -1; if (targetCounter >= 0) { // 0 for (let i = 0; i < Math.abs(targetCounter); i++) { current_price += delta; } } else { for (let i = 0; i < Math.abs(targetCounter); i++) { current_price -= delta; } } return current_price; } else if (bondingCurveType === types_1.BondingCurveType.Exponential) { const newCounter = counter - 1; let newDelta = newCounter > 0 ? (delta + 1e4) / 1e4 : 1 / ((delta + 1e4) / 1e4); return spotPrice * Math.pow(newDelta, Math.abs(newCounter)); } else { return 0; } }; exports.calculateNextSpotPrice = calculateNextSpotPrice; const calculateNextSpotPriceBN = ({ spotPrice, delta, bondingCurveType, counter, }) => { if (bondingCurveType === types_1.BondingCurveType.Linear || bondingCurveType === types_1.BondingCurveType.LinearUsdc || bondingCurveType === types_1.BondingCurveType.LinearBanxSol) { let current_price = spotPrice; // 1 const targetCounter = counter.sub(new anchor_1.BN(1)); if (targetCounter >= new anchor_1.BN(0)) { // 0 for (let i = 0; new anchor_1.BN(i) < targetCounter.abs(); i++) { current_price = current_price.add(delta); } } else { for (let i = 0; new anchor_1.BN(i) < targetCounter.abs(); i++) { current_price = current_price.sub(delta); } } return current_price; } else if (bondingCurveType === types_1.BondingCurveType.Exponential) { const newCounter = counter.sub(new anchor_1.BN(1)); let newDelta = newCounter > new anchor_1.BN(0) ? (delta.add(new anchor_1.BN(1e4))).div(new anchor_1.BN(1e4)) : new anchor_1.BN(1).div((delta.add(new anchor_1.BN(1e4))).div(new anchor_1.BN(1e4))); return spotPrice.mul(newDelta.pow(newCounter.abs())); } else { return new anchor_1.BN(0); } }; exports.calculateNextSpotPriceBN = calculateNextSpotPriceBN; const optimisticInitializeBondOfferBonding = (args) => ({ hadoMarket: args.hadoMarket, pairState: types_1.PairState.PerpetualBondingCurveOnMarket, bondingCurve: { delta: new anchor_1.BN(0), bondingType: args.bondingType }, baseSpotPrice: new anchor_1.BN(0), mathCounter: new anchor_1.BN(0), currentSpotPrice: new anchor_1.BN(0), 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(0), lastTransactedAt: new anchor_1.BN((0, helpers_1.nowInSeconds)()), assetReceiver: args.assetReceiver, validation: { loanToValueFilter: new anchor_1.BN(0), collateralsPerToken: new anchor_1.BN(0), maxReturnAmountFilter: new anchor_1.BN(0), bondFeatures: args.isSplFeature ? types_1.BondFeatures.AutoReceiveAndReceiveSpl : 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.optimisticInitializeBondOfferBonding = optimisticInitializeBondOfferBonding; const getLendingTokenType = (bondingCurveType) => { let lendingTokenType = types_1.LendingTokenType.NativeSol; switch (bondingCurveType) { case types_1.BondingCurveType.Linear || types_1.BondingCurveType.Exponential: { lendingTokenType = types_1.LendingTokenType.BanxSol; break; } case types_1.BondingCurveType.LinearUsdc || types_1.BondingCurveType.ExponentialUsdc: { lendingTokenType = types_1.LendingTokenType.Usdc; break; } case types_1.BondingCurveType.LinearBanxSol || types_1.BondingCurveType.ExponentialBanxSol: { lendingTokenType = types_1.LendingTokenType.BanxSol; break; } } ; return lendingTokenType; }; exports.getLendingTokenType = getLendingTokenType; const calculateLenderPartialPartFromBorrower = (args) => { const loanTime = (0, helpers_1.nowInSeconds)() - args.soldAt; const partOfYear = loanTime / constants_1.SECONDS_IN_YEAR; const partOfLoan = args.borrowerPart / (1 + (args.lenderApr + args.protocolRepayFeeApr) * partOfYear / constants_1.BASE_POINTS); const pureInterest = (0, helpers_1.calculateCurrentInterestSolPure)({ loanValue: partOfLoan, startTime: args.soldAt, currentTime: (0, helpers_1.nowInSeconds)(), rateBasePoints: args.lenderApr, }); return partOfLoan + pureInterest; }; exports.calculateLenderPartialPartFromBorrower = calculateLenderPartialPartFromBorrower; const calculateLenderPartialPartFromBorrowerBN = (args) => { const loanTime = new anchor_1.BN((0, helpers_1.nowInSeconds)()).sub(args.soldAt); const partOfYear = loanTime.div(new anchor_1.BN(constants_1.SECONDS_IN_YEAR)); const partOfLoan = args.borrowerPart.div(new anchor_1.BN(1).add((args.lenderApr.add(args.protocolRepayFeeApr)).mul(partOfYear).div(new anchor_1.BN(constants_1.BASE_POINTS)))); const pureInterest = (0, helpers_1.calculateCurrentInterestSolPureBN)({ loanValue: partOfLoan, startTime: args.soldAt, currentTime: new anchor_1.BN((0, helpers_1.nowInSeconds)()), rateBasePoints: args.lenderApr, }); return partOfLoan.add(pureInterest); }; exports.calculateLenderPartialPartFromBorrowerBN = calculateLenderPartialPartFromBorrowerBN; const optimisticUpdateBondOfferBonding = ({ bondOffer, newLoanValue, newQuantityOfLoans, collateralsPerToken, tokenLendingApr, }) => { const newBaseSpotPrice = newLoanValue; const newBuyOrdersSize = newLoanValue.mul(newQuantityOfLoans); return Object.assign(Object.assign({}, bondOffer), { fundsSolOrTokenBalance: newBuyOrdersSize, baseSpotPrice: newBaseSpotPrice, bondingCurve: { delta: constants_1.ZERO_BN, bondingType: bondOffer.bondingCurve.bondingType }, currentSpotPrice: newLoanValue, buyOrdersQuantity: newQuantityOfLoans, bidSettlement: constants_1.ZERO_BN, bidCap: constants_1.ZERO_BN, validation: Object.assign(Object.assign({}, bondOffer.validation), { collateralsPerToken: collateralsPerToken, loanToValueFilter: newLoanValue }), loanApr: tokenLendingApr, lastTransactedAt: new anchor_1.BN((0, helpers_1.nowInSeconds)()) }); }; exports.optimisticUpdateBondOfferBonding = optimisticUpdateBondOfferBonding; const calcObjectsDiff = (objectA, objectB, ignoreFields, diffMethod = 'sub') => { return (0, lodash_1.chain)(objectA) .toPairs() .map(([fieldName, fieldValue]) => { if (ignoreFields.includes(fieldName)) { return [fieldName, objectB[fieldName]]; } if (anchor_1.BN.isBN(fieldValue)) { if (diffMethod === 'add') { return [fieldName, fieldValue.add(objectB[fieldName])]; } return [fieldName, fieldValue.sub(objectB[fieldName])]; } if ((0, lodash_1.isObject)(fieldValue)) { // eslint-disable-next-line @typescript-eslint/no-explicit-any return calcObjectsDiff(fieldValue, objectB[fieldName], ignoreFields, diffMethod); } return [fieldName, objectB[fieldName]]; }) .fromPairs() .value(); }; const calcOptimisticBasedOnBulkSimulation = (account, simulatedAccounts, ignoreFields = []) => { const diffs = simulatedAccounts.map((simulatedAccount) => calcObjectsDiff(account, simulatedAccount, ignoreFields, 'sub')); return (0, lodash_1.chain)(diffs) .reduce((acc, diff) => { return calcObjectsDiff(acc, diff, ignoreFields, 'sub'); }, account) .value(); }; exports.calcOptimisticBasedOnBulkSimulation = calcOptimisticBasedOnBulkSimulation;