Branch data Line data Source code
1 : : // SPDX-License-Identifier: BUSL-1.1
2 : : pragma solidity ^0.8.10;
3 : :
4 : : import {GPv2SafeERC20} from '../../../dependencies/gnosis/contracts/GPv2SafeERC20.sol';
5 : : import {Address} from '../../../dependencies/openzeppelin/contracts/Address.sol';
6 : : import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol';
7 : : import {IAToken} from '../../../interfaces/IAToken.sol';
8 : : import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol';
9 : : import {Errors} from '../helpers/Errors.sol';
10 : : import {WadRayMath} from '../math/WadRayMath.sol';
11 : : import {DataTypes} from '../types/DataTypes.sol';
12 : : import {ReserveLogic} from './ReserveLogic.sol';
13 : : import {ValidationLogic} from './ValidationLogic.sol';
14 : : import {GenericLogic} from './GenericLogic.sol';
15 : :
16 : : /**
17 : : * @title PoolLogic library
18 : : * @author Aave
19 : : * @notice Implements the logic for Pool specific functions
20 : : */
21 : : library PoolLogic {
22 : : using GPv2SafeERC20 for IERC20;
23 : : using WadRayMath for uint256;
24 : : using ReserveLogic for DataTypes.ReserveData;
25 : : using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
26 : :
27 : : // See `IPool` for descriptions
28 : : event MintedToTreasury(address indexed reserve, uint256 amountMinted);
29 : : event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt);
30 : :
31 : : /**
32 : : * @notice Initialize an asset reserve and add the reserve to the list of reserves
33 : : * @param reservesData The state of all the reserves
34 : : * @param reservesList The addresses of all the active reserves
35 : : * @param params Additional parameters needed for initiation
36 : : * @return true if appended, false if inserted at existing empty spot
37 : : */
38 : : function executeInitReserve(
39 : : mapping(address => DataTypes.ReserveData) storage reservesData,
40 : : mapping(uint256 => address) storage reservesList,
41 : : DataTypes.InitReserveParams memory params
42 : : ) external returns (bool) {
43 : 166023 : require(Address.isContract(params.asset), Errors.NOT_CONTRACT);
44 : 166023 : reservesData[params.asset].init(
45 : : params.aTokenAddress,
46 : : params.variableDebtAddress,
47 : : params.interestRateStrategyAddress
48 : : );
49 : :
50 : 166022 : bool reserveAlreadyAdded = reservesData[params.asset].id != 0 ||
51 : 166022 : reservesList[0] == params.asset;
52 : 166022 : require(!reserveAlreadyAdded, Errors.RESERVE_ALREADY_ADDED);
53 : :
54 : 166022 : for (uint16 i = 0; i < params.reservesCount; i++) {
55 : 9608022 : if (reservesList[i] == address(0)) {
56 : 1 : reservesData[params.asset].id = i;
57 : 1 : reservesList[i] = params.asset;
58 : 1 : return false;
59 : : }
60 : : }
61 : :
62 : 166021 : require(params.reservesCount < params.maxNumberReserves, Errors.NO_MORE_RESERVES_ALLOWED);
63 : 165020 : reservesData[params.asset].id = params.reservesCount;
64 : 165020 : reservesList[params.reservesCount] = params.asset;
65 : 165020 : return true;
66 : : }
67 : :
68 : : /**
69 : : * @notice Rescue and transfer tokens locked in this contract
70 : : * @param token The address of the token
71 : : * @param to The address of the recipient
72 : : * @param amount The amount of token to transfer
73 : : */
74 : : function executeRescueTokens(address token, address to, uint256 amount) external {
75 : 2000 : IERC20(token).safeTransfer(to, amount);
76 : : }
77 : :
78 : : /**
79 : : * @notice Mints the assets accrued through the reserve factor to the treasury in the form of aTokens
80 : : * @param reservesData The state of all the reserves
81 : : * @param assets The list of reserves for which the minting needs to be executed
82 : : */
83 : : function executeMintToTreasury(
84 : : mapping(address => DataTypes.ReserveData) storage reservesData,
85 : : address[] calldata assets
86 : : ) external {
87 : 4 : for (uint256 i = 0; i < assets.length; i++) {
88 : 6 : address assetAddress = assets[i];
89 : :
90 : 6 : DataTypes.ReserveData storage reserve = reservesData[assetAddress];
91 : :
92 : : // this cover both inactive reserves and invalid reserves since the flag will be 0 for both
93 : 6 : if (!reserve.configuration.getActive()) {
94 : 2 : continue;
95 : : }
96 : :
97 : 4 : uint256 accruedToTreasury = reserve.accruedToTreasury;
98 : :
99 : 4 : if (accruedToTreasury != 0) {
100 : 4 : reserve.accruedToTreasury = 0;
101 : 4 : uint256 normalizedIncome = reserve.getNormalizedIncome();
102 : 4 : uint256 amountToMint = accruedToTreasury.rayMul(normalizedIncome);
103 : 4 : IAToken(reserve.aTokenAddress).mintToTreasury(amountToMint, normalizedIncome);
104 : :
105 : 4 : emit MintedToTreasury(assetAddress, amountToMint);
106 : : }
107 : : }
108 : : }
109 : :
110 : : /**
111 : : * @notice Resets the isolation mode total debt of the given asset to zero
112 : : * @dev It requires the given asset has zero debt ceiling
113 : : * @param reservesData The state of all the reserves
114 : : * @param asset The address of the underlying asset to reset the isolationModeTotalDebt
115 : : */
116 : : function executeResetIsolationModeTotalDebt(
117 : : mapping(address => DataTypes.ReserveData) storage reservesData,
118 : : address asset
119 : : ) external {
120 : 1951 : require(reservesData[asset].configuration.getDebtCeiling() == 0, Errors.DEBT_CEILING_NOT_ZERO);
121 : 1951 : reservesData[asset].isolationModeTotalDebt = 0;
122 : 1951 : emit IsolationModeTotalDebtUpdated(asset, 0);
123 : : }
124 : :
125 : : /**
126 : : * @notice Sets the liquidation grace period of the asset
127 : : * @param reservesData The state of all the reserves
128 : : * @param asset The address of the underlying asset to set the liquidationGracePeriod
129 : : * @param until Timestamp when the liquidation grace period will end
130 : : */
131 : : function executeSetLiquidationGracePeriod(
132 : : mapping(address => DataTypes.ReserveData) storage reservesData,
133 : : address asset,
134 : : uint40 until
135 : : ) external {
136 : 12412 : reservesData[asset].liquidationGracePeriodUntil = until;
137 : : }
138 : :
139 : : /**
140 : : * @notice Drop a reserve
141 : : * @param reservesData The state of all the reserves
142 : : * @param reservesList The addresses of all the active reserves
143 : : * @param asset The address of the underlying asset of the reserve
144 : : */
145 : : function executeDropReserve(
146 : : mapping(address => DataTypes.ReserveData) storage reservesData,
147 : : mapping(uint256 => address) storage reservesList,
148 : : address asset
149 : : ) external {
150 : 9 : DataTypes.ReserveData storage reserve = reservesData[asset];
151 : 9 : ValidationLogic.validateDropReserve(reservesList, reserve, asset);
152 : 5 : reservesList[reservesData[asset].id] = address(0);
153 : 5 : delete reservesData[asset];
154 : : }
155 : :
156 : : /**
157 : : * @notice Returns the user account data across all the reserves
158 : : * @param reservesData The state of all the reserves
159 : : * @param reservesList The addresses of all the active reserves
160 : : * @param eModeCategories The configuration of all the efficiency mode categories
161 : : * @param params Additional params needed for the calculation
162 : : * @return totalCollateralBase The total collateral of the user in the base currency used by the price feed
163 : : * @return totalDebtBase The total debt of the user in the base currency used by the price feed
164 : : * @return availableBorrowsBase The borrowing power left of the user in the base currency used by the price feed
165 : : * @return currentLiquidationThreshold The liquidation threshold of the user
166 : : * @return ltv The loan to value of The user
167 : : * @return healthFactor The current health factor of the user
168 : : */
169 : : function executeGetUserAccountData(
170 : : mapping(address => DataTypes.ReserveData) storage reservesData,
171 : : mapping(uint256 => address) storage reservesList,
172 : : mapping(uint8 => DataTypes.EModeCategory) storage eModeCategories,
173 : : DataTypes.CalculateUserAccountDataParams memory params
174 : : )
175 : : external
176 : : view
177 : : returns (
178 : : uint256 totalCollateralBase,
179 : : uint256 totalDebtBase,
180 : : uint256 availableBorrowsBase,
181 : : uint256 currentLiquidationThreshold,
182 : : uint256 ltv,
183 : : uint256 healthFactor
184 : : )
185 : : {
186 : 10015 : (
187 : : totalCollateralBase,
188 : : totalDebtBase,
189 : : ltv,
190 : : currentLiquidationThreshold,
191 : : healthFactor,
192 : :
193 : : ) = GenericLogic.calculateUserAccountData(reservesData, reservesList, eModeCategories, params);
194 : :
195 : 10015 : availableBorrowsBase = GenericLogic.calculateAvailableBorrows(
196 : : totalCollateralBase,
197 : : totalDebtBase,
198 : : ltv
199 : : );
200 : : }
201 : : }
|