11// SPDX-License-Identifier: LGPL-3.0-only
22pragma solidity 0.8.28 ;
33
4- import {ERC20 } from '@openzeppelin/contracts/token/ERC20/ERC20.sol ' ;
4+ import {IERC20 } from '@openzeppelin/contracts/token/ERC20/ERC20.sol ' ;
5+ import {IERC20Metadata } from '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol ' ;
56import {BitMaps} from "@openzeppelin/contracts/utils/structs/BitMaps.sol " ;
67import {AccessControlUpgradeable} from '@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol ' ;
78import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol " ;
@@ -15,7 +16,7 @@ import {IPool, DataTypes} from './interfaces/IPool.sol';
1516import {IAaveOracle} from './interfaces/IAaveOracle.sol ' ;
1617
1718contract LiquidityPool is AccessControlUpgradeable , EIP712Upgradeable {
18- using SafeERC20 for ERC20 ;
19+ using SafeERC20 for IERC20 ;
1920 using ECDSA for bytes32 ;
2021 using Math for uint256 ;
2122 using BitMaps for BitMaps.BitMap;
@@ -32,28 +33,19 @@ contract LiquidityPool is AccessControlUpgradeable, EIP712Upgradeable {
3233 ") "
3334 );
3435
35- ERC20 immutable public COLLATERAL;
36+ IERC20 immutable public COLLATERAL;
3637 IPoolAddressesProvider immutable public AAVE_POOL_PROVIDER;
3738
3839 /// @custom:storage-location erc7201:sprinter.storage.LiquidityPool
3940 struct LiquidityPoolStorage {
4041 // token address to ltv
41- mapping (address => uint256 ) borrowTokenLTV;
42+ mapping (address token = > uint256 ltv ) borrowTokenLTV;
4243 BitMaps.BitMap usedNonces;
4344 address MPCAddress;
4445 uint256 minHealthFactor;
4546 uint256 defaultLTV;
4647 }
4748
48- struct UserAccountData {
49- uint256 totalCollateralBase;
50- uint256 totalDebtBase;
51- uint256 availableBorrowsBase;
52- uint256 currentLiquidationThreshold;
53- uint256 ltv;
54- uint256 healthFactor;
55- }
56-
5749 bytes32 private constant StorageLocation = 0x457f6fd6dd83195f8bfff9ee98f2df1d90fadb996523baa2b453217997285e00 ;
5850
5951 bytes32 public constant LIQUIDITY_ADMIN_ROLE = "LIQUIDITY_ADMIN_ROLE " ;
@@ -73,13 +65,12 @@ contract LiquidityPool is AccessControlUpgradeable, EIP712Upgradeable {
7365 error NonceAlreadyUsed ();
7466
7567 event SuppliedToAave (uint256 amount );
76- event SolverStatusSet (address solver , bool status );
77- event BorrowTokenLTVSet (address token , uint256 ltv );
78- event HealthFactorSet (uint256 healthFactor );
79- event DefaultLTVSet (uint256 defaultLTV );
80- event Borrowed (address borrowToken , uint256 amount , address caller , address target );
68+ event BorrowTokenLTVSet (address token , uint256 oldLTV , uint256 newLTV );
69+ event HealthFactorSet (uint256 oldHealthFactor , uint256 newHealthFactor );
70+ event DefaultLTVSet (uint256 oldDefaultLTV , uint256 newDefaultLTV );
71+ event Borrowed (address borrowToken , uint256 amount , address caller , address target , bytes targetCallData );
8172 event Repaid (address borrowToken , uint256 repaidAmount );
82- event WithdrawnFromAave (uint256 amount );
73+ event WithdrawnFromAave (address to , uint256 amount );
8374 event ProfitWithdrawn (address token , address to , uint256 amount );
8475
8576 constructor (address liquidityToken , address aavePoolProvider ) {
@@ -88,7 +79,7 @@ contract LiquidityPool is AccessControlUpgradeable, EIP712Upgradeable {
8879 'sprinter.storage.LiquidityPool '
8980 );
9081 if (liquidityToken == address (0 )) revert ZeroAddress ();
91- COLLATERAL = ERC20 (liquidityToken);
82+ COLLATERAL = IERC20 (liquidityToken);
9283 if (aavePoolProvider == address (0 )) revert ZeroAddress ();
9384 AAVE_POOL_PROVIDER = IPoolAddressesProvider (aavePoolProvider);
9485 _disableInitializers ();
@@ -140,25 +131,17 @@ contract LiquidityPool is AccessControlUpgradeable, EIP712Upgradeable {
140131 );
141132
142133 // - Check health factor for user after borrow (can be read from aave, getUserAccountData)
143- UserAccountData memory userAccountData;
144- (
145- userAccountData.totalCollateralBase,
146- userAccountData.totalDebtBase,
147- userAccountData.availableBorrowsBase,
148- userAccountData.currentLiquidationThreshold,
149- userAccountData.ltv,
150- userAccountData.healthFactor
151- ) = pool.getUserAccountData (address (this ));
152- if (userAccountData.healthFactor < _getStorage ().minHealthFactor) revert HealthFactorTooLow ();
134+ (,,,,,uint256 healthFactor ) = pool.getUserAccountData (address (this ));
135+ if (healthFactor < _getStorage ().minHealthFactor) revert HealthFactorTooLow ();
153136
154137 // check ltv for token
155138 _checkTokenLTV (pool, borrowToken);
156139 // - Approve the borrowed funds for transfer to the recipient specified in the MPC signature.
157- ERC20 (borrowToken).forceApprove (target, amount);
140+ IERC20 (borrowToken).forceApprove (target, amount);
158141 // - Invoke the recipient's address with calldata provided in the MPC signature to complete the operation securely.
159142 (bool success ,) = target.call (targetCallData);
160143 if (! success) revert TargetCallFailed ();
161- emit Borrowed (borrowToken, amount, msg .sender , target);
144+ emit Borrowed (borrowToken, amount, msg .sender , target, targetCallData );
162145 }
163146
164147 function repay (address [] calldata borrowTokens ) public {
@@ -179,17 +162,9 @@ contract LiquidityPool is AccessControlUpgradeable, EIP712Upgradeable {
179162 uint256 withdrawn = pool.withdraw (address (COLLATERAL), amount, to);
180163 // assert(withdrawn == amount);
181164 // health factor after withdraw
182- UserAccountData memory userAccountData;
183- (
184- userAccountData.totalCollateralBase,
185- userAccountData.totalDebtBase,
186- userAccountData.availableBorrowsBase,
187- userAccountData.currentLiquidationThreshold,
188- userAccountData.ltv,
189- userAccountData.healthFactor
190- ) = pool.getUserAccountData (address (this ));
191- if (userAccountData.healthFactor < _getStorage ().minHealthFactor) revert HealthFactorTooLow ();
192- emit WithdrawnFromAave (withdrawn);
165+ (,,,,,uint256 healthFactor ) = pool.getUserAccountData (address (this ));
166+ if (healthFactor < _getStorage ().minHealthFactor) revert HealthFactorTooLow ();
167+ emit WithdrawnFromAave (to, withdrawn);
193168 }
194169
195170 function withdrawProfit (address token , address to , uint256 amount ) public onlyRole (WITHDRAW_PROFIT_ROLE) {
@@ -199,27 +174,33 @@ contract LiquidityPool is AccessControlUpgradeable, EIP712Upgradeable {
199174 IPool pool = IPool (AAVE_POOL_PROVIDER.getPool ());
200175 DataTypes.ReserveData memory tokenData = pool.getReserveData (token);
201176 if (tokenData.variableDebtTokenAddress != address (0 )) {
202- uint256 totalBorrowed = ERC20 (tokenData.variableDebtTokenAddress).balanceOf (address (this ));
177+ uint256 totalBorrowed = IERC20 (tokenData.variableDebtTokenAddress).balanceOf (address (this ));
203178 if (totalBorrowed != 0 ) revert TokenHasDebt ();
204179 }
205180 // withdraw from this contract
206- ERC20 (token).safeTransfer (to, amount);
181+ IERC20 (token).safeTransfer (to, amount);
207182 emit ProfitWithdrawn (token, to, amount);
208183 }
209184
210185 function setBorrowTokenLTV (address token , uint256 ltv ) public onlyRole (DEFAULT_ADMIN_ROLE) {
211- _getStorage ().borrowTokenLTV[token] = ltv;
212- emit BorrowTokenLTVSet (token, ltv);
186+ LiquidityPoolStorage storage $ = _getStorage ();
187+ uint256 oldLTV = $.borrowTokenLTV[token];
188+ $.borrowTokenLTV[token] = ltv;
189+ emit BorrowTokenLTVSet (token, oldLTV, ltv);
213190 }
214191
215192 function setDefaultLTV (uint256 defaultLTV_ ) public onlyRole (DEFAULT_ADMIN_ROLE) {
216- _getStorage ().defaultLTV = defaultLTV_;
217- emit DefaultLTVSet (defaultLTV_);
193+ LiquidityPoolStorage storage $ = _getStorage ();
194+ uint256 oldDefaultLTV = $.defaultLTV;
195+ $.defaultLTV = defaultLTV_;
196+ emit DefaultLTVSet (oldDefaultLTV, defaultLTV_);
218197 }
219198
220199 function setHealthFactor (uint256 minHealthFactor ) public onlyRole (DEFAULT_ADMIN_ROLE) {
221- _getStorage ().minHealthFactor = minHealthFactor;
222- emit HealthFactorSet (minHealthFactor);
200+ LiquidityPoolStorage storage $ = _getStorage ();
201+ uint256 oldHealthFactor = $.minHealthFactor;
202+ $.minHealthFactor = minHealthFactor;
203+ emit HealthFactorSet (oldHealthFactor, minHealthFactor);
223204 }
224205
225206 // Internal functions
@@ -262,12 +243,12 @@ contract LiquidityPool is AccessControlUpgradeable, EIP712Upgradeable {
262243 if (ltv == 0 ) ltv = $.defaultLTV;
263244
264245 DataTypes.ReserveData memory collateralData = pool.getReserveData (address (COLLATERAL));
265- uint256 totalCollateral = ERC20 (collateralData.aTokenAddress).balanceOf (address (this ));
246+ uint256 totalCollateral = IERC20 (collateralData.aTokenAddress).balanceOf (address (this ));
266247 if (totalCollateral == 0 ) revert NoCollateral ();
267248
268249 DataTypes.ReserveData memory borrowTokenData = pool.getReserveData (borrowToken);
269250 if (borrowTokenData.variableDebtTokenAddress == address (0 )) revert TokenNotSupported (borrowToken);
270- uint256 totalBorrowed = ERC20 (borrowTokenData.variableDebtTokenAddress).balanceOf (address (this ));
251+ uint256 totalBorrowed = IERC20 (borrowTokenData.variableDebtTokenAddress).balanceOf (address (this ));
271252
272253 IAaveOracle oracle = IAaveOracle (AAVE_POOL_PROVIDER.getPriceOracle ());
273254 address [] memory assets = new address [](2 );
@@ -277,8 +258,8 @@ contract LiquidityPool is AccessControlUpgradeable, EIP712Upgradeable {
277258 uint256 [] memory prices = oracle.getAssetsPrices (assets);
278259
279260
280- uint256 collateralDecimals = COLLATERAL.decimals ();
281- uint256 borrowDecimals = ERC20 (borrowToken).decimals ();
261+ uint256 collateralDecimals = IERC20Metadata ( address ( COLLATERAL)) .decimals ();
262+ uint256 borrowDecimals = IERC20Metadata (borrowToken).decimals ();
282263
283264 uint256 collateralUnit = 10 ** collateralDecimals;
284265 uint256 borrowUnit = 10 ** borrowDecimals;
@@ -297,12 +278,12 @@ contract LiquidityPool is AccessControlUpgradeable, EIP712Upgradeable {
297278 success = successInput;
298279 DataTypes.ReserveData memory borrowTokenData = pool.getReserveData (borrowToken);
299280 if (borrowTokenData.variableDebtTokenAddress == address (0 )) revert TokenNotSupported (borrowToken);
300- uint256 totalBorrowed = ERC20 (borrowTokenData.variableDebtTokenAddress).balanceOf (address (this ));
281+ uint256 totalBorrowed = IERC20 (borrowTokenData.variableDebtTokenAddress).balanceOf (address (this ));
301282 if (totalBorrowed == 0 ) return (success, 0 );
302- uint256 borrowTokenBalance = ERC20 (borrowToken).balanceOf (address (this ));
283+ uint256 borrowTokenBalance = IERC20 (borrowToken).balanceOf (address (this ));
303284 if (borrowTokenBalance == 0 ) return (success, 0 );
304285 uint256 amountToRepay = borrowTokenBalance < totalBorrowed ? borrowTokenBalance : type (uint256 ).max;
305- ERC20 (borrowToken).forceApprove (address (pool), amountToRepay);
286+ IERC20 (borrowToken).forceApprove (address (pool), amountToRepay);
306287 repaidAmount = pool.repay (
307288 borrowToken,
308289 amountToRepay,
0 commit comments