ghoUtilities.tsx
1 import { GhoReserveData, GhoUserData, normalize } from '@aave/math-utils'; 2 import { ComputedReserveData } from 'src/hooks/app-data-provider/useAppDataProvider'; 3 4 export const GHO_SYMBOL = 'GHO'; 5 6 /** 7 * List of markets where new GHO minting is available. 8 * Note that his is different from markets where GHO is listed as a reserve. 9 */ 10 export const GHO_MINTING_MARKETS = [ 11 'proto_mainnet_v3', 12 'fork_proto_mainnet_v3', 13 'proto_sepolia_v3', 14 'fork_proto_sepolia_v3', 15 ]; 16 17 export const getGhoReserve = (reserves: ComputedReserveData[]) => { 18 return reserves.find((reserve) => reserve.symbol === GHO_SYMBOL); 19 }; 20 21 /** 22 * Calculates the weighted average APY 23 * @param baseVariableBorrowRate - The base variable borrow rate, normalized 24 * @param totalBorrowAmount - The total amount of the asset that is being borrowed 25 * @param discountableAmount - The amount that can be discounted for the user 26 * @param borrowRateAfterDiscount - The borrow rate after the discount is applied 27 * @returns 28 */ 29 export const weightedAverageAPY = ( 30 baseVariableBorrowRate: number, 31 totalBorrowAmount: number, 32 discountableAmount: number, 33 borrowRateAfterDiscount: number 34 ) => { 35 if (discountableAmount === 0) return baseVariableBorrowRate; 36 if (totalBorrowAmount <= discountableAmount) return borrowRateAfterDiscount; 37 38 const nonDiscountableAmount = totalBorrowAmount - discountableAmount; 39 40 return ( 41 (nonDiscountableAmount * baseVariableBorrowRate + 42 discountableAmount * borrowRateAfterDiscount) / 43 totalBorrowAmount 44 ); 45 }; 46 47 /** 48 * This helps display the discountable amount of GHO based off of how much is being borrowed and how much is discountable. 49 * This is used in both the borrow modal and the discount rate calculator. 50 * @param discountableGhoAmount - The amount of GHO that is discountable 51 * @param amountGhoBeingBorrowed - The amount of GHO requesting to be borrowed 52 * @returns The amount of discountable GHO as a number in a display-friendly form 53 */ 54 export const displayDiscountableAmount = ( 55 discountableGhoAmount: number, 56 amountGhoBeingBorrowed: number 57 ): number => { 58 return discountableGhoAmount >= amountGhoBeingBorrowed 59 ? amountGhoBeingBorrowed 60 : discountableGhoAmount; 61 }; 62 63 /** 64 * This helps display the non-discountable amount of GHO based off of how much is being borrowed and how much is discountable. 65 * This is used in both the borrow modal and the discount rate calculator. 66 * @param discountableGhoAmount - The amount of GHO that is discountable 67 * @param amountGhoBeingBorrowed - The amount of GHO requesting to be borrowed 68 * @returns The amount of non-discountable GHO as a number in a display-friendly form 69 */ 70 export const displayNonDiscountableAmount = ( 71 discountableGhoAmount: number, 72 amountGhoBeingBorrowed: number 73 ): number => { 74 return discountableGhoAmount >= amountGhoBeingBorrowed 75 ? 0 76 : amountGhoBeingBorrowed - discountableGhoAmount; 77 }; 78 79 interface ReserveWithSymbol { 80 symbol: string; 81 } 82 83 type FindAndFilterReturn<T> = { 84 value: T | undefined; 85 filtered: Array<T>; 86 }; 87 88 export const findAndFilterMintableGhoReserve = <T extends ReserveWithSymbol>( 89 reserves: Array<T>, 90 currentMarket: string 91 ) => { 92 if (!GHO_MINTING_MARKETS.includes(currentMarket)) return { value: undefined, filtered: reserves }; 93 94 return reserves.reduce<FindAndFilterReturn<T>>( 95 (acum, reserve) => { 96 if (reserve.symbol === GHO_SYMBOL) return { value: reserve, filtered: acum.filtered }; 97 else return { ...acum, filtered: acum.filtered.concat(reserve) }; 98 }, 99 { 100 value: undefined, 101 filtered: [], 102 } 103 ); 104 }; 105 106 /** 107 * Determines if the given symbol is GHO and the market supports minting new GHO 108 */ 109 export const displayGhoForMintableMarket = ({ 110 symbol, 111 currentMarket, 112 }: GhoUtilMintingAvailableParams): boolean => { 113 return symbol === GHO_SYMBOL && GHO_MINTING_MARKETS.includes(currentMarket); 114 }; 115 116 interface GhoUtilMintingAvailableParams { 117 symbol: string; 118 currentMarket: string; 119 } 120 121 export const ghoUserQualifiesForDiscount = ( 122 ghoReserveData: GhoReserveData, 123 ghoUserData: GhoUserData, 124 futureBorrowAmount = '0' 125 ) => { 126 const borrowBalance = Number(normalize(ghoUserData.userGhoScaledBorrowBalance, 18)); 127 const minBorrowBalanceForDiscount = Number( 128 normalize(ghoReserveData.ghoMinDebtTokenBalanceForDiscount, 18) 129 ); 130 131 const stkAaveBalance = Number(normalize(ghoUserData.userDiscountTokenBalance, 18)); 132 const minStkAaveBalanceForDiscount = Number( 133 normalize(ghoReserveData.ghoMinDiscountTokenBalanceForDiscount, 18) 134 ); 135 136 return ( 137 borrowBalance + Number(futureBorrowAmount) >= minBorrowBalanceForDiscount && 138 stkAaveBalance >= minStkAaveBalanceForDiscount 139 ); 140 };