@gearbox-protocol/periphery-v3 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,66 @@
1
+ ## Foundry
2
+
3
+ **Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.**
4
+
5
+ Foundry consists of:
6
+
7
+ - **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools).
8
+ - **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data.
9
+ - **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network.
10
+ - **Chisel**: Fast, utilitarian, and verbose solidity REPL.
11
+
12
+ ## Documentation
13
+
14
+ https://book.getfoundry.sh/
15
+
16
+ ## Usage
17
+
18
+ ### Build
19
+
20
+ ```shell
21
+ $ forge build
22
+ ```
23
+
24
+ ### Test
25
+
26
+ ```shell
27
+ $ forge test
28
+ ```
29
+
30
+ ### Format
31
+
32
+ ```shell
33
+ $ forge fmt
34
+ ```
35
+
36
+ ### Gas Snapshots
37
+
38
+ ```shell
39
+ $ forge snapshot
40
+ ```
41
+
42
+ ### Anvil
43
+
44
+ ```shell
45
+ $ anvil
46
+ ```
47
+
48
+ ### Deploy
49
+
50
+ ```shell
51
+ $ forge script script/Counter.s.sol:CounterScript --rpc-url <your_rpc_url> --private-key <your_private_key>
52
+ ```
53
+
54
+ ### Cast
55
+
56
+ ```shell
57
+ $ cast <subcommand>
58
+ ```
59
+
60
+ ### Help
61
+
62
+ ```shell
63
+ $ forge --help
64
+ $ anvil --help
65
+ $ cast --help
66
+ ```
@@ -0,0 +1,318 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ // Gearbox Protocol. Generalized leverage for DeFi protocols
3
+ // (c) Gearbox Holdings, 2022
4
+ pragma solidity ^0.8.10;
5
+ pragma experimental ABIEncoderV2;
6
+
7
+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
8
+ import {Pausable} from "@openzeppelin/contracts/security/Pausable.sol";
9
+
10
+ import {PERCENTAGE_FACTOR} from "@gearbox-protocol/core-v2/contracts/libraries/PercentageMath.sol";
11
+
12
+ import {ContractsRegisterTrait} from "@gearbox-protocol/core-v3/contracts/traits/ContractsRegisterTrait.sol";
13
+ import {IContractsRegister} from "@gearbox-protocol/core-v2/contracts/interfaces/IContractsRegister.sol";
14
+
15
+ import {ICreditManagerV2} from "@gearbox-protocol/core-v2/contracts/interfaces/ICreditManagerV2.sol";
16
+ import {ICreditFacadeV2} from "@gearbox-protocol/core-v2/contracts/interfaces/ICreditFacadeV2.sol";
17
+ import {ICreditConfiguratorV2} from "@gearbox-protocol/core-v2/contracts/interfaces/ICreditConfiguratorV2.sol";
18
+ import {ICreditAccount} from "@gearbox-protocol/core-v2/contracts/interfaces/ICreditAccount.sol";
19
+ import {IPoolService} from "@gearbox-protocol/core-v2/contracts/interfaces/IPoolService.sol";
20
+
21
+ import {IVersion} from "@gearbox-protocol/core-v2/contracts/interfaces/IVersion.sol";
22
+
23
+ import {IAddressProvider} from "@gearbox-protocol/core-v2/contracts/interfaces/IAddressProvider.sol";
24
+ import {IDataCompressorV2_10} from "../interfaces/IDataCompressorV2_10.sol";
25
+
26
+ import {CreditAccountData, CreditManagerData, PoolData, TokenBalance, ContractAdapter} from "./Types.sol";
27
+
28
+ // EXCEPTIONS
29
+ import {ZeroAddressException} from "@gearbox-protocol/core-v2/contracts/interfaces/IErrors.sol";
30
+
31
+ /// @title Data compressor 2.1.
32
+ /// @notice Collects data from various contracts for use in the dApp
33
+ /// Do not use for data from data compressor for state-changing functions
34
+ contract DataCompressorV2_10 is IDataCompressorV2_10, ContractsRegisterTrait {
35
+ // Contract version
36
+ uint256 public constant version = 2_10;
37
+
38
+ constructor(address _addressProvider) ContractsRegisterTrait(_addressProvider) {}
39
+
40
+ /// @dev Returns CreditAccountData for all opened accounts for particular borrower
41
+ /// @param borrower Borrower address
42
+ function getCreditAccountList(address borrower) external view returns (CreditAccountData[] memory result) {
43
+ // Counts how many opened accounts a borrower has
44
+ uint256 count;
45
+ uint256 creditManagersLength = IContractsRegister(contractsRegister).getCreditManagersCount();
46
+ unchecked {
47
+ for (uint256 i = 0; i < creditManagersLength; ++i) {
48
+ address creditManager = IContractsRegister(contractsRegister).creditManagers(i);
49
+ if (hasOpenedCreditAccount(creditManager, borrower)) {
50
+ ++count;
51
+ }
52
+ }
53
+ }
54
+
55
+ result = new CreditAccountData[](count);
56
+
57
+ // Get data & fill the array
58
+ count = 0;
59
+ for (uint256 i = 0; i < creditManagersLength;) {
60
+ address creditManager = IContractsRegister(contractsRegister).creditManagers(i);
61
+ unchecked {
62
+ if (hasOpenedCreditAccount(creditManager, borrower)) {
63
+ result[count] = getCreditAccountData(creditManager, borrower);
64
+
65
+ count++;
66
+ }
67
+
68
+ ++i;
69
+ }
70
+ }
71
+ }
72
+
73
+ /// @dev Returns whether the borrower has an open credit account with the credit manager
74
+ /// @param _creditManager Credit manager to check
75
+ /// @param borrower Borrower to check
76
+ function hasOpenedCreditAccount(address _creditManager, address borrower)
77
+ public
78
+ view
79
+ registeredCreditManagerOnly(_creditManager)
80
+ returns (bool)
81
+ {
82
+ return _hasOpenedCreditAccount(_creditManager, borrower);
83
+ }
84
+
85
+ /// @dev Returns CreditAccountData for a particular Credit Account account, based on creditManager and borrower
86
+ /// @param _creditManager Credit manager address
87
+ /// @param borrower Borrower address
88
+ function getCreditAccountData(address _creditManager, address borrower)
89
+ public
90
+ view
91
+ returns (CreditAccountData memory result)
92
+ {
93
+ (uint256 ver, ICreditManagerV2 creditManagerV2, ICreditFacadeV2 creditFacade,) =
94
+ getCreditContracts(_creditManager);
95
+
96
+ result.cfVersion = ver;
97
+
98
+ address creditAccount = creditManagerV2.getCreditAccountOrRevert(borrower);
99
+
100
+ result.borrower = borrower;
101
+ result.creditManager = _creditManager;
102
+ result.addr = creditAccount;
103
+
104
+ result.underlying = creditManagerV2.underlying();
105
+ (result.totalValue,) = creditFacade.calcTotalValue(creditAccount);
106
+ result.healthFactor = creditFacade.calcCreditAccountHealthFactor(creditAccount);
107
+
108
+ {
109
+ (uint256 debt, uint256 borrowedAmountPlusInterest, uint256 borrowedAmountPlusInterestAndFees) =
110
+ creditManagerV2.calcCreditAccountAccruedInterest(creditAccount);
111
+
112
+ result.debt = debt;
113
+ result.accruedInterest = borrowedAmountPlusInterest - debt;
114
+ result.accruedFees = borrowedAmountPlusInterestAndFees - borrowedAmountPlusInterest;
115
+ }
116
+
117
+ address pool = creditManagerV2.pool();
118
+ result.baseBorrowRate = IPoolService(pool).borrowAPY_RAY();
119
+
120
+ uint256 collateralTokenCount = creditManagerV2.collateralTokensCount();
121
+
122
+ result.enabledTokensMask = creditManagerV2.enabledTokensMap(creditAccount);
123
+
124
+ result.balances = new TokenBalance[](collateralTokenCount);
125
+
126
+ unchecked {
127
+ for (uint256 i = 0; i < collateralTokenCount; ++i) {
128
+ TokenBalance memory balance;
129
+ uint256 tokenMask = 1 << i;
130
+
131
+ (balance.token,) = creditManagerV2.collateralTokens(i);
132
+ balance.balance = IERC20(balance.token).balanceOf(creditAccount);
133
+
134
+ balance.isForbidden = !creditFacade.isTokenAllowed(balance.token);
135
+ balance.isEnabled = tokenMask & result.enabledTokensMask == 0 ? false : true;
136
+
137
+ result.balances[i] = balance;
138
+ }
139
+ }
140
+
141
+ result.cumulativeIndexLastUpdate = ICreditAccount(creditAccount).cumulativeIndexAtOpen();
142
+
143
+ result.since = uint64(ICreditAccount(creditAccount).since());
144
+ }
145
+
146
+ /// @dev Returns CreditManagerData for all Credit Managers
147
+ function getCreditManagersList() external view returns (CreditManagerData[] memory result) {
148
+ uint256 creditManagersCount = IContractsRegister(contractsRegister).getCreditManagersCount();
149
+
150
+ result = new CreditManagerData[](creditManagersCount);
151
+
152
+ unchecked {
153
+ for (uint256 i = 0; i < creditManagersCount; ++i) {
154
+ address creditManager = IContractsRegister(contractsRegister).creditManagers(i);
155
+ result[i] = getCreditManagerData(creditManager);
156
+ }
157
+ }
158
+ }
159
+
160
+ /// @dev Returns CreditManagerData for a particular _creditManager
161
+ /// @param _creditManager CreditManager address
162
+ function getCreditManagerData(address _creditManager) public view returns (CreditManagerData memory result) {
163
+ (
164
+ uint256 ver,
165
+ ICreditManagerV2 creditManagerV2,
166
+ ICreditFacadeV2 creditFacade,
167
+ ICreditConfiguratorV2 creditConfigurator
168
+ ) = getCreditContracts(_creditManager);
169
+
170
+ result.addr = _creditManager;
171
+ result.cfVersion = ver;
172
+
173
+ result.underlying = creditManagerV2.underlying();
174
+
175
+ {
176
+ result.pool = creditManagerV2.pool();
177
+ IPoolService pool = IPoolService(result.pool);
178
+ // result.canBorrow =;
179
+ result.baseBorrowRate = pool.borrowAPY_RAY();
180
+ result.availableToBorrow = pool.creditManagersCanBorrow(_creditManager) ? pool.availableLiquidity() : 0;
181
+ }
182
+
183
+ (result.minDebt, result.maxDebt) = creditFacade.limits();
184
+
185
+ {
186
+ uint256 collateralTokenCount = creditManagerV2.collateralTokensCount();
187
+
188
+ result.collateralTokens = new address[](collateralTokenCount);
189
+ result.liquidationThresholds = new uint256[](collateralTokenCount);
190
+
191
+ unchecked {
192
+ for (uint256 i = 0; i < collateralTokenCount; ++i) {
193
+ (result.collateralTokens[i], result.liquidationThresholds[i]) = creditManagerV2.collateralTokens(i);
194
+ }
195
+ }
196
+ }
197
+
198
+ address[] memory allowedContracts = creditConfigurator.allowedContracts();
199
+ uint256 len = allowedContracts.length;
200
+ result.adapters = new ContractAdapter[](len);
201
+
202
+ unchecked {
203
+ for (uint256 i = 0; i < len; ++i) {
204
+ address targetContract = allowedContracts[i];
205
+
206
+ result.adapters[i] = ContractAdapter({
207
+ targetContract: targetContract,
208
+ adapter: creditManagerV2.contractToAdapter(targetContract)
209
+ });
210
+ }
211
+ }
212
+
213
+ result.creditFacade = address(creditFacade);
214
+ result.creditConfigurator = creditManagerV2.creditConfigurator();
215
+ result.degenNFT = creditFacade.degenNFT();
216
+ {
217
+ bool isIncreaseDebtForbidden;
218
+ (, isIncreaseDebtForbidden,,) = creditFacade.params(); // V2 only: true if increasing debt is forbidden
219
+
220
+ (uint128 currentTotalDebt, uint128 totalDebtLimit) = creditFacade.totalDebt(); // V2 only: total debt and total debt limit
221
+
222
+ result.availableToBorrow = isIncreaseDebtForbidden ? 0 : totalDebtLimit - currentTotalDebt;
223
+ }
224
+
225
+ result.forbiddenTokenMask = creditManagerV2.forbiddenTokenMask(); // V2 only: mask which forbids some particular tokens
226
+ result.maxEnabledTokensLength = creditManagerV2.maxAllowedEnabledTokenLength(); // V2 only: a limit on enabled tokens imposed for security
227
+ {
228
+ (
229
+ result.feeInterest,
230
+ result.feeLiquidation,
231
+ result.liquidationDiscount,
232
+ result.feeLiquidationExpired,
233
+ result.liquidationDiscountExpired
234
+ ) = creditManagerV2.fees();
235
+ }
236
+
237
+ result.isPaused = Pausable(address(creditManagerV2)).paused();
238
+ }
239
+
240
+ /// @dev Returns PoolData for a particular pool
241
+ /// @param _pool Pool address
242
+ function getPoolData(address _pool) public view registeredPoolOnly(_pool) returns (PoolData memory result) {
243
+ IPoolService pool = IPoolService(_pool);
244
+
245
+ result.addr = _pool;
246
+ result.expectedLiquidity = pool.expectedLiquidity();
247
+ result.availableLiquidity = pool.availableLiquidity();
248
+ result.totalBorrowed = pool.totalBorrowed();
249
+ result.dieselRate_RAY = pool.getDieselRate_RAY();
250
+ result.linearCumulativeIndex = pool.calcLinearCumulative_RAY();
251
+ result.baseInterestRate = pool.borrowAPY_RAY();
252
+ result.underlying = pool.underlyingToken();
253
+ result.dieselToken = pool.dieselToken();
254
+ result.dieselRate_RAY = pool.getDieselRate_RAY();
255
+ result.withdrawFee = pool.withdrawFee();
256
+ result.baseInterestIndexLU = pool._timestampLU();
257
+ result.cumulativeIndex_RAY = pool._cumulativeIndex_RAY();
258
+
259
+ uint256 dieselSupply = IERC20(result.dieselToken).totalSupply();
260
+ uint256 totalLP = pool.fromDiesel(dieselSupply);
261
+ result.supplyRate = totalLP == 0
262
+ ? result.baseInterestRate
263
+ : (result.baseInterestRate * result.totalBorrowed) * (PERCENTAGE_FACTOR - result.withdrawFee) / totalLP
264
+ / PERCENTAGE_FACTOR;
265
+
266
+ result.version = uint8(pool.version());
267
+
268
+ return result;
269
+ }
270
+
271
+ /// @dev Returns PoolData for all registered pools
272
+ function getPoolsList() external view returns (PoolData[] memory result) {
273
+ uint256 poolsLength = IContractsRegister(contractsRegister).getPoolsCount();
274
+
275
+ result = new PoolData[](poolsLength);
276
+ unchecked {
277
+ for (uint256 i = 0; i < poolsLength; ++i) {
278
+ address pool = IContractsRegister(contractsRegister).pools(i);
279
+ result[i] = getPoolData(pool);
280
+ }
281
+ }
282
+ }
283
+
284
+ /// @dev Returns the adapter address for a particular creditManager and targetContract
285
+ function getAdapter(address _creditManager, address _allowedContract)
286
+ external
287
+ view
288
+ registeredCreditManagerOnly(_creditManager)
289
+ returns (address adapter)
290
+ {
291
+ (, ICreditManagerV2 creditManagerV2,,) = getCreditContracts(_creditManager);
292
+
293
+ adapter = creditManagerV2.contractToAdapter(_allowedContract);
294
+ }
295
+
296
+ /// @dev Internal implementation for hasOpenedCreditAccount
297
+ function _hasOpenedCreditAccount(address creditManager, address borrower) internal view returns (bool) {
298
+ return ICreditManagerV2(creditManager).creditAccounts(borrower) != address(0);
299
+ }
300
+
301
+ /// @dev Retrieves all relevant credit contracts for a particular Credit Manager
302
+ function getCreditContracts(address _creditManager)
303
+ internal
304
+ view
305
+ registeredCreditManagerOnly(_creditManager)
306
+ returns (
307
+ uint256 ver,
308
+ ICreditManagerV2 creditManagerV2,
309
+ ICreditFacadeV2 creditFacade,
310
+ ICreditConfiguratorV2 creditConfigurator
311
+ )
312
+ {
313
+ creditManagerV2 = ICreditManagerV2(_creditManager);
314
+ creditFacade = ICreditFacadeV2(creditManagerV2.creditFacade());
315
+ creditConfigurator = ICreditConfiguratorV2(creditManagerV2.creditConfigurator());
316
+ ver = ICreditFacadeV2(creditFacade).version();
317
+ }
318
+ }
@@ -0,0 +1,625 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ // Gearbox Protocol. Generalized leverage for DeFi protocols
3
+ // (c) Gearbox Holdings, 2022
4
+ pragma solidity ^0.8.10;
5
+ pragma experimental ABIEncoderV2;
6
+
7
+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
8
+ import {PERCENTAGE_FACTOR, RAY} from "@gearbox-protocol/core-v2/contracts/libraries/Constants.sol";
9
+
10
+ import {ContractsRegisterTrait} from "@gearbox-protocol/core-v3/contracts/traits/ContractsRegisterTrait.sol";
11
+ import {IContractsRegister} from "@gearbox-protocol/core-v2/contracts/interfaces/IContractsRegister.sol";
12
+ import {CreditFacadeV3} from "@gearbox-protocol/core-v3/contracts/credit/CreditFacadeV3.sol";
13
+
14
+ import {
15
+ ICreditManagerV3,
16
+ CollateralDebtData,
17
+ CollateralCalcTask
18
+ } from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
19
+ import {ICreditFacadeV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditFacadeV3.sol";
20
+ import {ICreditConfiguratorV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditConfiguratorV3.sol";
21
+ import {IPriceOracleV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IPriceOracleV3.sol";
22
+ import {ICreditAccountV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditAccountV3.sol";
23
+ import {IPoolQuotaKeeperV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IPoolQuotaKeeperV3.sol";
24
+ import {IPoolV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IPoolV3.sol";
25
+
26
+ import {CreditManagerV3} from "@gearbox-protocol/core-v3/contracts/credit/CreditManagerV3.sol";
27
+
28
+ import {CreditFacadeV3} from "@gearbox-protocol/core-v3/contracts/credit/CreditFacadeV3.sol";
29
+ import {IBotListV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IBotListV3.sol";
30
+ import {IWithdrawalManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IWithdrawalManagerV3.sol";
31
+ import {IGaugeV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IGaugeV3.sol";
32
+
33
+ import {IPriceFeed} from "@gearbox-protocol/core-v2/contracts/interfaces/IPriceFeed.sol";
34
+ import {IUpdatablePriceFeed} from "@gearbox-protocol/core-v2/contracts/interfaces/IPriceFeed.sol";
35
+
36
+ import {IVersion} from "@gearbox-protocol/core-v2/contracts/interfaces/IVersion.sol";
37
+
38
+ import {AddressProvider} from "@gearbox-protocol/core-v2/contracts/core/AddressProvider.sol";
39
+ import {IDataCompressorV3_00, PriceOnDemand} from "../interfaces/IDataCompressorV3_00.sol";
40
+
41
+ import {
42
+ CreditAccountData,
43
+ CreditManagerData,
44
+ PoolData,
45
+ TokenBalance,
46
+ ContractAdapter,
47
+ QuotaInfo,
48
+ GaugeInfo,
49
+ GaugeQuotaParams,
50
+ CreditManagerDebtParams,
51
+ GaugeVote
52
+ } from "./Types.sol";
53
+
54
+ // EXCEPTIONS
55
+ import "@gearbox-protocol/core-v3/contracts/interfaces/IExceptions.sol";
56
+
57
+ uint256 constant COUNT = 0;
58
+ uint256 constant QUERY = 1;
59
+
60
+ /// @title Data compressor 3.0.
61
+ /// @notice Collects data from various contracts for use in the dApp
62
+ /// Do not use for data from data compressor for state-changing functions
63
+ contract DataCompressorV3_00 is IDataCompressorV3_00, ContractsRegisterTrait {
64
+ // Contract version
65
+ uint256 public constant version = 3_00;
66
+
67
+ error CreditManagerIsNotV3Exception();
68
+
69
+ constructor(address _addressProvider) ContractsRegisterTrait(_addressProvider) {}
70
+
71
+ /// @dev Returns CreditAccountData for all opened accounts for particular borrower
72
+ /// @param borrower Borrower address
73
+ /// @param priceUpdates Price updates for priceFeedsOnDemand
74
+ function getCreditAccountsByBorrower(address borrower, PriceOnDemand[] memory priceUpdates)
75
+ external
76
+ override
77
+ returns (CreditAccountData[] memory result)
78
+ {
79
+ return _queryCreditAccounts(_listCreditManagersV3(), borrower, false, priceUpdates);
80
+ }
81
+
82
+ function getCreditAccountsByCreditManager(address creditManager, PriceOnDemand[] memory priceUpdates)
83
+ external
84
+ registeredCreditManagerOnly(creditManager)
85
+ returns (CreditAccountData[] memory result)
86
+ {
87
+ if (!_isContractV3(creditManager)) revert CreditManagerIsNotV3Exception();
88
+
89
+ address[] memory creditManagers = new address[](1);
90
+ creditManagers[0] = creditManager;
91
+ return _queryCreditAccounts(creditManagers, address(0), false, priceUpdates);
92
+ }
93
+
94
+ function getLiquidatableCreditAccounts(PriceOnDemand[] memory priceUpdates)
95
+ external
96
+ returns (CreditAccountData[] memory result)
97
+ {
98
+ return _queryCreditAccounts(_listCreditManagersV3(), address(0), true, priceUpdates);
99
+ }
100
+
101
+ /// @notice Query credit accounts data by parameters
102
+ /// @param borrower Borrower address, all borrowers if address(0)
103
+ /// @param liquidatableOnly If true, returns only liquidatable accounts
104
+ /// @param priceUpdates Price updates for priceFeedsOnDemand
105
+ function _queryCreditAccounts(
106
+ address[] memory creditManagers,
107
+ address borrower,
108
+ bool liquidatableOnly,
109
+ PriceOnDemand[] memory priceUpdates
110
+ ) internal returns (CreditAccountData[] memory result) {
111
+ uint256 index;
112
+ uint256 len = creditManagers.length;
113
+ unchecked {
114
+ for (uint256 op = COUNT; op <= QUERY; ++op) {
115
+ if (op == QUERY && index == 0) {
116
+ break;
117
+ } else {
118
+ result = new CreditAccountData[](index);
119
+ index = 0;
120
+ }
121
+
122
+ for (uint256 i = 0; i < len; ++i) {
123
+ address _pool = creditManagers[i];
124
+
125
+ _updatePrices(_pool, priceUpdates);
126
+ address[] memory creditAccounts = ICreditManagerV3(_pool).creditAccounts();
127
+ uint256 caLen = creditAccounts.length;
128
+ for (uint256 j; j < caLen; ++j) {
129
+ if (
130
+ (
131
+ borrower == address(0)
132
+ || ICreditManagerV3(_pool).getBorrowerOrRevert(creditAccounts[i]) == borrower
133
+ )
134
+ && (
135
+ !liquidatableOnly
136
+ || ICreditManagerV3(_pool).isLiquidatable(creditAccounts[i], PERCENTAGE_FACTOR)
137
+ )
138
+ ) {
139
+ if (op == QUERY) {
140
+ result[index] = _getCreditAccountData(_pool, creditAccounts[j]);
141
+ }
142
+ ++index;
143
+ }
144
+ }
145
+ }
146
+ }
147
+ }
148
+ }
149
+
150
+ /// @dev Returns CreditAccountData for a particular Credit Account account, based on creditManager and borrower
151
+ /// @param _creditAccount Credit account address
152
+ /// @param priceUpdates Price updates for priceFeedsOnDemand
153
+ function getCreditAccountData(address _creditAccount, PriceOnDemand[] memory priceUpdates)
154
+ public
155
+ returns (CreditAccountData memory result)
156
+ {
157
+ ICreditAccountV3 creditAccount = ICreditAccountV3(_creditAccount);
158
+
159
+ address _pool = creditAccount.creditManager();
160
+ _ensureRegisteredCreditManager(_pool);
161
+
162
+ if (!_isContractV3(_pool)) revert CreditManagerIsNotV3Exception();
163
+
164
+ _updatePrices(_pool, priceUpdates);
165
+
166
+ return _getCreditAccountData(_pool, _creditAccount);
167
+ }
168
+
169
+ function _getCreditAccountData(address _pool, address _creditAccount)
170
+ internal
171
+ view
172
+ returns (CreditAccountData memory result)
173
+ {
174
+ ICreditManagerV3 creditManager = ICreditManagerV3(_pool);
175
+ ICreditFacadeV3 creditFacade = ICreditFacadeV3(creditManager.creditFacade());
176
+ // ICreditConfiguratorV3 creditConfigurator = ICreditConfiguratorV3(creditManager.creditConfigurator());
177
+
178
+ result.cfVersion = creditFacade.version();
179
+
180
+ address borrower = creditManager.getBorrowerOrRevert(_creditAccount);
181
+
182
+ result.borrower = borrower;
183
+ result.creditManager = _pool;
184
+ result.addr = _creditAccount;
185
+
186
+ result.underlying = creditManager.underlying();
187
+
188
+ address pool = creditManager.pool();
189
+ result.baseBorrowRate = IPoolV3(pool).baseInterestRate();
190
+
191
+ uint256 collateralTokenCount = creditManager.collateralTokensCount();
192
+
193
+ result.enabledTokensMask = creditManager.enabledTokensMaskOf(_creditAccount);
194
+
195
+ result.balances = new TokenBalance[](collateralTokenCount);
196
+ {
197
+ uint256 forbiddenTokenMask = creditFacade.forbiddenTokenMask();
198
+ uint256 quotedTokensMask = creditManager.quotedTokensMask();
199
+ IPoolQuotaKeeperV3 pqk = IPoolQuotaKeeperV3(creditManager.poolQuotaKeeper());
200
+
201
+ unchecked {
202
+ for (uint256 i = 0; i < collateralTokenCount; ++i) {
203
+ TokenBalance memory balance;
204
+ uint256 tokenMask = 1 << i;
205
+
206
+ (balance.token,) = creditManager.collateralTokenByMask(tokenMask);
207
+ balance.balance = IERC20(balance.token).balanceOf(_creditAccount);
208
+
209
+ balance.isForbidden = tokenMask & forbiddenTokenMask == 0 ? false : true;
210
+ balance.isEnabled = tokenMask & result.enabledTokensMask == 0 ? false : true;
211
+
212
+ balance.isQuoted = tokenMask & quotedTokensMask == 0 ? false : true;
213
+
214
+ if (balance.isQuoted) {
215
+ (balance.quota,) = pqk.getQuota(_creditAccount, balance.token);
216
+ balance.quotaRate = pqk.getQuotaRate(balance.token);
217
+ }
218
+
219
+ result.balances[i] = balance;
220
+ }
221
+ }
222
+ }
223
+
224
+ // uint256 debt;
225
+ // uint256 cumulativeIndexNow;
226
+ // uint256 cumulativeIndexLastUpdate;
227
+ // uint128 cumulativeQuotaInterest;
228
+ // uint256 accruedInterest;
229
+ // uint256 accruedFees;
230
+ // uint256 totalDebtUSD;
231
+ // uint256 totalValue;
232
+ // uint256 totalValueUSD;
233
+ // uint256 twvUSD;
234
+ // uint256 enabledTokensMask;
235
+ // uint256 quotedTokensMask;
236
+ // address[] quotedTokens;
237
+
238
+ try creditManager.calcDebtAndCollateral(_creditAccount, CollateralCalcTask.DEBT_COLLATERAL_WITHOUT_WITHDRAWALS)
239
+ returns (CollateralDebtData memory collateralDebtData) {
240
+ result.accruedInterest = collateralDebtData.accruedInterest;
241
+ result.accruedFees = collateralDebtData.accruedFees;
242
+ result.healthFactor = collateralDebtData.twvUSD * PERCENTAGE_FACTOR / collateralDebtData.debt;
243
+ result.totalValue = collateralDebtData.totalValue;
244
+ result.isSuccessful = true;
245
+ } catch {
246
+ _getPriceFeedFailedList(_pool, result.balances);
247
+ result.isSuccessful = false;
248
+ }
249
+
250
+ // (result.totalValue,) = creditFacade.calcTotalValue(creditAccount);
251
+ // = ICreditAccountV3(creditAccount).cumulativeIndexAtOpen();
252
+
253
+ // uint256 debt;
254
+ // uint256 cumulativeIndexLastUpdate;
255
+ // uint128 cumulativeQuotaInterest;
256
+ // uint128 quotaFees;
257
+ // uint256 enabledTokensMask;
258
+ // uint16 flags;
259
+ // uint64 since;
260
+ // address borrower;
261
+
262
+ (result.debt, result.cumulativeIndexLastUpdate, result.cumulativeQuotaInterest,,,, result.since,) =
263
+ CreditManagerV3(_pool).creditAccountInfo(_creditAccount);
264
+
265
+ result.expirationDate = creditFacade.expirationDate();
266
+ result.maxApprovedBots = CreditFacadeV3(address(creditFacade)).maxApprovedBots();
267
+
268
+ result.activeBots =
269
+ IBotListV3(CreditFacadeV3(address(creditFacade)).botList()).getActiveBots(_pool, _creditAccount);
270
+
271
+ // QuotaInfo[] quotas;
272
+ result.schedultedWithdrawals = IWithdrawalManagerV3(CreditFacadeV3(address(creditFacade)).withdrawalManager())
273
+ .scheduledWithdrawals(_creditAccount);
274
+ }
275
+
276
+ function _listCreditManagersV3() internal view returns (address[] memory result) {
277
+ uint256 len = IContractsRegister(contractsRegister).getCreditManagersCount();
278
+
279
+ uint256 index;
280
+ unchecked {
281
+ for (uint256 op = COUNT; op <= QUERY; ++op) {
282
+ if (op == QUERY && index == 0) {
283
+ break;
284
+ } else {
285
+ result = new address[](index);
286
+ index = 0;
287
+ }
288
+
289
+ for (uint256 i = 0; i < len; ++i) {
290
+ address _pool = IContractsRegister(contractsRegister).creditManagers(i);
291
+
292
+ if (_isContractV3(_pool)) {
293
+ if (op == QUERY) result[index] = _pool;
294
+ ++index;
295
+ }
296
+ }
297
+ }
298
+ }
299
+ }
300
+
301
+ function _isContractV3(address _pool) internal view returns (bool) {
302
+ uint256 cmVersion = IVersion(_pool).version();
303
+ return cmVersion >= 3_00 && cmVersion < 3_99;
304
+ }
305
+
306
+ /// @dev Returns CreditManagerData for all Credit Managers
307
+ function getCreditManagersV3List() external view returns (CreditManagerData[] memory result) {
308
+ address[] memory creditManagers = _listCreditManagersV3();
309
+ uint256 len = creditManagers.length;
310
+
311
+ result = new CreditManagerData[](len);
312
+
313
+ unchecked {
314
+ for (uint256 i = 0; i < len; ++i) {
315
+ result[i] = getCreditManagerData(creditManagers[i]);
316
+ }
317
+ }
318
+ }
319
+
320
+ /// @dev Returns CreditManagerData for a particular _pool
321
+ /// @param _pool CreditManager address
322
+ function getCreditManagerData(address _pool) public view returns (CreditManagerData memory result) {
323
+ ICreditManagerV3 creditManager = ICreditManagerV3(_pool);
324
+ ICreditConfiguratorV3 creditConfigurator = ICreditConfiguratorV3(creditManager.creditConfigurator());
325
+ ICreditFacadeV3 creditFacade = ICreditFacadeV3(creditManager.creditFacade());
326
+
327
+ result.addr = _pool;
328
+ result.cfVersion = creditFacade.version();
329
+
330
+ result.underlying = creditManager.underlying();
331
+
332
+ {
333
+ result.pool = creditManager.pool();
334
+ IPoolV3 pool = IPoolV3(result.pool);
335
+ result.baseBorrowRate = pool.baseInterestRate();
336
+ result.availableToBorrow = pool.creditManagerBorrowable(_pool);
337
+ }
338
+
339
+ (result.minDebt, result.maxDebt) = creditFacade.debtLimits();
340
+
341
+ {
342
+ uint256 collateralTokenCount = creditManager.collateralTokensCount();
343
+
344
+ result.collateralTokens = new address[](collateralTokenCount);
345
+ result.liquidationThresholds = new uint256[](collateralTokenCount);
346
+
347
+ unchecked {
348
+ for (uint256 i = 0; i < collateralTokenCount; ++i) {
349
+ (result.collateralTokens[i], result.liquidationThresholds[i]) =
350
+ creditManager.collateralTokenByMask(1 << i);
351
+ }
352
+ }
353
+ }
354
+
355
+ address[] memory allowedAdapters = creditConfigurator.allowedAdapters();
356
+ uint256 len = allowedAdapters.length;
357
+ result.adapters = new ContractAdapter[](len);
358
+
359
+ unchecked {
360
+ for (uint256 i = 0; i < len; ++i) {
361
+ address allowedAdapter = allowedAdapters[i];
362
+
363
+ result.adapters[i] = ContractAdapter({
364
+ targetContract: creditManager.adapterToContract(allowedAdapter),
365
+ adapter: allowedAdapter
366
+ });
367
+ }
368
+ }
369
+
370
+ result.creditFacade = address(creditFacade);
371
+ result.creditConfigurator = address(creditConfigurator);
372
+ result.degenNFT = creditFacade.degenNFT();
373
+ // (, result.isIncreaseDebtForbidden,,) = creditFacade.params(); // V2 only: true if increasing debt is forbidden
374
+ result.forbiddenTokenMask = creditFacade.forbiddenTokenMask(); // V2 only: mask which forbids some particular tokens
375
+ result.maxEnabledTokensLength = creditManager.maxEnabledTokens(); // V2 only: a limit on enabled tokens imposed for security
376
+ {
377
+ (
378
+ result.feeInterest,
379
+ result.feeLiquidation,
380
+ result.liquidationDiscount,
381
+ result.feeLiquidationExpired,
382
+ result.liquidationDiscountExpired
383
+ ) = creditManager.fees();
384
+ }
385
+
386
+ result.quotas = _getQuotas(result.pool);
387
+
388
+ result.isPaused = CreditFacadeV3(address(creditFacade)).paused();
389
+ }
390
+
391
+ /// @dev Returns PoolData for a particular pool
392
+ /// @param _pool Pool address
393
+ function getPoolData(address _pool) public view registeredPoolOnly(_pool) returns (PoolData memory result) {
394
+ IPoolV3 pool = IPoolV3(_pool);
395
+
396
+ result.addr = _pool;
397
+ result.expectedLiquidity = pool.expectedLiquidity();
398
+ result.availableLiquidity = pool.availableLiquidity();
399
+
400
+ result.dieselRate_RAY = pool.convertToAssets(RAY);
401
+ result.linearCumulativeIndex = pool.calcLinearCumulative_RAY();
402
+ result.baseInterestRate = pool.baseInterestRate();
403
+ result.underlying = pool.underlyingToken();
404
+ result.dieselToken = address(pool);
405
+
406
+ result.dieselRate_RAY = pool.convertToAssets(RAY);
407
+ result.withdrawFee = pool.withdrawFee();
408
+ result.baseInterestIndexLU = pool.baseInterestIndexLU();
409
+ // result.cumulativeIndex_RAY = pool.calcLinearCumulative_RAY();
410
+
411
+ // Borrowing limits
412
+ result.totalBorrowed = pool.totalBorrowed();
413
+ result.totalDebtLimit = pool.totalDebtLimit();
414
+
415
+ address[] memory creditManagers = pool.creditManagers();
416
+ uint256 len = creditManagers.length;
417
+ result.creditManagerDebtParams = new CreditManagerDebtParams[](len);
418
+
419
+ unchecked {
420
+ for (uint256 i; i < len; ++i) {
421
+ address creditManager = creditManagers[i];
422
+ result.creditManagerDebtParams[i] = CreditManagerDebtParams({
423
+ creditManager: creditManager,
424
+ borrowed: pool.creditManagerBorrowed(creditManager),
425
+ limit: pool.creditManagerDebtLimit(creditManager),
426
+ availableToBorrow: pool.creditManagerBorrowable(creditManager)
427
+ });
428
+ }
429
+ }
430
+
431
+ result.totalSupply = pool.totalSupply();
432
+ result.totalAssets = pool.totalAssets();
433
+
434
+ result.supplyRate = pool.supplyRate();
435
+
436
+ result.version = uint8(pool.version());
437
+
438
+ result.quotas = _getQuotas(_pool);
439
+
440
+ return result;
441
+ }
442
+
443
+ /// @dev Returns PoolData for all registered pools
444
+ function getPoolsV3List() external view returns (PoolData[] memory result) {
445
+ address[] memory poolsV3 = _listPoolsV3();
446
+ uint256 len = poolsV3.length;
447
+ result = new PoolData[](len);
448
+
449
+ unchecked {
450
+ for (uint256 i = 0; i < len; ++i) {
451
+ result[i] = getPoolData(poolsV3[i]);
452
+ }
453
+ }
454
+ }
455
+
456
+ function _listPoolsV3() internal view returns (address[] memory result) {
457
+ uint256 len = IContractsRegister(contractsRegister).getPoolsCount();
458
+
459
+ uint256 index;
460
+ unchecked {
461
+ for (uint256 op = COUNT; op <= QUERY; ++op) {
462
+ if (op == QUERY && index == 0) {
463
+ break;
464
+ } else {
465
+ result = new address[](index);
466
+ index = 0;
467
+ }
468
+
469
+ for (uint256 i = 0; i < len; ++i) {
470
+ address _pool = IContractsRegister(contractsRegister).pools(i);
471
+
472
+ if (_isContractV3(_pool)) {
473
+ if (op == QUERY) result[index] = _pool;
474
+ ++index;
475
+ }
476
+ }
477
+ }
478
+ }
479
+ }
480
+
481
+ function _updatePrices(address creditManager, PriceOnDemand[] memory priceUpdates) internal {
482
+ uint256 len = priceUpdates.length;
483
+ unchecked {
484
+ for (uint256 i; i < len; ++i) {
485
+ address priceFeed =
486
+ IPriceOracleV3(ICreditManagerV3(creditManager).priceOracle()).priceFeeds(priceUpdates[i].token);
487
+ if (priceFeed == address(0)) revert PriceFeedDoesNotExistException();
488
+
489
+ IUpdatablePriceFeed(priceFeed).updatePrice(priceUpdates[i].callData);
490
+ }
491
+ }
492
+ }
493
+
494
+ function _getPriceFeedFailedList(address _pool, TokenBalance[] memory balances)
495
+ internal
496
+ view
497
+ returns (address[] memory priceFeedFailed)
498
+ {
499
+ uint256 len = balances.length;
500
+
501
+ IPriceOracleV3 priceOracle = IPriceOracleV3(ICreditManagerV3(_pool).priceOracle());
502
+
503
+ uint256 index;
504
+
505
+ /// It counts on the first iteration how many price feeds failed and then fill the array on the second iteration
506
+ for (uint256 op = COUNT; op <= QUERY; ++op) {
507
+ if (op == QUERY && index == 0) {
508
+ break;
509
+ } else {
510
+ priceFeedFailed = new address[](index);
511
+ index = 0;
512
+ }
513
+ unchecked {
514
+ for (uint256 i = 0; i < len; ++i) {
515
+ TokenBalance memory balance = balances[i];
516
+
517
+ if (balance.balance > 1 && balance.isEnabled) {
518
+ try IPriceFeed(priceOracle.priceFeeds(balance.token)).latestRoundData() returns (
519
+ uint80, int256, uint256, uint256, uint80
520
+ ) {} catch {
521
+ if (op == QUERY) priceFeedFailed[index] = balance.token;
522
+ ++index;
523
+ }
524
+ }
525
+ }
526
+ }
527
+ }
528
+ }
529
+
530
+ function _getQuotas(address _pool) internal view returns (QuotaInfo[] memory quotas) {
531
+ IPoolQuotaKeeperV3 pqk = IPoolQuotaKeeperV3(IPoolV3(_pool).poolQuotaKeeper());
532
+
533
+ address[] memory quotaTokens = pqk.quotedTokens();
534
+ uint256 len = quotaTokens.length;
535
+ quotas = new QuotaInfo[](len);
536
+ unchecked {
537
+ for (uint256 i; i < len; ++i) {
538
+ quotas[i].token = quotaTokens[i];
539
+ (quotas[i].rate,, quotas[i].quotaIncreaseFee, quotas[i].totalQuoted, quotas[i].limit) =
540
+ pqk.getTokenQuotaParams(quotaTokens[i]);
541
+ }
542
+ }
543
+ }
544
+
545
+ function getGaugesV3Data() external view returns (GaugeInfo[] memory result) {
546
+ address[] memory poolsV3 = _listPoolsV3();
547
+ uint256 len = poolsV3.length;
548
+ result = new GaugeInfo[](len);
549
+
550
+ unchecked {
551
+ for (uint256 i; i < len; ++i) {
552
+ GaugeInfo memory gaugeInfo = result[i];
553
+ IPoolQuotaKeeperV3 pqk = IPoolQuotaKeeperV3(IPoolV3(poolsV3[i]).poolQuotaKeeper());
554
+ address gauge = pqk.gauge();
555
+ gaugeInfo.addr = gauge;
556
+
557
+ address[] memory quotaTokens = pqk.quotedTokens();
558
+ uint256 quotaTokensLen = quotaTokens.length;
559
+ gaugeInfo.quotaParams = new GaugeQuotaParams[](quotaTokensLen);
560
+
561
+ for (uint256 j; j < quotaTokensLen; ++j) {
562
+ GaugeQuotaParams memory quotaParams = gaugeInfo.quotaParams[j];
563
+ address token = quotaTokens[j];
564
+ quotaParams.token = token;
565
+
566
+ (quotaParams.rate,, quotaParams.quotaIncreaseFee, quotaParams.totalQuoted, quotaParams.limit) =
567
+ pqk.getTokenQuotaParams(token);
568
+
569
+ (
570
+ quotaParams.minRate,
571
+ quotaParams.maxRate,
572
+ quotaParams.totalVotesLpSide,
573
+ quotaParams.totalVotesCaSide
574
+ ) = IGaugeV3(gauge).quotaRateParams(token);
575
+ }
576
+ }
577
+ }
578
+ }
579
+
580
+ function getGaugeVotes(address staker) external view returns (GaugeVote[] memory gaugeVotes) {
581
+ address[] memory poolsV3 = _listPoolsV3();
582
+ uint256 len = poolsV3.length;
583
+ uint256 index;
584
+
585
+ unchecked {
586
+ for (uint256 op = COUNT; op <= QUERY; ++op) {
587
+ if (op == QUERY && index == 0) {
588
+ break;
589
+ } else {
590
+ gaugeVotes = new GaugeVote[](index);
591
+ index = 0;
592
+ }
593
+ for (uint256 i; i < len; ++i) {
594
+ address[] memory quotaTokens;
595
+ address gauge;
596
+ {
597
+ IPoolQuotaKeeperV3 pqk = IPoolQuotaKeeperV3(IPoolV3(poolsV3[i]).poolQuotaKeeper());
598
+ gauge = pqk.gauge();
599
+
600
+ quotaTokens = pqk.quotedTokens();
601
+ }
602
+ uint256 quotaTokensLen = quotaTokens.length;
603
+
604
+ for (uint256 j; j < quotaTokensLen; ++j) {
605
+ address token = quotaTokens[j];
606
+
607
+ (uint96 votesLpSide, uint96 votesCaSide) = IGaugeV3(gauge).userTokenVotes(staker, token);
608
+
609
+ if (votesLpSide > 0 || votesCaSide > 0) {
610
+ if (op == QUERY) {
611
+ gaugeVotes[index] = GaugeVote({
612
+ gauge: gauge,
613
+ token: token,
614
+ totalVotesLpSide: votesLpSide,
615
+ totalVotesCaSide: votesCaSide
616
+ });
617
+ }
618
+ ++index;
619
+ }
620
+ }
621
+ }
622
+ }
623
+ }
624
+ }
625
+ }
@@ -0,0 +1,148 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Gearbox Protocol. Generalized leverage for DeFi protocols
3
+ // (c) Gearbox Holdings, 2023
4
+ pragma solidity ^0.8.17;
5
+
6
+ import {ScheduledWithdrawal} from "@gearbox-protocol/core-v3/contracts/interfaces/IWithdrawalManagerV3.sol";
7
+
8
+ struct TokenBalance {
9
+ address token;
10
+ uint256 balance;
11
+ bool isForbidden;
12
+ bool isEnabled;
13
+ bool isQuoted;
14
+ uint256 quota;
15
+ uint16 quotaRate;
16
+ }
17
+
18
+ struct QuotaInfo {
19
+ address token;
20
+ uint16 rate;
21
+ uint16 quotaIncreaseFee;
22
+ uint96 totalQuoted;
23
+ uint96 limit;
24
+ }
25
+
26
+ struct ContractAdapter {
27
+ address targetContract;
28
+ address adapter;
29
+ }
30
+
31
+ struct CreditAccountData {
32
+ // if not successful, priceFeedsNeeded are filled with the data
33
+ bool isSuccessful;
34
+ address[] priceFeedsNeeded;
35
+ address addr;
36
+ address borrower;
37
+ address creditManager;
38
+ address creditFacade;
39
+ address underlying;
40
+ uint256 debt;
41
+ uint256 cumulativeIndexNow;
42
+ uint256 cumulativeIndexLastUpdate;
43
+ uint128 cumulativeQuotaInterest;
44
+ uint256 accruedInterest;
45
+ uint256 accruedFees;
46
+ uint256 totalDebtUSD;
47
+ uint256 totalValue;
48
+ uint256 totalValueUSD;
49
+ uint256 twvUSD;
50
+ uint256 enabledTokensMask;
51
+ ///
52
+ uint256 healthFactor;
53
+ uint256 baseBorrowRate;
54
+ uint256 aggregatedBorrowRate;
55
+ TokenBalance[] balances;
56
+ uint64 since;
57
+ uint256 cfVersion;
58
+ // V3 features
59
+ uint40 expirationDate;
60
+ address[] activeBots;
61
+ uint256 maxApprovedBots;
62
+ ScheduledWithdrawal[2] schedultedWithdrawals;
63
+ }
64
+
65
+ struct CreditManagerData {
66
+ address addr;
67
+ uint256 cfVersion;
68
+ address creditFacade; // V2 only: address of creditFacade
69
+ address creditConfigurator; // V2 only: address of creditConfigurator
70
+ address underlying;
71
+ address pool;
72
+ uint256 totalDebt;
73
+ uint256 totalDebtLimit;
74
+ uint256 baseBorrowRate;
75
+ uint256 minDebt;
76
+ uint256 maxDebt;
77
+ uint256 availableToBorrow;
78
+ address[] collateralTokens;
79
+ ContractAdapter[] adapters;
80
+ uint256[] liquidationThresholds;
81
+ bool isDegenMode; // V2 only: true if contract is in Degen mode
82
+ address degenNFT; // V2 only: degenNFT, address(0) if not in degen mode
83
+ uint256 forbiddenTokenMask; // V2 only: mask which forbids some particular tokens
84
+ uint8 maxEnabledTokensLength; // V2 only: in V1 as many tokens as the CM can support (256)
85
+ uint16 feeInterest; // Interest fee protocol charges: fee = interest accrues * feeInterest
86
+ uint16 feeLiquidation; // Liquidation fee protocol charges: fee = totalValue * feeLiquidation
87
+ uint16 liquidationDiscount; // Miltiplier to get amount which liquidator should pay: amount = totalValue * liquidationDiscount
88
+ uint16 feeLiquidationExpired; // Liquidation fee protocol charges on expired accounts
89
+ uint16 liquidationDiscountExpired; // Multiplier for the amount the liquidator has to pay when closing an expired account
90
+ // V3 Fileds
91
+ QuotaInfo[] quotas;
92
+ bool isPaused;
93
+ }
94
+
95
+ struct CreditManagerDebtParams {
96
+ address creditManager;
97
+ uint256 borrowed;
98
+ uint256 limit;
99
+ uint256 availableToBorrow;
100
+ }
101
+
102
+ struct PoolData {
103
+ address addr;
104
+ address underlying;
105
+ address dieselToken;
106
+ ///
107
+ uint256 linearCumulativeIndex;
108
+ uint256 availableLiquidity;
109
+ uint256 expectedLiquidity;
110
+ //
111
+ uint256 totalBorrowed;
112
+ uint256 totalDebtLimit;
113
+ CreditManagerDebtParams[] creditManagerDebtParams;
114
+ uint256 totalAssets;
115
+ uint256 totalSupply;
116
+ uint256 supplyRate;
117
+ uint256 baseInterestRate;
118
+ uint256 dieselRate_RAY;
119
+ uint256 withdrawFee;
120
+ uint256 cumulativeIndex_RAY;
121
+ uint256 baseInterestIndexLU;
122
+ uint256 version;
123
+ QuotaInfo[] quotas;
124
+ }
125
+
126
+ struct GaugeQuotaParams {
127
+ address token;
128
+ uint16 minRate;
129
+ uint16 maxRate;
130
+ uint96 totalVotesLpSide;
131
+ uint96 totalVotesCaSide;
132
+ uint16 rate;
133
+ uint16 quotaIncreaseFee;
134
+ uint96 totalQuoted;
135
+ uint96 limit;
136
+ }
137
+
138
+ struct GaugeInfo {
139
+ address addr;
140
+ GaugeQuotaParams[] quotaParams;
141
+ }
142
+
143
+ struct GaugeVote {
144
+ address gauge;
145
+ address token;
146
+ uint96 totalVotesLpSide;
147
+ uint96 totalVotesCaSide;
148
+ }
@@ -0,0 +1,43 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Gearbox Protocol. Generalized leverage for DeFi protocols
3
+ // (c) Gearbox Holdings, 2022
4
+ pragma solidity ^0.8.10;
5
+
6
+ import {CreditAccountData, CreditManagerData, PoolData} from "../data/Types.sol";
7
+ import {IVersion} from "@gearbox-protocol/core-v2/contracts/interfaces/IVersion.sol";
8
+
9
+ interface IDataCompressorV2_10 is IVersion {
10
+ /// @dev Returns CreditAccountData for all opened accounts for particular borrower
11
+ /// @param borrower Borrower address
12
+ function getCreditAccountList(address borrower) external view returns (CreditAccountData[] memory);
13
+
14
+ /// @dev Returns whether the borrower has an open credit account with the credit manager
15
+ /// @param creditManager Credit manager to check
16
+ /// @param borrower Borrower to check
17
+ function hasOpenedCreditAccount(address creditManager, address borrower) external view returns (bool);
18
+
19
+ /// @dev Returns CreditAccountData for a particular Credit Account account, based on creditManager and borrower
20
+ /// @param _creditManager Credit manager address
21
+ /// @param borrower Borrower address
22
+ function getCreditAccountData(address _creditManager, address borrower)
23
+ external
24
+ view
25
+ returns (CreditAccountData memory);
26
+
27
+ /// @dev Returns CreditManagerData for all Credit Managers
28
+ function getCreditManagersList() external view returns (CreditManagerData[] memory);
29
+
30
+ /// @dev Returns CreditManagerData for a particular _creditManager
31
+ /// @param _creditManager CreditManager address
32
+ function getCreditManagerData(address _creditManager) external view returns (CreditManagerData memory);
33
+
34
+ /// @dev Returns PoolData for a particular pool
35
+ /// @param _pool Pool address
36
+ function getPoolData(address _pool) external view returns (PoolData memory);
37
+
38
+ /// @dev Returns PoolData for all registered pools
39
+ function getPoolsList() external view returns (PoolData[] memory);
40
+
41
+ /// @dev Returns the adapter address for a particular creditManager and targetContract
42
+ function getAdapter(address _creditManager, address _allowedContract) external view returns (address adapter);
43
+ }
@@ -0,0 +1,49 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Gearbox Protocol. Generalized leverage for DeFi protocols
3
+ // (c) Gearbox Holdings, 2022
4
+ pragma solidity ^0.8.10;
5
+
6
+ import {CreditAccountData, CreditManagerData, PoolData} from "../data/Types.sol";
7
+ import {IVersion} from "@gearbox-protocol/core-v2/contracts/interfaces/IVersion.sol";
8
+
9
+ struct PriceOnDemand {
10
+ address token;
11
+ bytes callData;
12
+ }
13
+
14
+ interface IDataCompressorV3_00 is IVersion {
15
+ /// @dev Returns CreditAccountData for all opened accounts for particular borrower
16
+ /// @param borrower Borrower address
17
+ /// @param priceUpdates Price updates for price on demand oracles
18
+ function getCreditAccountsByBorrower(address borrower, PriceOnDemand[] memory priceUpdates)
19
+ external
20
+ returns (CreditAccountData[] memory);
21
+
22
+ /// @dev Returns CreditAccountData for all opened accounts for particular borrower
23
+ /// @param creditManager Address
24
+ /// @param priceUpdates Price updates for price on demand oracles
25
+ function getCreditAccountsByCreditManager(address creditManager, PriceOnDemand[] memory priceUpdates)
26
+ external
27
+ returns (CreditAccountData[] memory);
28
+
29
+ /// @dev Returns CreditAccountData for a particular Credit Account account, based on creditManager and borrower
30
+ /// @param creditAccount Address of credit account
31
+ /// @param priceUpdates Price updates for price on demand oracles
32
+ function getCreditAccountData(address creditAccount, PriceOnDemand[] memory priceUpdates)
33
+ external
34
+ returns (CreditAccountData memory);
35
+
36
+ /// @dev Returns CreditManagerData for all Credit Managers
37
+ function getCreditManagersV3List() external view returns (CreditManagerData[] memory);
38
+
39
+ /// @dev Returns CreditManagerData for a particular _creditManager
40
+ /// @param creditManager CreditManager address
41
+ function getCreditManagerData(address creditManager) external view returns (CreditManagerData memory);
42
+
43
+ /// @dev Returns PoolData for a particular pool
44
+ /// @param _pool Pool address
45
+ function getPoolData(address _pool) external view returns (PoolData memory);
46
+
47
+ /// @dev Returns PoolData for all registered pools
48
+ function getPoolsV3List() external view returns (PoolData[] memory);
49
+ }
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@gearbox-protocol/periphery-v3",
3
+ "version": "1.0.2",
4
+ "main": "index.js",
5
+ "repository": "git@github.com:Gearbox-protocol/periphery-v3.git",
6
+ "author": "Mikael <26343374+0xmikko@users.noreply.github.com>",
7
+ "license": "MIT",
8
+ "files": [
9
+ "contracts"
10
+ ],
11
+ "scripts": {
12
+ "prepare": "husky install",
13
+ "prettier": "forge fmt",
14
+ "prettier:ci": "forge fmt"
15
+ },
16
+ "devDependencies": {
17
+ "@1inch/solidity-utils": "^2.2.27",
18
+ "@commitlint/cli": "^17.6.3",
19
+ "@commitlint/config-conventional": "17.6.0",
20
+ "@gearbox-protocol/core-v2": "1.19.0-base.14",
21
+ "@gearbox-protocol/core-v3": "^1.36.5",
22
+ "@gearbox-protocol/oracles-v3": "^1.7.2",
23
+ "@gearbox-protocol/sdk-gov": "^1.5.10",
24
+ "@openzeppelin/contracts": "4.8.3",
25
+ "husky": "^8.0.3",
26
+ "lint-staged": "^13.0.3",
27
+ "prettier": "^3.0.3"
28
+ },
29
+ "prettier": "@gearbox-protocol/prettier-config",
30
+ "lint-staged": {
31
+ "*.sol": "forge fmt",
32
+ "*.{json,md}": "prettier --write"
33
+ }
34
+ }