@@ -22,12 +22,13 @@ contract LendingPool is NilBase, NilTokenBase {
2222 error InvalidCaller ();
2323 error InvalidShardId ();
2424 error ExcessTransfer ();
25- error InsufficientFunds (string message );
2625 error InvalidPoolAddress ();
2726 error PoolAlreadyRegistered ();
2827 error InvalidTransferAmount ();
2928 error InsufficientCollateral ();
29+ error NoLendingPoolsRegistered ();
3030 error FailedToRetrieveCollateral ();
31+ error InsufficientFunds (string message );
3132 error CrossShardCallFailed (string message );
3233
3334 /// @dev Mapping to track lending pools on different shards
@@ -65,12 +66,16 @@ contract LendingPool is NilBase, NilTokenBase {
6566 eth = _eth;
6667
6768 deployer = msg .sender ;
69+
70+ /// @notice Register the current contract as a lending pool
71+ /// @dev This ensures that the current contract is recognized as a valid lending pool
72+ registerLendingPool (address (this ));
6873 }
6974
7075 /// @notice Register a new lending pool on a different shard
7176 /// @dev Allows registration of other lending pools for cross-shard borrowing
7277 /// @param poolAddress The address of the lending pool to register
73- function registerLendingPool (address poolAddress ) external onlyDeployer {
78+ function registerLendingPool (address poolAddress ) public onlyDeployer {
7479 if (poolAddress == address (0 )) revert InvalidPoolAddress ();
7580
7681 uint256 shardId = Nil.getShardId (poolAddress);
@@ -82,101 +87,6 @@ contract LendingPool is NilBase, NilTokenBase {
8287 lendingPoolCount++ ;
8388 }
8489
85- /// @notice Check liquidity across all registered lending pools
86- /// @dev Queries each registered lending pool for available liquidity
87- /// @param token The token to check liquidity for
88- /// @param amount The amount needed
89- /// @param requestId Unique identifier for this borrow request
90- function checkCrossShardLiquidity (
91- TokenId token ,
92- uint256 amount ,
93- bytes32 requestId ,
94- address borrower
95- ) internal {
96- uint256 currentShardId = Nil.getShardId (address (this ));
97-
98- if (lendingPoolCount > 0 ) {
99- for (uint256 i = 0 ; i < lendingPools.length ; i++ ) {
100- address poolAddress = lendingPools[i];
101- uint256 poolShardId = Nil.getShardId (poolAddress);
102-
103- // Skip if the pool is on the same shard
104- if (poolShardId == currentShardId) {
105- continue ;
106- }
107-
108- // Query the other pool's token balance
109- bytes memory callData = abi.encodeWithSignature (
110- "getTokenBalance(address) " ,
111- token
112- );
113-
114- bytes memory context = abi.encodeWithSelector (
115- this .handleLiquidityCheck.selector ,
116- token,
117- amount,
118- poolAddress,
119- poolShardId,
120- requestId,
121- borrower
122- );
123-
124- Nil.sendRequest (poolAddress, 0 , 6_000_000 , context, callData);
125- }
126- }
127- }
128-
129- /// @notice Handle the response from liquidity check
130- /// @dev If liquidity is found on another shard, initiate the cross-shard transfer
131- function handleLiquidityCheck (
132- bool success ,
133- bytes memory returnData ,
134- bytes memory context
135- ) public payable {
136- if (! success) revert CrossShardCallFailed ("Liquidity check failed " );
137-
138- (
139- TokenId token ,
140- uint256 amount ,
141- address sourcePool ,
142- ,
143- bytes32 requestId ,
144- address borrower
145- ) = abi.decode (
146- context,
147- (TokenId, uint256 , address , uint256 , bytes32 , address )
148- );
149-
150- uint256 availableLiquidity = abi.decode (returnData, (uint256 ));
151-
152- // Only process if this request hasn't been fulfilled yet
153- if (! activeBorrowRequests[requestId] && availableLiquidity >= amount) {
154- // Mark this request as active to prevent other shards from processing it
155- activeBorrowRequests[requestId] = true ;
156-
157- // Continue with the normal borrow process first
158- TokenId collateralToken = (token == usdt) ? eth : usdt;
159-
160- bytes memory callData = abi.encodeWithSignature (
161- "getPrice(address) " ,
162- token
163- );
164-
165- // Pass the source pool information in the context for later use
166- bytes memory priceContext = abi.encodeWithSelector (
167- this .processLoan.selector ,
168- borrower,
169- amount,
170- token,
171- collateralToken,
172- requestId,
173- sourcePool
174- );
175-
176- Nil.sendRequest (oracle, 0 , 9_000_000 , priceContext, callData);
177- }
178- }
179-
18090 /// @notice Transfer liquidity to another shard
18191 /// @dev Called by other shards to request liquidity,
18292 /// @dev loan are to be sent directly to the borrower therefore we need to record the loan first
@@ -244,52 +154,48 @@ contract LendingPool is NilBase, NilTokenBase {
244154 /// @dev Prevents invalid token types from being borrowed.
245155 if (borrowToken != usdt && borrowToken != eth) revert InvalidToken ();
246156
247- /// @notice Check local liquidity first
248- /// @dev If local pool has sufficient liquidity, process the borrow locally
157+ /// @notice Determine which collateral token will be used (opposite of the borrow token)
158+ /// @dev Identifies the collateral token by comparing the borrow token.
159+ TokenId collateralToken = (borrowToken == usdt) ? eth : usdt;
249160
250- // Create a unique request ID at the start of the borrow process
251- bytes32 requestId = keccak256 (
252- abi.encodePacked (block .timestamp , msg .sender , borrowToken, amount)
161+ /// @notice Prepare a call to the Oracle to get the price of the borrow token
162+ /// @dev The price of the borrow token is fetched from the Oracle to calculate collateral.
163+ /// @param callData The encoded data to fetch the price from the Oracle.
164+ bytes memory callData = abi.encodeWithSignature (
165+ "getPrice(address) " ,
166+ borrowToken
253167 );
254168
255- // Check local liquidity first
256- if (Nil.tokenBalance (address (this ), borrowToken) >= amount) {
257- /// @notice Determine which collateral token will be used (opposite of the borrow token)
258- /// @dev Identifies the collateral token by comparing the borrow token.
259- TokenId collateralToken = (borrowToken == usdt) ? eth : usdt;
260-
261- /// @notice Prepare a call to the Oracle to get the price of the borrow token
262- /// @dev The price of the borrow token is fetched from the Oracle to calculate collateral.
263- /// @param callData The encoded data to fetch the price from the Oracle.
264- bytes memory callData = abi.encodeWithSignature (
265- "getPrice(address) " ,
169+ /// @notice Check if there are any lending pools registered
170+ /// @dev If there are no registered lending pools, revert with an error message
171+ if (lendingPoolCount == 0 ) revert NoLendingPoolsRegistered ();
172+
173+ /// @notice Iterate through all registered lending pools
174+ /// @dev Check if any lending pool has sufficient balance of the borrow token
175+ /// @notice we expect that the first lending pool has this contract in the array thereby checking local liquidity first
176+ for (uint256 i = 0 ; i < lendingPools.length ; i++ ) {
177+ uint256 shardBalnce = Nil.tokenBalance (
178+ lendingPools[i],
266179 borrowToken
267180 );
268181
269- /// @notice Encoding the context to process the loan after the price is fetched
270- /// @dev The context contains the borrower's details, loan amount, borrow token, and collateral token.
271- bytes memory context = abi.encodeWithSelector (
272- this .processLoan.selector ,
273- msg .sender ,
274- amount,
275- borrowToken,
276- collateralToken,
277- requestId,
278- address (this )
279- );
182+ if (shardBalnce >= amount) {
183+ bytes memory context = abi.encodeWithSelector (
184+ this .processLoan.selector ,
185+ msg .sender ,
186+ amount,
187+ borrowToken,
188+ collateralToken,
189+ lendingPools[i]
190+ );
280191
281- /// @notice Send a request to the Oracle to get the price of the borrow token.
282- /// @dev This request is processed with a fee for the transaction, allowing the system to fetch the token price.
283- Nil.sendRequest (oracle, 0 , 9_000_000 , context, callData);
284- } else {
285- /// @notice If local liquidity is insufficient, check cross-shard liquidity
286- /// @dev Queries other lending pools across shards for available liquidity
287- checkCrossShardLiquidity (
288- borrowToken,
289- amount,
290- requestId,
291- msg .sender
292- );
192+ /// @notice Send a request to the Oracle to get the price of the borrow token.
193+ /// @dev This request is processed with a fee for the transaction, allowing the system to fetch the token price.
194+ Nil.sendRequest (oracle, 0 , 9_000_000 , context, callData);
195+
196+ /// @notice Break out of the loop after finding a sufficient balance
197+ break ;
198+ }
293199 }
294200 }
295201
@@ -314,12 +220,8 @@ contract LendingPool is NilBase, NilTokenBase {
314220 uint256 amount ,
315221 TokenId borrowToken ,
316222 TokenId collateralToken ,
317- bytes32 requestId ,
318223 address sourcePool
319- ) = abi.decode (
320- context,
321- (address , uint256 , TokenId, TokenId, bytes32 , address )
322- );
224+ ) = abi.decode (context, (address , uint256 , TokenId, TokenId, address ));
323225
324226 /// @notice Decode the price data returned from the Oracle
325227 /// @dev The returned price data is used to calculate the loan value in USD.
@@ -347,7 +249,6 @@ contract LendingPool is NilBase, NilTokenBase {
347249 amount,
348250 borrowToken,
349251 requiredCollateral,
350- requestId,
351252 sourcePool
352253 );
353254
@@ -383,12 +284,8 @@ contract LendingPool is NilBase, NilTokenBase {
383284 uint256 amount ,
384285 TokenId borrowToken ,
385286 uint256 requiredCollateral ,
386- ,
387287 address sourcePool
388- ) = abi.decode (
389- context,
390- (address , uint256 , TokenId, uint256 , bytes32 , address )
391- );
288+ ) = abi.decode (context, (address , uint256 , TokenId, uint256 , address ));
392289
393290 /// @notice Decode the user's collateral balance from GlobalLedger
394291 /// @dev Retrieves the user's collateral balance from the GlobalLedger to compare it with the required collateral.
0 commit comments