From 4cd7bf9cecbe2b7cff25d53ab9a2aebef3915040 Mon Sep 17 00:00:00 2001 From: gidonkatten Date: Thu, 2 Jan 2025 15:49:50 +0000 Subject: [PATCH] option to include xalgo staking apr in net rate and yield calculations --- .changeset/dirty-waves-sell.md | 5 +++++ src/lend/loan.ts | 11 +++++++++-- src/lend/utils.ts | 21 ++++++++++++++++++++- src/math-lib.ts | 2 ++ 4 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 .changeset/dirty-waves-sell.md diff --git a/.changeset/dirty-waves-sell.md b/.changeset/dirty-waves-sell.md new file mode 100644 index 00000000..e1619f56 --- /dev/null +++ b/.changeset/dirty-waves-sell.md @@ -0,0 +1,5 @@ +--- +"@folks-finance/algorand-sdk": patch +--- + +option to include xalgo staking apr in net rate and yield calculations diff --git a/src/lend/loan.ts b/src/lend/loan.ts index 079d0b01..8e72b3b4 100644 --- a/src/lend/loan.ts +++ b/src/lend/loan.ts @@ -146,6 +146,7 @@ async function retrieveLoanLocalState( * @param poolManagerAppId - pool manager application to query about * @param oracle - oracle to query * @param userAddr - account address for the user + * @param xAlgoStakingRateBps - optional xALGO staking rate (in bps) to include in loan net rate/yield * @returns Promise user loans infos */ async function retrieveUserLoansInfo( @@ -154,6 +155,7 @@ async function retrieveUserLoansInfo( poolManagerAppId: number, oracle: Oracle, userAddr: string, + xAlgoStakingRateBps?: bigint, ): Promise { const userLoanInfos: UserLoanInfo[] = []; @@ -178,7 +180,10 @@ async function retrieveUserLoansInfo( ); if (state === undefined) throw Error(`Could not find loan ${loanAppId} in escrow ${escrowAddr}`); const localState = loanLocalState(state, loanAppId, escrowAddr); - userLoanInfos.push({ ...userLoanInfo(localState, poolManagerInfo, loanInfo, oraclePrices), currentRound }); + userLoanInfos.push({ + ...userLoanInfo(localState, poolManagerInfo, loanInfo, oraclePrices, xAlgoStakingRateBps), + currentRound, + }); } return userLoanInfos; @@ -193,6 +198,7 @@ async function retrieveUserLoansInfo( * @param poolManagerAppId - pool manager application to query about * @param oracle - oracle to query * @param escrowAddr - account address for the loan escrow + * @param xAlgoStakingRateBps - optional xALGO staking rate (in bps) to include in loan net rate/yield * @returns Promise user loan info */ async function retrieveUserLoanInfo( @@ -201,6 +207,7 @@ async function retrieveUserLoanInfo( poolManagerAppId: number, oracle: Oracle, escrowAddr: string, + xAlgoStakingRateBps?: bigint, ): Promise { // get all prerequisites const loanInfoReq = retrieveLoanInfo(client, loanAppId); @@ -212,7 +219,7 @@ async function retrieveUserLoanInfo( const { currentRound, localState: state } = await getAccountApplicationLocalState(client, loanAppId, escrowAddr); if (state === undefined) throw Error(`Could not find loan ${loanAppId} in escrow ${escrowAddr}`); const localState = loanLocalState(state, loanAppId, escrowAddr); - return { ...userLoanInfo(localState, poolInfo, loanInfo, oraclePrices), currentRound }; + return { ...userLoanInfo(localState, poolInfo, loanInfo, oraclePrices, xAlgoStakingRateBps), currentRound }; } /** diff --git a/src/lend/utils.ts b/src/lend/utils.ts index ab904937..411a8bb1 100644 --- a/src/lend/utils.ts +++ b/src/lend/utils.ts @@ -1,6 +1,15 @@ import { encodeAddress, getApplicationAddress } from "algosdk"; -import { compoundEverySecond, maximum, mulScale, ONE_10_DP, ONE_16_DP, ONE_4_DP, SECONDS_IN_YEAR } from "../math-lib"; +import { + compoundEverySecond, + maximum, + mulScale, + ONE_10_DP, + ONE_12_DP, + ONE_16_DP, + ONE_4_DP, + SECONDS_IN_YEAR +} from "../math-lib"; import { enc, fromIntToByteHex, getParsedValueFromState, parseUint64s, unixTime } from "../utils"; import { @@ -31,6 +40,7 @@ import type { } from "./types"; import type { Indexer } from "algosdk"; import type { TealKeyValue } from "algosdk/dist/types/client/v2/algod/models/types"; +import {MainnetPools} from "./constants/mainnet-constants"; export async function getEscrows( indexerClient: Indexer, @@ -359,6 +369,7 @@ export function loanLocalState(state: TealKeyValue[], loanAppId: number, escrowA * @param poolManagerInfo - pool manager info which is returned by retrievePoolManagerInfo function * @param loanInfo - loan info which is returned by retrieveLoanInfo function * @param oraclePrices - oracle prices which is returned by getOraclePrices function + * @param xAlgoStakingRateBps - optional xALGO staking rate (in bps) to include in loan net rate/yield * @returns Promise user loans info */ export function userLoanInfo( @@ -366,6 +377,7 @@ export function userLoanInfo( poolManagerInfo: PoolManagerInfo, loanInfo: LoanInfo, oraclePrices: OraclePrices, + xAlgoStakingRateBps?: bigint, ): UserLoanInfo { const { pools: poolManagerPools } = poolManagerInfo; const { pools: loanPools } = loanInfo; @@ -403,6 +415,13 @@ export function userLoanInfo( netRate += balanceValue * depositInterestRate; netYield += balanceValue * depositInterestYield; + // add xALGO staking apr if requested (must be mainnet) + if (assetId === MainnetPools.xALGO.assetId && xAlgoStakingRateBps) { + // multiply by 1e12 to standardise at 16 d.p. + netRate += balanceValue * xAlgoStakingRateBps * ONE_12_DP; + netYield += balanceValue * xAlgoStakingRateBps * ONE_12_DP; + } + collaterals.push({ poolAppId, assetId, diff --git a/src/math-lib.ts b/src/math-lib.ts index 715ff789..dabf02ae 100644 --- a/src/math-lib.ts +++ b/src/math-lib.ts @@ -4,6 +4,7 @@ const HOURS_IN_YEAR = BigInt(365 * 24); const ONE_2_DP = BigInt(1e2); const ONE_4_DP = BigInt(1e4); const ONE_10_DP = BigInt(1e10); +const ONE_12_DP = BigInt(1e12); const ONE_14_DP = BigInt(1e14); const ONE_16_DP = BigInt(1e16); @@ -81,6 +82,7 @@ export { HOURS_IN_YEAR, ONE_16_DP, ONE_14_DP, + ONE_12_DP, ONE_10_DP, ONE_4_DP, ONE_2_DP,