@@ -8,7 +8,7 @@ contract CrossCreditBorrow is Base {
88 function test_lendOnSourceAndBorrowOnDest () public {
99 _setOraclePrices (1 );
1010
11- uint256 amountToLend = 1e6 ; // 1 USDC
11+ uint256 amountToLend = 1e6 ; // ~ 1 USDC
1212 address assetToLend = address (sourceUSDC);
1313
1414 // --- SOURCE CHAIN ACTIONS (Lend) ---
@@ -52,7 +52,7 @@ contract CrossCreditBorrow is Base {
5252
5353 // Calculate max borrowable amount and the specific amount to borrow
5454 (,int usdPriceETH_dest , , ,) = priceFeedOnDestETH.latestRoundData ();
55- uint256 LTV = crossCreditOnDest.LTV (); // Assuming LTV is 80 (0.8)
55+ uint256 LTV = crossCreditOnDest.LTV ();
5656 uint256 maxBorrowableUSD = (LTV * userTotalLendValue) / 100 ;
5757 uint256 targetBorrowUSD = ((LTV - 10 ) * userTotalLendValue) / 100 ; // Borrow 10% less than max for safety
5858
@@ -99,4 +99,62 @@ contract CrossCreditBorrow is Base {
9999 assertEq (userTotalBorrowValueOnDest, userTotalBorrowValueOnSource, "Final Borrow USD value mismatch between chains " );
100100 }
101101
102+ function test_lendOnSourceBorrowAndRepayOnDest () public {
103+ _setOraclePrices (1 );
104+
105+ uint256 amountToLend = 1e6 ; // ~1 USDC
106+ address assetToLend = address (sourceUSDC);
107+
108+ vm.selectFork (sourceFork);
109+
110+ vm.startPrank (firstUser);
111+ sourceUSDC.approve (address (crossCreditOnSource), amountToLend);
112+ crossCreditOnSource.lend (amountToLend, assetToLend);
113+ vm.stopPrank ();
114+
115+ ccipLocalSimulatorFork.switchChainAndRouteMessage (destinationFork);
116+
117+ vm.selectFork (destinationFork);
118+ uint userTotalLendValue = crossCreditOnDest.getTotalUSDValueOfUserByType (firstUser, 1 );
119+ (,int usdPriceETH_dest , , ,) = priceFeedOnDestETH.latestRoundData ();
120+ uint256 LTV = crossCreditOnDest.LTV ();
121+ uint256 maxBorrowableUSD = (LTV * userTotalLendValue) / 100 ;
122+ uint256 targetBorrowUSD = ((LTV - 10 ) * userTotalLendValue) / 100 ; // Borrow 10% less than max for safety
123+
124+ uint256 nativeAssetDecimals = crossCreditOnDest.getAssetDecimalsOnSource (NATIVE_ASSET);
125+ uint256 amountToBorrowRaw = (targetBorrowUSD * (10 ** nativeAssetDecimals)) / uint256 (usdPriceETH_dest);
126+
127+ vm.startPrank (firstUser);
128+ // BORROW
129+ uint userBalOnDestBefore = firstUser.balance;
130+ crossCreditOnDest.borrow (amountToBorrowRaw, NATIVE_ASSET);
131+ uint userBalOnDestAfter = firstUser.balance;
132+ vm.stopPrank ();
133+
134+ ccipLocalSimulatorFork.switchChainAndRouteMessage (sourceFork);
135+
136+ vm.selectFork (destinationFork);
137+ // REPAY
138+ vm.startPrank (firstUser);
139+ uint userTotalBorrowValue = crossCreditOnDest.getTotalUSDValueOfUserByType (firstUser, 2 );
140+ bool usdValCalc = userTotalBorrowValue < targetBorrowUSD ? targetBorrowUSD - userTotalBorrowValue < 10 : userTotalBorrowValue - targetBorrowUSD < 10 ;
141+ assertEq (usdValCalc, true , "Borrowed USD value not within tolerance of target " );
142+
143+ _setOraclePrices (1 ); // Price change
144+ (,usdPriceETH_dest, , ,) = priceFeedOnDestETH.latestRoundData ();
145+ uint amountToRepay = (userTotalBorrowValue * (10 ** nativeAssetDecimals)) / uint256 (usdPriceETH_dest);
146+ vm.deal (firstUser, amountToRepay);
147+ crossCreditOnDest.repay {value: amountToRepay}(amountToRepay, NATIVE_ASSET);
148+ userTotalBorrowValue = crossCreditOnDest.getTotalUSDValueOfUserByType (firstUser, 2 );
149+
150+ bool userBorrowValueRepaid = userTotalBorrowValue == 0 || userTotalBorrowValue < 10 ;
151+ assertTrue (userBorrowValueRepaid, "Loan repayment not within range " );
152+ vm.stopPrank ();
153+ ccipLocalSimulatorFork.switchChainAndRouteMessage (sourceFork);
154+
155+ vm.selectFork (sourceFork);
156+ userTotalBorrowValue = crossCreditOnSource.getTotalUSDValueOfUserByType (firstUser, 2 );
157+ userBorrowValueRepaid = userTotalBorrowValue == 0 || userTotalBorrowValue < 10 ;
158+ assertTrue (userBorrowValueRepaid, "Loan repayment not within range " );
159+ }
102160}
0 commit comments