22
33pragma solidity 0.8.18 ;
44
5+ import { Multicall } from '@openzeppelin/contracts/utils/Multicall.sol ' ;
6+ import { IERC20 } from '@openzeppelin/contracts/token/ERC20/IERC20.sol ' ;
7+ import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol " ;
8+
59import { PoolInfoUtils } from "./PoolInfoUtils.sol " ;
610
11+ import { IPool } from "./interfaces/pool/IPool.sol " ;
12+ import { IERC20Pool } from "./interfaces/pool/erc20/IERC20Pool.sol " ;
13+
714contract PoolInfoUtilsMulticall {
815
916 PoolInfoUtils public immutable poolInfoUtils;
1017
18+ struct PoolLoansInfo {
19+ uint256 poolSize;
20+ uint256 loansCount;
21+ address maxBorrower;
22+ uint256 pendingInflator;
23+ uint256 pendingInterestFactor;
24+ }
25+
1126 struct PoolPriceInfo {
1227 uint256 hpb;
1328 uint256 hpbIndex;
@@ -17,6 +32,12 @@ contract PoolInfoUtilsMulticall {
1732 uint256 lupIndex;
1833 }
1934
35+ struct PoolRatesAndFees {
36+ uint256 lenderInterestMargin;
37+ uint256 borrowFeeRate;
38+ uint256 depositFeeRate;
39+ }
40+
2041 struct PoolReservesInfo {
2142 uint256 reserves;
2243 uint256 claimableReserves;
@@ -32,38 +53,47 @@ contract PoolInfoUtilsMulticall {
3253 uint256 poolTargetUtilization;
3354 }
3455
35- struct BucketInfo {
36- uint256 price;
37- uint256 quoteTokens;
38- uint256 collateral;
39- uint256 bucketLP;
40- uint256 scale;
41- uint256 exchangeRate;
56+ struct PoolBalanceDetails {
57+ uint256 debt; // debtInfo()
58+ uint256 accruedDebt; // debtInfo()
59+ uint256 debtInAuction; // debtInfo()
60+ uint256 t0Debt2ToCollateral; // debtInfo()
61+ uint256 depositUpToIndex;
62+ uint256 quoteTokenBalance;
63+ uint256 collateralTokenBalance;
4264 }
4365
4466 constructor (PoolInfoUtils poolInfoUtils_ ) {
4567 poolInfoUtils = poolInfoUtils_;
4668 }
4769
4870 /**
49- * @notice Retrieves PoolPriceInfo, PoolReservesInfo, PoolUtilizationInfo and BucketInfo
71+ * @notice Retrieves PoolLoansInfo, PoolPriceInfo, PoolRatesAndFees, PoolReservesInfo and PoolUtilizationInfo
72+ * @dev This function is used to retrieve pool details available from PoolInfoUtils in a single RPC call for Indexers.
5073 * @param ajnaPool_ Address of `Ajna` pool
51- * @param bucketIndex_ The index of the bucket to retrieve
74+ * @return poolLoansInfo_ Pool loans info struct
5275 * @return poolPriceInfo_ Pool price info struct
76+ * @return poolRatesAndFees_ Pool rates and fees struct
5377 * @return poolReservesInfo_ Pool reserves info struct
5478 * @return poolUtilizationInfo_ Pool utilization info struct
55- * @return bucketInfo_ Bucket info struct
5679 */
57- function poolDetailsAndBucketInfo (address ajnaPool_ , uint256 bucketIndex_ )
58- external
59- view
60- returns (
61- PoolPriceInfo memory poolPriceInfo_ ,
62- PoolReservesInfo memory poolReservesInfo_ ,
63- PoolUtilizationInfo memory poolUtilizationInfo_ ,
64- BucketInfo memory bucketInfo_
65- )
66- {
80+ function poolDetailsMulticall (address ajnaPool_ ) external view returns (
81+ PoolLoansInfo memory poolLoansInfo_ ,
82+ PoolPriceInfo memory poolPriceInfo_ ,
83+ PoolRatesAndFees memory poolRatesAndFees_ ,
84+ PoolReservesInfo memory poolReservesInfo_ ,
85+ PoolUtilizationInfo memory poolUtilizationInfo_
86+ ) {
87+ // retrieve loans info
88+ (
89+ poolLoansInfo_.poolSize,
90+ poolLoansInfo_.loansCount,
91+ poolLoansInfo_.maxBorrower,
92+ poolLoansInfo_.pendingInflator,
93+ poolLoansInfo_.pendingInterestFactor
94+ ) = poolInfoUtils.poolLoansInfo (ajnaPool_);
95+
96+ // retrieve prices info
6797 (
6898 poolPriceInfo_.hpb,
6999 poolPriceInfo_.hpbIndex,
@@ -73,6 +103,12 @@ contract PoolInfoUtilsMulticall {
73103 poolPriceInfo_.lupIndex
74104 ) = poolInfoUtils.poolPricesInfo (ajnaPool_);
75105
106+ // retrieve rates and fees
107+ poolRatesAndFees_.lenderInterestMargin = poolInfoUtils.lenderInterestMargin (ajnaPool_);
108+ poolRatesAndFees_.borrowFeeRate = poolInfoUtils.borrowFeeRate (ajnaPool_);
109+ poolRatesAndFees_.depositFeeRate = poolInfoUtils.unutilizedDepositFeeRate (ajnaPool_);
110+
111+ // retrieve reserves info
76112 (
77113 poolReservesInfo_.reserves,
78114 poolReservesInfo_.claimableReserves,
@@ -81,21 +117,13 @@ contract PoolInfoUtilsMulticall {
81117 poolReservesInfo_.timeRemaining
82118 ) = poolInfoUtils.poolReservesInfo (ajnaPool_);
83119
120+ // retrieve utilization info
84121 (
85122 poolUtilizationInfo_.poolMinDebtAmount,
86123 poolUtilizationInfo_.poolCollateralization,
87124 poolUtilizationInfo_.poolActualUtilization,
88125 poolUtilizationInfo_.poolTargetUtilization
89126 ) = poolInfoUtils.poolUtilizationInfo (ajnaPool_);
90-
91- (
92- bucketInfo_.price,
93- bucketInfo_.quoteTokens,
94- bucketInfo_.collateral,
95- bucketInfo_.bucketLP,
96- bucketInfo_.scale,
97- bucketInfo_.exchangeRate
98- ) = poolInfoUtils.bucketInfo (ajnaPool_, bucketIndex_);
99127 }
100128
101129 /**
@@ -105,21 +133,60 @@ contract PoolInfoUtilsMulticall {
105133 * @return borrowFeeRate Borrow fee rate calculated from the pool interest ra
106134 * @return depositFeeRate Deposit fee rate calculated from the pool interest rate
107135 */
108- function poolRatesAndFees (address ajnaPool_ )
136+ function poolRatesAndFeesMulticall (address ajnaPool_ )
109137 external
110- view
111- returns
138+ returns
112139 (
113140 uint256 lenderInterestMargin ,
114141 uint256 borrowFeeRate ,
115142 uint256 depositFeeRate
116- )
143+ )
117144 {
118145 lenderInterestMargin = poolInfoUtils.lenderInterestMargin (ajnaPool_);
119146 borrowFeeRate = poolInfoUtils.borrowFeeRate (ajnaPool_);
120147 depositFeeRate = poolInfoUtils.unutilizedDepositFeeRate (ajnaPool_);
121148 }
122149
150+ /**
151+ * @notice Retrieves pool debtInfo, depositUpToIndex, quoteTokenBalance and collateralTokenBalance
152+ * @dev This function is used to retrieve pool balance details in a single RPC call for Indexers.
153+ * @param ajnaPool_ Address of `Ajna` pool
154+ * @param index_ Index of deposit
155+ * @param quoteTokenAddress_ Address of quote token
156+ * @param collateralTokenAddress_ Address of collateral token
157+ * @param isNFT_ Boolean indicating if the pool is an NFT pool
158+ * @return poolBalanceDetails_ Pool balance details struct
159+ */
160+ function poolBalanceDetails (address ajnaPool_ , uint256 index_ , address quoteTokenAddress_ , address collateralTokenAddress_ , bool isNFT_ )
161+ external view
162+ returns (PoolBalanceDetails memory poolBalanceDetails_ )
163+ {
164+ IPool pool = IPool (ajnaPool_);
165+
166+ // pool debtInfo
167+ (poolBalanceDetails_.debt, poolBalanceDetails_.accruedDebt, poolBalanceDetails_.debtInAuction, poolBalanceDetails_.t0Debt2ToCollateral) = pool.debtInfo ();
168+
169+ // depositUpToIndex(index_)
170+ poolBalanceDetails_.depositUpToIndex = pool.depositUpToIndex (index_);
171+
172+ // get pool quote token balance
173+ uint256 poolQuoteBalance = IERC20 (quoteTokenAddress_).balanceOf (ajnaPool_);
174+ uint256 quoteScale = pool.quoteTokenScale ();
175+ // normalize token balance to WAD scale
176+ poolBalanceDetails_.quoteTokenBalance = poolQuoteBalance * quoteScale;
177+
178+ // get pool collateral token balance
179+ if (isNFT_) {
180+ // convert whole NFT amounts to WAD to match pool accounting
181+ poolBalanceDetails_.collateralTokenBalance = IERC721 (collateralTokenAddress_).balanceOf (ajnaPool_) * 10 ** 18 ;
182+ } else {
183+ // normalize token balance to WAD scale
184+ uint256 collateralScale = IERC20Pool (ajnaPool_).collateralScale ();
185+ uint256 poolCollateralBalance = IERC20 (collateralTokenAddress_).balanceOf (ajnaPool_);
186+ poolBalanceDetails_.collateralTokenBalance = poolCollateralBalance * collateralScale;
187+ }
188+ }
189+
123190 /**
124191 * @notice Aggregate results from multiple read-only function calls
125192 * @param functionSignatures_ Array of signatures of read-only functions to be called
0 commit comments