@gearbox-protocol/periphery-v3 1.7.0-next.36 → 1.7.0-next.38

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.
@@ -3,13 +3,13 @@
3
3
  // (c) Gearbox Holdings, 2024
4
4
  pragma solidity ^0.8.17;
5
5
 
6
+ import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol";
6
7
  import {AdapterType} from "@gearbox-protocol/sdk-gov/contracts/AdapterType.sol";
7
- import {ContractAdapter} from "../types/MarketData.sol";
8
+ import {AdapterState} from "../types/CreditSuiteData.sol";
8
9
  import {IAdapterCompressor} from "../interfaces/IAdapterCompressor.sol";
9
10
  import {ICreditConfiguratorV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditConfiguratorV3.sol";
10
11
  import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
11
12
  import {IStateSerializer} from "../interfaces/IStateSerializer.sol";
12
- import {IVersion} from "../interfaces/IVersion.sol";
13
13
 
14
14
  interface ILegacyAdapter {
15
15
  function _gearboxAdapterVersion() external view returns (uint16);
@@ -61,22 +61,20 @@ contract AdapterCompressor is IAdapterCompressor {
61
61
  // TODO: should add equalizer as well
62
62
  }
63
63
 
64
- function getContractAdapters(address creditManager) external view returns (ContractAdapter[] memory adapters) {
64
+ function getAdapters(address creditManager) external view returns (AdapterState[] memory adapters) {
65
65
  ICreditConfiguratorV3 creditConfigurator =
66
66
  ICreditConfiguratorV3(ICreditManagerV3(creditManager).creditConfigurator());
67
67
 
68
68
  address[] memory allowedAdapters = creditConfigurator.allowedAdapters();
69
69
  uint256 len = allowedAdapters.length;
70
70
 
71
- adapters = new ContractAdapter[](len);
72
- bytes memory stateSerialised;
73
-
71
+ adapters = new AdapterState[](len);
74
72
  unchecked {
75
73
  for (uint256 i = 0; i < len; ++i) {
76
74
  address adapter = allowedAdapters[i];
77
75
  adapters[i].baseParams.addr = adapter;
78
- try IVersion(adapter).contractType() returns (bytes32 adapterType) {
79
- adapters[i].baseParams.contractType = adapterType;
76
+ try IVersion(adapter).contractType() returns (bytes32 contractType_) {
77
+ adapters[i].baseParams.contractType = contractType_;
80
78
  } catch {
81
79
  try ILegacyAdapter(adapter)._gearboxAdapterType() returns (uint8 adapterType) {
82
80
  adapters[i].baseParams.contractType = contractTypes[adapterType];
@@ -7,19 +7,19 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
7
7
  import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
8
8
  import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
9
9
 
10
- import {IContractsRegister} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IContractsRegister.sol";
11
10
  import {ICreditAccountV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditAccountV3.sol";
11
+ import {ICreditFacadeV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditFacadeV3.sol";
12
12
  import {
13
13
  CollateralCalcTask,
14
14
  CollateralDebtData,
15
15
  ICreditManagerV3
16
16
  } from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
17
17
  import {IPoolQuotaKeeperV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IPoolQuotaKeeperV3.sol";
18
- import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol";
19
18
  import {PERCENTAGE_FACTOR} from "@gearbox-protocol/core-v3/contracts/libraries/Constants.sol";
20
19
  import {SanityCheckTrait} from "@gearbox-protocol/core-v3/contracts/traits/SanityCheckTrait.sol";
21
20
  import {ICreditAccountCompressor} from "../interfaces/ICreditAccountCompressor.sol";
22
21
 
22
+ import {IContractsRegister} from "@gearbox-protocol/governance/contracts/interfaces/extensions/IContractsRegister.sol";
23
23
  import {IAddressProvider} from "@gearbox-protocol/governance/contracts/interfaces/IAddressProvider.sol";
24
24
  import {IMarketConfigurator} from "@gearbox-protocol/governance/contracts/interfaces/IMarketConfigurator.sol";
25
25
  import {IMarketConfiguratorFactory} from
@@ -29,7 +29,8 @@ import {
29
29
  NO_VERSION_CONTROL
30
30
  } from "@gearbox-protocol/governance/contracts/libraries/ContractLiterals.sol";
31
31
 
32
- import {CreditAccountData, CreditAccountFilter, MarketFilter, TokenInfo} from "../types/CreditAccountState.sol";
32
+ import {CreditAccountData, TokenInfo} from "../types/CreditAccountState.sol";
33
+ import {CreditAccountFilter, MarketFilter} from "../types/Filters.sol";
33
34
 
34
35
  import {Contains} from "../libraries/Contains.sol";
35
36
 
@@ -49,12 +50,12 @@ contract CreditAccountCompressor is ICreditAccountCompressor, SanityCheckTrait {
49
50
 
50
51
  address public immutable marketConfiguratorFactory;
51
52
 
52
- /// @notice Thrown when address provider is not a contract or does not implement `marketConfigurators()`
53
+ /// @notice Thrown when address provider is not a contract
53
54
  error InvalidAddressProviderException();
54
55
 
55
56
  /// @notice Constructor
56
57
  /// @param addressProvider_ Address provider contract address
57
- constructor(address addressProvider_) nonZeroAddress(addressProvider) {
58
+ constructor(address addressProvider_) nonZeroAddress(addressProvider_) {
58
59
  if (addressProvider_.code.length == 0) {
59
60
  revert InvalidAddressProviderException();
60
61
  }
@@ -269,6 +270,7 @@ contract CreditAccountCompressor is ICreditAccountCompressor, SanityCheckTrait {
269
270
  data.creditFacade = ICreditManagerV3(creditManager).creditFacade();
270
271
  data.underlying = ICreditManagerV3(creditManager).underlying();
271
272
  data.owner = ICreditManagerV3(creditManager).getBorrowerOrRevert(creditAccount);
273
+ data.expirationDate = ICreditFacadeV3(creditManager).expirationDate();
272
274
 
273
275
  CollateralDebtData memory cdd =
274
276
  ICreditManagerV3(creditManager).calcDebtAndCollateral(creditAccount, CollateralCalcTask.DEBT_ONLY);
@@ -369,7 +371,9 @@ contract CreditAccountCompressor is ICreditAccountCompressor, SanityCheckTrait {
369
371
 
370
372
  /// @dev Credit managers discovery
371
373
  function _getCreditManagers(MarketFilter memory filter) internal view returns (address[] memory creditManagers) {
372
- address[] memory configurators = IMarketConfiguratorFactory(marketConfiguratorFactory).getMarketConfigurators();
374
+ address[] memory configurators = filter.configurators.length != 0
375
+ ? filter.configurators
376
+ : IMarketConfiguratorFactory(marketConfiguratorFactory).getMarketConfigurators();
373
377
 
374
378
  // rough estimate of maximum number of credit managers
375
379
  uint256 max;
@@ -383,26 +387,17 @@ contract CreditAccountCompressor is ICreditAccountCompressor, SanityCheckTrait {
383
387
  creditManagers = new address[](max);
384
388
  uint256 num;
385
389
  for (uint256 i; i < configurators.length; ++i) {
386
- if (filter.curators.length != 0) {
387
- if (!filter.curators.contains(Ownable(configurators[i]).owner())) continue;
388
- }
389
-
390
390
  address cr = IMarketConfigurator(configurators[i]).contractsRegister();
391
391
  address[] memory managers = IContractsRegister(cr).getCreditManagers();
392
392
  for (uint256 j; j < managers.length; ++j) {
393
- // we're only concerned with v3 contracts
394
- uint256 ver = IVersion(managers[j]).version();
395
- if (ver < 3_00 || ver > 3_99) continue;
396
-
397
- if (filter.pools.length != 0) {
398
- if (!filter.pools.contains(ICreditManagerV3(managers[j]).pool())) continue;
399
- }
400
-
401
- if (filter.underlying != address(0)) {
402
- if (ICreditManagerV3(managers[j]).underlying() != filter.underlying) continue;
393
+ address manager = managers[j];
394
+ // FIXME: there's room for optimization that allows to avoid scanning over all configurators
395
+ if (filter.pools.length != 0 && !filter.pools.contains(ICreditManagerV3(manager).pool())) continue;
396
+ if (filter.underlying != address(0) && ICreditManagerV3(manager).underlying() != filter.underlying) {
397
+ continue;
403
398
  }
404
399
 
405
- creditManagers[num++] = managers[j];
400
+ creditManagers[num++] = manager;
406
401
  }
407
402
  }
408
403
 
@@ -0,0 +1,91 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Gearbox Protocol. Generalized leverage for DeFi protocols
3
+ // (c) Gearbox Foundation, 2024.
4
+ pragma solidity ^0.8.23;
5
+
6
+ import {ICreditConfiguratorV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditConfiguratorV3.sol";
7
+ import {CreditFacadeV3} from "@gearbox-protocol/core-v3/contracts/credit/CreditFacadeV3.sol";
8
+ import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
9
+
10
+ import {BaseLib} from "../libraries/BaseLib.sol";
11
+
12
+ import {BaseParams, BaseState} from "../types/BaseState.sol";
13
+ import {CreditFacadeState} from "../types/CreditFacadeState.sol";
14
+ import {CollateralToken, CreditManagerState} from "../types/CreditManagerState.sol";
15
+ import {CreditSuiteData} from "../types/CreditSuiteData.sol";
16
+
17
+ import {AdapterCompressor} from "./AdapterCompressor.sol";
18
+
19
+ contract CreditSuiteCompressor {
20
+ AdapterCompressor adapterCompressor;
21
+
22
+ constructor() {
23
+ adapterCompressor = new AdapterCompressor();
24
+ }
25
+
26
+ function getCreditSuiteData(address creditManager) public view returns (CreditSuiteData memory result) {
27
+ result.creditManager = getCreditManagerState(creditManager);
28
+ result.creditFacade = getCreditFacadeState(ICreditManagerV3(creditManager).creditFacade());
29
+ result.creditConfigurator = BaseLib.getBaseState(
30
+ ICreditManagerV3(creditManager).creditConfigurator(), "CREDIT_CONFIGURATOR", address(0)
31
+ );
32
+
33
+ result.adapters = adapterCompressor.getAdapters(creditManager);
34
+ }
35
+
36
+ /// @dev Returns CreditManagerData for a particular _cm
37
+ /// @param _cm CreditManager address
38
+ function getCreditManagerState(address _cm) public view returns (CreditManagerState memory result) {
39
+ ICreditManagerV3 creditManager = ICreditManagerV3(_cm);
40
+ ICreditConfiguratorV3 creditConfigurator = ICreditConfiguratorV3(creditManager.creditConfigurator());
41
+ CreditFacadeV3 creditFacade = CreditFacadeV3(creditManager.creditFacade());
42
+
43
+ result.baseParams = BaseLib.getBaseParams(_cm, "CREDIT_MANAGER", address(0));
44
+ // string name;
45
+ result.name = ICreditManagerV3(_cm).name();
46
+
47
+ // address accountFactory;
48
+ result.accountFactory = creditManager.accountFactory();
49
+ // address underlying;
50
+ result.underlying = creditManager.underlying();
51
+ // address pool;
52
+ result.pool = creditManager.pool();
53
+ // address creditFacade;
54
+ result.creditFacade = address(creditFacade);
55
+ // address creditConfigurator;
56
+ result.creditConfigurator = address(creditConfigurator);
57
+ // uint8 maxEnabledTokens;
58
+ result.maxEnabledTokens = creditManager.maxEnabledTokens();
59
+
60
+ uint256 collateralTokensCount = creditManager.collateralTokensCount();
61
+ result.collateralTokens = new CollateralToken[](collateralTokensCount);
62
+ for (uint256 i; i < collateralTokensCount; ++i) {
63
+ (address token, uint16 lt) = creditManager.collateralTokenByMask(1 << i);
64
+ result.collateralTokens[i] = CollateralToken(token, lt);
65
+ }
66
+
67
+ (
68
+ result.feeInterest,
69
+ result.feeLiquidation,
70
+ result.liquidationDiscount,
71
+ result.feeLiquidationExpired,
72
+ result.liquidationDiscountExpired
73
+ ) = creditManager.fees();
74
+ }
75
+
76
+ /// @dev Returns CreditManagerData for a particular _cm
77
+ /// @param _cf CreditFacade address
78
+ function getCreditFacadeState(address _cf) public view returns (CreditFacadeState memory result) {
79
+ CreditFacadeV3 creditFacade = CreditFacadeV3(_cf);
80
+
81
+ result.baseParams = BaseLib.getBaseParams(_cf, "CREDIT_FACADE", address(0));
82
+ result.expirable = creditFacade.expirable();
83
+ result.degenNFT = creditFacade.degenNFT();
84
+ result.expirationDate = creditFacade.expirationDate();
85
+ result.maxDebtPerBlockMultiplier = creditFacade.maxDebtPerBlockMultiplier();
86
+ result.botList = creditFacade.botList();
87
+ (result.minDebt, result.maxDebt) = creditFacade.debtLimits();
88
+ result.forbiddenTokenMask = creditFacade.forbiddenTokenMask();
89
+ result.isPaused = creditFacade.paused();
90
+ }
91
+ }
@@ -5,31 +5,37 @@ pragma solidity ^0.8.17;
5
5
 
6
6
  import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
7
7
 
8
+ import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol";
8
9
  import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
9
- import {IPoolV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IPoolV3.sol";
10
10
  import {IPoolQuotaKeeperV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IPoolQuotaKeeperV3.sol";
11
- import {IContractsRegister} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IContractsRegister.sol";
12
- import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol";
11
+ import {IPoolV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IPoolV3.sol";
13
12
 
13
+ import {IACL} from "@gearbox-protocol/governance/contracts/interfaces/extensions/IACL.sol";
14
+ import {IContractsRegister} from "@gearbox-protocol/governance/contracts/interfaces/extensions/IContractsRegister.sol";
14
15
  import {IAddressProvider} from "@gearbox-protocol/governance/contracts/interfaces/IAddressProvider.sol";
15
16
  import {IMarketConfigurator} from "@gearbox-protocol/governance/contracts/interfaces/IMarketConfigurator.sol";
16
17
  import {IMarketConfiguratorFactory} from
17
18
  "@gearbox-protocol/governance/contracts/interfaces/IMarketConfiguratorFactory.sol";
18
19
  import {
19
20
  AP_MARKET_CONFIGURATOR_FACTORY,
20
- NO_VERSION_CONTROL
21
+ NO_VERSION_CONTROL,
22
+ ROLE_EMERGENCY_LIQUIDATOR,
23
+ ROLE_PAUSABLE_ADMIN,
24
+ ROLE_UNPAUSABLE_ADMIN
21
25
  } from "@gearbox-protocol/governance/contracts/libraries/ContractLiterals.sol";
22
26
 
23
27
  import {Contains} from "../libraries/Contains.sol";
24
28
 
25
- import {MarketFilter} from "../types/CreditAccountState.sol";
29
+ import {MarketFilter} from "../types/Filters.sol";
26
30
 
27
- import {PoolCompressorV3} from "./PoolCompressor.sol";
31
+ import {CreditSuiteCompressor} from "./CreditSuiteCompressor.sol";
32
+ import {PoolCompressor} from "./PoolCompressor.sol";
28
33
  import {PriceFeedCompressor} from "./PriceFeedCompressor.sol";
29
34
  import {TokenCompressor} from "./TokenCompressor.sol";
30
35
 
31
36
  import {BaseParams} from "../types/BaseState.sol";
32
- import {MarketData, CreditManagerData} from "../types/MarketData.sol";
37
+ import {CreditSuiteData} from "../types/CreditSuiteData.sol";
38
+ import {MarketData} from "../types/MarketData.sol";
33
39
  import {TokenData} from "../types/TokenData.sol";
34
40
  import {PoolState} from "../types/PoolState.sol";
35
41
  import {PriceOracleState} from "../types/PriceOracleState.sol";
@@ -45,33 +51,35 @@ contract MarketCompressor is IMarketCompressor {
45
51
  uint256 public constant version = 3_10;
46
52
  bytes32 public constant contractType = "MARKET_COMPRESSOR";
47
53
 
48
- /// @notice Address provider contract address
49
54
  address public immutable addressProvider;
50
-
51
55
  address public immutable marketConfiguratorFactory;
52
56
 
57
+ PoolCompressor poolCompressor;
53
58
  TokenCompressor tokenCompressor;
54
59
  PriceFeedCompressor priceOracleCompressor;
55
- PoolCompressorV3 poolCompressor;
60
+ CreditSuiteCompressor creditSuiteCompressor;
56
61
 
57
- error CreditManagerIsNotV3Exception();
62
+ struct Pool {
63
+ address addr;
64
+ address configurator;
65
+ }
58
66
 
59
67
  constructor(address addressProvider_, address priceOracleCompressorAddress) {
60
68
  addressProvider = addressProvider_;
61
69
  marketConfiguratorFactory =
62
70
  IAddressProvider(addressProvider_).getAddressOrRevert(AP_MARKET_CONFIGURATOR_FACTORY, NO_VERSION_CONTROL);
63
71
 
72
+ poolCompressor = new PoolCompressor();
64
73
  tokenCompressor = new TokenCompressor();
65
- poolCompressor = new PoolCompressorV3();
74
+ creditSuiteCompressor = new CreditSuiteCompressor();
66
75
  priceOracleCompressor = PriceFeedCompressor(priceOracleCompressorAddress);
67
76
  }
68
77
 
69
78
  function getMarkets(MarketFilter memory filter) external view returns (MarketData[] memory result) {
70
- address[] memory pools = _getPools(filter);
79
+ Pool[] memory pools = _getPools(filter);
71
80
  result = new MarketData[](pools.length);
72
-
73
- for (uint256 i = 0; i < pools.length; i++) {
74
- result[i] = getMarketData(pools[i]);
81
+ for (uint256 i; i < pools.length; ++i) {
82
+ result[i] = getMarketData(pools[i].addr, pools[i].configurator);
75
83
  }
76
84
  }
77
85
 
@@ -80,13 +88,13 @@ contract MarketCompressor is IMarketCompressor {
80
88
  view
81
89
  returns (BaseParams[] memory updatablePriceFeeds)
82
90
  {
83
- address[] memory pools = _getPools(filter);
91
+ Pool[] memory pools = _getPools(filter);
84
92
  uint256 numPools = pools.length;
85
93
  PriceOracleState[] memory poStates = new PriceOracleState[](numPools);
86
94
  uint256 numUpdatable;
87
95
  for (uint256 i; i < numPools; ++i) {
88
- address[] memory tokens = _getTokens(pools[i]);
89
- address priceOracle = _getPriceOracle(poolCompressor.getPoolState(pools[i]));
96
+ address[] memory tokens = _getTokens(pools[i].addr);
97
+ address priceOracle = _getPriceOracle(pools[i].addr, pools[i].configurator);
90
98
  poStates[i] = priceOracleCompressor.getPriceOracleState(priceOracle, tokens);
91
99
  for (uint256 j; j < poStates[i].priceFeedStructure.length; ++j) {
92
100
  if (poStates[i].priceFeedStructure[j].updatable) ++numUpdatable;
@@ -104,8 +112,17 @@ contract MarketCompressor is IMarketCompressor {
104
112
  }
105
113
  }
106
114
 
107
- function getMarketData(address pool) public view returns (MarketData memory result) {
108
- result.acl = IPoolV3(pool).acl();
115
+ function getMarketData(address pool) external view returns (MarketData memory result) {
116
+ // After full migration to v3.1.x governance system, pool's market configurator will be the owner of its ACL.
117
+ // Before that, however, there's no way to recover it unless it is provided directly or with market filter.
118
+ return getMarketData(pool, Ownable(IPoolV3(pool).acl()).owner());
119
+ }
120
+
121
+ function getMarketData(address pool, address configurator) public view returns (MarketData memory result) {
122
+ result.acl = IMarketConfigurator(configurator).acl();
123
+ result.contractsRegister = IMarketConfigurator(configurator).contractsRegister();
124
+ result.treasury = IMarketConfigurator(configurator).treasury();
125
+
109
126
  result.pool = poolCompressor.getPoolState(pool);
110
127
  result.poolQuotaKeeper = poolCompressor.getPoolQuotaKeeperState(result.pool.poolQuotaKeeper);
111
128
  result.rateKeeper = poolCompressor.getRateKeeperState(result.poolQuotaKeeper.rateKeeper);
@@ -117,20 +134,25 @@ contract MarketCompressor is IMarketCompressor {
117
134
  result.tokens[i] = tokenCompressor.getTokenInfo(tokens[i]);
118
135
  }
119
136
 
120
- // creditManager
121
- uint256 len = result.pool.creditManagerDebtParams.length;
122
- result.creditManagers = new CreditManagerData[](len);
123
- for (uint256 i = 0; i < len; i++) {
124
- result.creditManagers[i] =
125
- poolCompressor.getCreditManagerData(result.pool.creditManagerDebtParams[i].creditManager);
137
+ address[] memory creditManagers = IContractsRegister(result.contractsRegister).getCreditManagers(pool);
138
+ uint256 numCreditManagers = creditManagers.length;
139
+ result.creditManagers = new CreditSuiteData[](numCreditManagers);
140
+ for (uint256 i; i < numCreditManagers; ++i) {
141
+ result.creditManagers[i] = creditSuiteCompressor.getCreditSuiteData(creditManagers[i]);
126
142
  }
127
143
 
128
- address priceOracle = _getPriceOracle(result.pool);
129
- result.priceOracleData = priceOracleCompressor.getPriceOracleState(priceOracle, tokens);
144
+ result.priceOracleData = priceOracleCompressor.getPriceOracleState(_getPriceOracle(pool, configurator), tokens);
145
+ result.lossPolicy = poolCompressor.getLossPolicyState(_getLossPolicy(pool, configurator));
146
+
147
+ result.configurator = configurator;
148
+ result.pausableAdmins = IACL(result.acl).getRoleHolders(ROLE_PAUSABLE_ADMIN);
149
+ result.unpausableAdmins = IACL(result.acl).getRoleHolders(ROLE_UNPAUSABLE_ADMIN);
150
+ result.emergencyLiquidators = IACL(result.acl).getRoleHolders(ROLE_EMERGENCY_LIQUIDATOR);
151
+
152
+ // TODO: add zappers
130
153
  }
131
154
 
132
155
  function _getTokens(address pool) internal view returns (address[] memory tokens) {
133
- // under proper configuration, equivalent to price oracle's `getTokens`
134
156
  address quotaKeeper = IPoolV3(pool).poolQuotaKeeper();
135
157
  address[] memory quotedTokens = IPoolQuotaKeeperV3(quotaKeeper).quotedTokens();
136
158
  uint256 numTokens = quotedTokens.length;
@@ -141,18 +163,21 @@ contract MarketCompressor is IMarketCompressor {
141
163
  }
142
164
  }
143
165
 
144
- function _getPriceOracle(PoolState memory ps) internal view returns (address) {
145
- // TODO: read from market configurator instead once structure is known
146
- if (ps.creditManagerDebtParams.length == 0) {
147
- return address(0);
148
- }
166
+ function _getPriceOracle(address pool, address configurator) internal view returns (address) {
167
+ address contractsRegister = IMarketConfigurator(configurator).contractsRegister();
168
+ return IContractsRegister(contractsRegister).getPriceOracle(pool);
169
+ }
149
170
 
150
- return ICreditManagerV3(ps.creditManagerDebtParams[0].creditManager).priceOracle();
171
+ function _getLossPolicy(address pool, address configurator) internal view returns (address) {
172
+ address contractsRegister = IMarketConfigurator(configurator).contractsRegister();
173
+ return IContractsRegister(contractsRegister).getLossLiquidator(pool);
151
174
  }
152
175
 
153
176
  /// @dev Pools discovery
154
- function _getPools(MarketFilter memory filter) internal view returns (address[] memory pools) {
155
- address[] memory configurators = IMarketConfiguratorFactory(marketConfiguratorFactory).getMarketConfigurators();
177
+ function _getPools(MarketFilter memory filter) internal view returns (Pool[] memory pools) {
178
+ address[] memory configurators = filter.configurators.length != 0
179
+ ? filter.configurators
180
+ : IMarketConfiguratorFactory(marketConfiguratorFactory).getMarketConfigurators();
156
181
 
157
182
  // rough estimate of maximum number of credit pools
158
183
  uint256 max;
@@ -163,29 +188,18 @@ contract MarketCompressor is IMarketCompressor {
163
188
 
164
189
  // allocate the array with maximum potentially needed size (total number of credit pools can be assumed
165
190
  // to be relatively small and the function is only called once, so memory expansion cost is not an issue)
166
- pools = new address[](max);
191
+ pools = new Pool[](max);
167
192
  uint256 num;
168
193
 
169
194
  for (uint256 i; i < configurators.length; ++i) {
170
- if (filter.curators.length != 0) {
171
- if (!filter.curators.contains(Ownable(configurators[i]).owner())) continue;
172
- }
173
-
174
195
  address contractsRegister = IMarketConfigurator(configurators[i]).contractsRegister();
175
196
  address[] memory poolsMC = IContractsRegister(contractsRegister).getPools();
176
197
  for (uint256 j; j < poolsMC.length; ++j) {
177
- address currentPool = poolsMC[j];
178
- if (filter.pools.length != 0) {
179
- if (!filter.pools.contains(currentPool)) continue;
180
- }
181
-
182
- if (filter.underlying != address(0)) {
183
- if (IPoolV3(currentPool).asset() != filter.underlying) {
184
- continue;
185
- }
186
- }
187
-
188
- pools[num++] = currentPool;
198
+ address pool = poolsMC[j];
199
+ // FIXME: that's kinda weird to filter pools by pools
200
+ if (filter.pools.length != 0 && !filter.pools.contains(pool)) continue;
201
+ if (filter.underlying != address(0) && IPoolV3(pool).asset() != filter.underlying) continue;
202
+ pools[num++] = Pool({addr: pool, configurator: configurators[i]});
189
203
  }
190
204
  }
191
205
 
@@ -1,16 +1,11 @@
1
1
  // SPDX-License-Identifier: BUSL-1.1
2
2
  // Gearbox Protocol. Generalized leverage for DeFi protocols
3
- // (c) Gearbox Holdings, 2023
4
- pragma solidity ^0.8.10;
5
- pragma experimental ABIEncoderV2;
3
+ // (c) Gearbox Holdings, 2024
4
+ pragma solidity ^0.8.23;
6
5
 
7
6
  import {PoolV3} from "@gearbox-protocol/core-v3/contracts/pool/PoolV3.sol";
8
7
  import {IPoolQuotaKeeperV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IPoolQuotaKeeperV3.sol";
9
8
  import {IGaugeV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IGaugeV3.sol";
10
- import {IVersion} from "../interfaces/IVersion.sol";
11
- import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
12
- import {ICreditConfiguratorV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditConfiguratorV3.sol";
13
- import {CreditFacadeV3} from "@gearbox-protocol/core-v3/contracts/credit/CreditFacadeV3.sol";
14
9
 
15
10
  // State & Params
16
11
  import {BaseParams, BaseState} from "../types/BaseState.sol";
@@ -18,25 +13,18 @@ import {PoolState, CreditManagerDebtParams} from "../types/PoolState.sol";
18
13
  import {PoolQuotaKeeperState, QuotaTokenParams} from "../types/PoolQuotaKeeperState.sol";
19
14
  import {RateKeeperState, Rate} from "../types/RateKeeperState.sol";
20
15
 
21
- import {CreditManagerData} from "../types/MarketData.sol";
22
- import {CreditManagerState} from "../types/CreditManagerState.sol";
23
- import {CreditFacadeState} from "../types/CreditFacadeState.sol";
24
-
25
- import {PERCENTAGE_FACTOR, RAY} from "@gearbox-protocol/core-v3/contracts/libraries/Constants.sol";
16
+ import {RAY} from "@gearbox-protocol/core-v3/contracts/libraries/Constants.sol";
26
17
  import {IRateKeeper} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IRateKeeper.sol";
27
18
 
28
19
  // Serializers
29
20
  import {BaseLib} from "../libraries/BaseLib.sol";
30
-
31
21
  import {GaugeSerializer} from "../serializers/pool/GaugeSerializer.sol";
32
22
  import {LinearInterestRateModelSerializer} from "../serializers/pool/LinearInterestRateModelSerializer.sol";
33
23
 
34
- import {AdapterCompressor} from "./AdapterCompressor.sol";
35
-
36
24
  /// @title Pool compressor
37
25
  /// @notice Collects data from pool related contracts
38
26
  /// Do not use for data from data compressor for state-changing functions
39
- contract PoolCompressorV3 {
27
+ contract PoolCompressor {
40
28
  // Contract version
41
29
  uint256 public constant version = 3_10;
42
30
  bytes32 public constant contractType = "POOL_COMPRESSOR";
@@ -44,12 +32,9 @@ contract PoolCompressorV3 {
44
32
  address public immutable gaugeSerializer;
45
33
  address public immutable linearInterestRateModelSerializer;
46
34
 
47
- AdapterCompressor adapterCompressor;
48
-
49
35
  constructor() {
50
36
  gaugeSerializer = address(new GaugeSerializer());
51
37
  linearInterestRateModelSerializer = address(new LinearInterestRateModelSerializer());
52
- adapterCompressor = new AdapterCompressor();
53
38
  }
54
39
 
55
40
  function getPoolState(address pool) public view returns (PoolState memory result) {
@@ -76,7 +61,6 @@ contract PoolCompressorV3 {
76
61
  // address interestRateModel;
77
62
  result.interestRateModel = _pool.interestRateModel();
78
63
 
79
- result.treasury = _pool.treasury();
80
64
  //
81
65
  // address underlying;
82
66
  result.underlying = _pool.underlyingToken();
@@ -93,16 +77,10 @@ contract PoolCompressorV3 {
93
77
  // uint256 dieselRate;
94
78
  result.dieselRate = _pool.convertToAssets(RAY);
95
79
 
96
- // uint256 totalBorrowed;
97
- result.totalBorrowed = _pool.totalBorrowed();
98
- // uint256 totalAssets;
99
- result.totalAssets = _pool.totalAssets();
100
80
  // uint256 supplyRate;
101
81
  result.supplyRate = _pool.supplyRate();
102
82
  // uint256 withdrawFee;
103
83
  result.withdrawFee = _pool.withdrawFee();
104
- // uint256 totalDebtLimit;
105
- result.totalDebtLimit = _pool.totalDebtLimit();
106
84
 
107
85
  // updates
108
86
  // uint256 baseInterestIndexLU;
@@ -122,21 +100,26 @@ contract PoolCompressorV3 {
122
100
  // uint256 baseInterestIndexLU;
123
101
  result.baseInterestIndexLU = _pool.baseInterestIndexLU();
124
102
 
103
+ // uint256 totalBorrowed;
104
+ result.totalBorrowed = _pool.totalBorrowed();
105
+ // uint256 totalDebtLimit;
106
+ result.totalDebtLimit = _pool.totalDebtLimit();
107
+
125
108
  // CreditManagerDebtParams[] creditManagerDebtParams;
126
109
  address[] memory creditManagers = _pool.creditManagers();
127
110
  uint256 len = creditManagers.length;
128
111
  result.creditManagerDebtParams = new CreditManagerDebtParams[](len);
129
112
 
130
- unchecked {
131
- for (uint256 i; i < len; ++i) {
132
- address creditManager = creditManagers[i];
133
- result.creditManagerDebtParams[i] = CreditManagerDebtParams({
134
- creditManager: creditManager,
135
- borrowed: _pool.creditManagerBorrowed(creditManager),
136
- limit: _pool.creditManagerDebtLimit(creditManager)
137
- });
138
- }
113
+ for (uint256 i; i < len; ++i) {
114
+ address creditManager = creditManagers[i];
115
+ result.creditManagerDebtParams[i] = CreditManagerDebtParams({
116
+ creditManager: creditManager,
117
+ borrowed: _pool.creditManagerBorrowed(creditManager),
118
+ limit: _pool.creditManagerDebtLimit(creditManager),
119
+ available: _pool.creditManagerBorrowable(creditManager)
120
+ });
139
121
  }
122
+
140
123
  // bool isPaused;
141
124
  result.isPaused = _pool.paused();
142
125
  }
@@ -192,109 +175,11 @@ contract PoolCompressorV3 {
192
175
  }
193
176
  }
194
177
 
195
- /// @dev Returns CreditManagerData for a particular _cm
196
- /// @param _cm CreditManager address
197
- function getCreditManagerState(address _cm) public view returns (CreditManagerState memory result) {
198
- ICreditManagerV3 creditManager = ICreditManagerV3(_cm);
199
- ICreditConfiguratorV3 creditConfigurator = ICreditConfiguratorV3(creditManager.creditConfigurator());
200
- CreditFacadeV3 creditFacade = CreditFacadeV3(creditManager.creditFacade());
201
-
202
- result.baseParams = BaseLib.getBaseParams(_cm, "CREDIT_MANAGER", address(0));
203
- // string name;
204
- result.name = ICreditManagerV3(_cm).name();
205
-
206
- // address accountFactory;
207
- result.accountFactory = creditManager.accountFactory();
208
- // address underlying;
209
- result.underlying = creditManager.underlying();
210
- // address pool;
211
- result.pool = creditManager.pool();
212
- // address creditFacade;
213
- result.creditFacade = address(creditFacade);
214
- // address creditConfigurator;
215
- result.creditConfigurator = address(creditConfigurator);
216
- // address priceOracle;
217
- result.priceOracle = creditManager.priceOracle();
218
- // uint8 maxEnabledTokens;
219
- result.maxEnabledTokens = creditManager.maxEnabledTokens();
220
- // address[] collateralTokens;
221
- // uint16[] liquidationThresholds;
222
- {
223
- uint256 collateralTokenCount = creditManager.collateralTokensCount();
224
-
225
- result.collateralTokens = new address[](collateralTokenCount);
226
- result.liquidationThresholds = new uint16[](collateralTokenCount);
227
-
228
- unchecked {
229
- for (uint256 i = 0; i < collateralTokenCount; ++i) {
230
- (result.collateralTokens[i], result.liquidationThresholds[i]) =
231
- creditManager.collateralTokenByMask(1 << i);
232
- }
233
- }
234
- }
235
- // uint16 feeInterest; // Interest fee protocol charges: fee = interest accrues * feeInterest
236
- // uint16 feeLiquidation; // Liquidation fee protocol charges: fee = totalValue * feeLiquidation
237
- // uint16 liquidationDiscount; // Miltiplier to get amount which liquidator should pay: amount = totalValue * liquidationDiscount
238
- // uint16 feeLiquidationExpired; // Liquidation fee protocol charges on expired accounts
239
- // uint16 liquidationDiscountExpired; // Multiplier for the amount the liquidator has to pay when closing an expired account
240
- {
241
- (
242
- result.feeInterest,
243
- result.feeLiquidation,
244
- result.liquidationDiscount,
245
- result.feeLiquidationExpired,
246
- result.liquidationDiscountExpired
247
- ) = creditManager.fees();
248
- }
249
- }
250
-
251
- /// @dev Returns CreditManagerData for a particular _cm
252
- /// @param _cf CreditFacade address
253
- function getCreditFacadeState(address _cf) public view returns (CreditFacadeState memory result) {
254
- CreditFacadeV3 creditFacade = CreditFacadeV3(_cf);
255
-
256
- result.baseParams = BaseLib.getBaseParams(_cf, "CREDIT_FACADE", address(0));
257
- //
258
- result.maxQuotaMultiplier = creditFacade.maxQuotaMultiplier();
259
- // address treasury;
260
- // result.treasury = creditFacade.treasury();
261
- // bool expirable;
262
- result.expirable = creditFacade.expirable();
263
- // address degenNFT;
264
- result.degenNFT = creditFacade.degenNFT();
265
- // uint40 expirationDate;
266
- result.expirationDate = creditFacade.expirationDate();
267
- // uint8 maxDebtPerBlockMultiplier;
268
- result.maxDebtPerBlockMultiplier = creditFacade.maxDebtPerBlockMultiplier();
269
- // address botList;
270
- result.botList = creditFacade.botList();
271
- // uint256 minDebt;
272
- // uint256 maxDebt;
273
- (result.minDebt, result.maxDebt) = creditFacade.debtLimits();
274
- // uint256 forbiddenTokenMask;
275
- result.forbiddenTokenMask = creditFacade.forbiddenTokenMask();
276
- // address lossLiquidator;
277
- // result.lossLiquidator = creditFacade.lossLiquidator();
278
- // bool isPaused;
279
- result.isPaused = creditFacade.paused();
178
+ function getInterestRateModelState(address addr) public view returns (BaseState memory) {
179
+ return BaseLib.getBaseState(addr, "IRM_LINEAR", linearInterestRateModelSerializer);
280
180
  }
281
181
 
282
- function getInterestRateModelState(address addr) public view returns (BaseState memory baseState) {
283
- baseState = BaseLib.getBaseState(addr, "INTEREST_MODEL", linearInterestRateModelSerializer);
284
- }
285
-
286
- function getCreditManagerData(address creditManager) public view returns (CreditManagerData memory result) {
287
- result.creditManager = getCreditManagerState(creditManager);
288
- result.creditFacade = getCreditFacadeState(ICreditManagerV3(creditManager).creditFacade());
289
- result.creditConfigurator = BaseLib.getBaseState(
290
- ICreditManagerV3(creditManager).creditConfigurator(), "CREDIT_CONFIGURATOR", address(0)
291
- );
292
-
293
- PoolV3 _pool = PoolV3(result.creditManager.pool);
294
- result.totalDebt = _pool.creditManagerBorrowed(creditManager);
295
- result.totalDebtLimit = _pool.creditManagerDebtLimit(creditManager);
296
- result.availableToBorrow = _pool.creditManagerBorrowable(creditManager);
297
-
298
- result.adapters = adapterCompressor.getContractAdapters(creditManager);
182
+ function getLossPolicyState(address lossPolicy) public view returns (BaseState memory) {
183
+ return BaseLib.getBaseState(lossPolicy, "LP_ALIASED", address(0));
299
184
  }
300
185
  }
@@ -3,12 +3,12 @@
3
3
  // (c) Gearbox Foundation, 2024.
4
4
  pragma solidity ^0.8.17;
5
5
 
6
+ import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol";
6
7
  import {AddressIsNotContractException} from "@gearbox-protocol/core-v3/contracts/interfaces/IExceptions.sol";
7
8
  import {IPriceOracleV3, PriceFeedParams} from "@gearbox-protocol/core-v3/contracts/interfaces/IPriceOracleV3.sol";
8
9
  import {IPriceFeed, IUpdatablePriceFeed} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IPriceFeed.sol";
9
10
  import {IPriceFeedCompressor} from "../interfaces/IPriceFeedCompressor.sol";
10
11
  import {PriceFeedType} from "@gearbox-protocol/sdk-gov/contracts/PriceFeedType.sol";
11
- import {IVersion} from "../interfaces/IVersion.sol";
12
12
 
13
13
  import {BaseLib} from "../libraries/BaseLib.sol";
14
14
 
@@ -197,10 +197,10 @@ contract PriceFeedCompressor is IPriceFeedCompressor {
197
197
  // --------- //
198
198
 
199
199
  /// @dev Sets `serializer` for `priceFeedType`
200
- function _setSerializer(bytes32 contractType, address serializer) internal {
201
- if (serializers[contractType] != serializer) {
202
- serializers[contractType] = serializer;
203
- emit SetSerializer(contractType, serializer);
200
+ function _setSerializer(bytes32 contractType_, address serializer) internal {
201
+ if (serializers[contractType_] != serializer) {
202
+ serializers[contractType_] = serializer;
203
+ emit SetSerializer(contractType_, serializer);
204
204
  }
205
205
  }
206
206
 
@@ -251,8 +251,8 @@ contract PriceFeedCompressor is IPriceFeedCompressor {
251
251
 
252
252
  /// @dev Returns price feed tree node, see `PriceFeedTreeNode` for detailed description of struct fields
253
253
  function _getPriceFeedTreeNode(address priceFeed) internal view returns (PriceFeedTreeNode memory data) {
254
- try IVersion(priceFeed).contractType() returns (bytes32 contractType) {
255
- data.baseParams.contractType = contractType;
254
+ try IVersion(priceFeed).contractType() returns (bytes32 contractType_) {
255
+ data.baseParams.contractType = contractType_;
256
256
  } catch {
257
257
  try ImplementsPriceFeedType(priceFeed).priceFeedType() returns (uint8 priceFeedType) {
258
258
  data.baseParams.contractType = contractTypes[priceFeedType];
@@ -3,10 +3,10 @@
3
3
  // (c) Gearbox Holdings, 2024
4
4
  pragma solidity ^0.8.10;
5
5
 
6
- import {ContractAdapter} from "../types/MarketData.sol";
6
+ import {AdapterState} from "../types/CreditSuiteData.sol";
7
7
  import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol";
8
8
 
9
9
  /// @title Adapter compressor 3.1
10
10
  interface IAdapterCompressor is IVersion {
11
- function getContractAdapters(address creditManager) external view returns (ContractAdapter[] memory result);
11
+ function getAdapters(address creditManager) external view returns (AdapterState[] memory result);
12
12
  }
@@ -4,7 +4,8 @@
4
4
  pragma solidity ^0.8.17;
5
5
 
6
6
  import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol";
7
- import {CreditAccountData, CreditAccountFilter, MarketFilter, TokenInfo} from "../types/CreditAccountState.sol";
7
+ import {CreditAccountData, TokenInfo} from "../types/CreditAccountState.sol";
8
+ import {CreditAccountFilter, MarketFilter} from "../types/Filters.sol";
8
9
 
9
10
  /// @title Credit account compressor
10
11
  /// @notice Allows to fetch data on all credit accounts matching certain criteria in an efficient manner
@@ -3,18 +3,16 @@
3
3
  // (c) Gearbox Holdings, 2024
4
4
  pragma solidity ^0.8.10;
5
5
 
6
+ import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol";
6
7
  import {BaseParams} from "../types/BaseState.sol";
8
+ import {MarketFilter} from "../types/Filters.sol";
7
9
  import {MarketData} from "../types/MarketData.sol";
8
- import {PoolState} from "../types/PoolState.sol";
9
- import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol";
10
- import {MarketFilter} from "../types/CreditAccountState.sol";
11
10
 
12
- /// @title Data compressor 3.0.
13
- /// @notice Collects data from various contracts for use in the dApp
14
- /// Do not use for data from data compressor for state-changing functions
15
11
  interface IMarketCompressor is IVersion {
16
12
  function getMarketData(address pool) external view returns (MarketData memory result);
17
13
 
14
+ function getMarketData(address pool, address configurator) external view returns (MarketData memory result);
15
+
18
16
  function getMarkets(MarketFilter memory filter) external view returns (MarketData[] memory result);
19
17
 
20
18
  function getUpdatablePriceFeeds(MarketFilter memory filter)
@@ -3,8 +3,8 @@
3
3
  // (c) Gearbox Foundation, 2024.
4
4
  pragma solidity ^0.8.17;
5
5
 
6
+ import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol";
6
7
  import {BaseParams, BaseState} from "../types/BaseState.sol";
7
- import {IVersion} from "../interfaces/IVersion.sol";
8
8
  import {IStateSerializer} from "../interfaces/IStateSerializer.sol";
9
9
  import {IStateSerializerLegacy} from "../interfaces/IStateSerializerLegacy.sol";
10
10
 
@@ -0,0 +1,65 @@
1
+ // SPDX-License-Identifier: UNLICENSED
2
+ // Gearbox Protocol. Generalized leverage for DeFi protocols
3
+ // (c) Gearbox Foundation, 2024.
4
+ pragma solidity ^0.8.23;
5
+
6
+ import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol";
7
+ import {ICreditFacadeV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditFacadeV3.sol";
8
+ import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
9
+ import {IPoolV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IPoolV3.sol";
10
+
11
+ import {IContractsRegisterLegacy} from
12
+ "@gearbox-protocol/governance/contracts/market/legacy/MarketConfiguratorLegacy.sol";
13
+ import {ACL} from "@gearbox-protocol/governance/contracts/market/ACL.sol";
14
+ import {ContractsRegister} from "@gearbox-protocol/governance/contracts/market/ContractsRegister.sol";
15
+
16
+ /// @dev Extremely dumbed-down version of `MarketConfiguratorLegacy` that is just enough to let compressors work
17
+ contract MarketConfigurator {
18
+ string public name;
19
+ address public immutable acl;
20
+ address public immutable treasury;
21
+ address public immutable contractsRegister;
22
+
23
+ constructor(string memory name_, address acl_, address contractsRegister_, address treasury_) {
24
+ name = name_;
25
+ acl = acl_;
26
+ contractsRegister = address(new ContractsRegister(address(new ACL())));
27
+ treasury = treasury_;
28
+
29
+ address[] memory pools = IContractsRegisterLegacy(contractsRegister_).getPools();
30
+ uint256 numPools = pools.length;
31
+ for (uint256 i; i < numPools; ++i) {
32
+ address pool = pools[i];
33
+ if (!_isV3Contract(pool)) continue;
34
+
35
+ address[] memory creditManagers = IPoolV3(pool).creditManagers();
36
+ uint256 numCreditManagers = creditManagers.length;
37
+ if (numCreditManagers == 0) continue;
38
+
39
+ address priceOracle = _priceOracle(creditManagers[0]);
40
+ // NOTE: v3.0.x contracts don't have loss policies set so we don't bother with them here
41
+ address lossPolicy = address(1);
42
+
43
+ ContractsRegister(contractsRegister).registerMarket(pool, priceOracle, lossPolicy);
44
+ for (uint256 j; j < numCreditManagers; ++j) {
45
+ ContractsRegister(contractsRegister).registerCreditSuite(creditManagers[j]);
46
+ }
47
+ }
48
+ }
49
+
50
+ function _isV3Contract(address contract_) internal view returns (bool) {
51
+ try IVersion(contract_).version() returns (uint256 version_) {
52
+ return version_ >= 300 && version_ < 400;
53
+ } catch {
54
+ return false;
55
+ }
56
+ }
57
+
58
+ function _priceOracle(address creditManager) internal view returns (address) {
59
+ return ICreditManagerV3(creditManager).priceOracle();
60
+ }
61
+
62
+ function _lossLiquidator(address creditManager) internal view returns (address) {
63
+ return ICreditFacadeV3(ICreditManagerV3(creditManager).creditFacade()).lossLiquidator();
64
+ }
65
+ }
@@ -15,13 +15,15 @@ import {
15
15
  NO_VERSION_CONTROL
16
16
  } from "@gearbox-protocol/governance/contracts/libraries/ContractLiterals.sol";
17
17
 
18
- import {IACLLegacy as IACL} from "@gearbox-protocol/governance/contracts/market/legacy/MarketConfiguratorLegacy.sol";
19
- import {IContractsRegisterExt} from "./interfaces/IContractsRegisterExt.sol";
18
+ import {ACL} from "@gearbox-protocol/governance/contracts/market/ACL.sol";
19
+ import {IACLLegacy} from "@gearbox-protocol/governance/contracts/market/legacy/MarketConfiguratorLegacy.sol";
20
+ import {IContractsRegister} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IContractsRegister.sol";
20
21
 
21
22
  abstract contract ForkTest is Test {
22
23
  IAddressProvider addressProvider;
23
- IACL acl;
24
- IContractsRegisterExt register;
24
+ ACL acl;
25
+ IACLLegacy aclLegacy;
26
+ IContractsRegister register;
25
27
  address configurator;
26
28
 
27
29
  modifier onlyFork() {
@@ -40,8 +42,25 @@ abstract contract ForkTest is Test {
40
42
  }
41
43
 
42
44
  addressProvider = IAddressProvider(vm.envAddress("FORK_ADDRESS_PROVIDER"));
43
- acl = IACL(addressProvider.getAddressOrRevert(AP_ACL, NO_VERSION_CONTROL));
44
- register = IContractsRegisterExt(addressProvider.getAddressOrRevert(AP_CONTRACTS_REGISTER, NO_VERSION_CONTROL));
45
- configurator = Ownable(address(acl)).owner();
45
+
46
+ acl = new ACL();
47
+ aclLegacy = IACLLegacy(addressProvider.getAddressOrRevert(AP_ACL, NO_VERSION_CONTROL));
48
+ register = IContractsRegister(addressProvider.getAddressOrRevert(AP_CONTRACTS_REGISTER, NO_VERSION_CONTROL));
49
+ configurator = Ownable(address(aclLegacy)).owner();
50
+ acl.transferOwnership(configurator);
51
+ vm.prank(configurator);
52
+ acl.acceptOwnership();
53
+ }
54
+
55
+ function _grantRole(bytes32 role, address account) internal {
56
+ acl.grantRole(role, account);
57
+ if (role == "PAUSABLE_ADMIN") IACLLegacy(aclLegacy).addPausableAdmin(account);
58
+ else if (role == "UNPAUSABLE_ADMIN") IACLLegacy(aclLegacy).addUnpausableAdmin(account);
59
+ }
60
+
61
+ function _revokeRole(bytes32 role, address account) internal {
62
+ acl.revokeRole(role, account);
63
+ if (role == "PAUSABLE_ADMIN") IACLLegacy(aclLegacy).removePausableAdmin(account);
64
+ else if (role == "UNPAUSABLE_ADMIN") IACLLegacy(aclLegacy).removeUnpausableAdmin(account);
46
65
  }
47
66
  }
@@ -22,8 +22,8 @@ contract MultiPauseTest is ForkTest {
22
22
  admin = makeAddr("ADMIN");
23
23
 
24
24
  vm.startPrank(configurator);
25
- acl.addPausableAdmin(admin);
26
- acl.addPausableAdmin(address(multiPause));
25
+ _grantRole("PAUSABLE_ADMIN", admin);
26
+ _grantRole("PAUSABLE_ADMIN", address(multiPause));
27
27
  vm.stopPrank();
28
28
  }
29
29
 
@@ -9,6 +9,7 @@ pragma solidity ^0.8.17;
9
9
  /// @param creditFacade Facade connected to account's credit manager
10
10
  /// @param underlying Credit manager's underlying token
11
11
  /// @param owner Credit account's owner
12
+ /// @param expirationDate Expiration timestamp, in case facade is expirable
12
13
  /// @param enabledTokensMask Bitmask of tokens enabled on credit account as collateral
13
14
  /// @param debt Credit account's debt principal in underlying
14
15
  /// @param accruedInterest Base and quota interest accrued on the credit account
@@ -28,6 +29,7 @@ struct CreditAccountData {
28
29
  address creditFacade;
29
30
  address underlying;
30
31
  address owner;
32
+ uint40 expirationDate;
31
33
  uint256 enabledTokensMask;
32
34
  uint256 debt;
33
35
  uint256 accruedInterest;
@@ -41,30 +43,6 @@ struct CreditAccountData {
41
43
  TokenInfo[] tokens;
42
44
  }
43
45
 
44
- /// @notice Credit account filters
45
- /// @param owner If set, match credit accounts owned by given address
46
- /// @param includeZeroDebt If set, also match accounts with zero debt
47
- /// @param minHealthFactor If set, only return accounts with health factor above this value
48
- /// @param maxHealthFactor If set, only return accounts with health factor below this value
49
- /// @param reverting If set, only match accounts with reverting collateral calculation
50
- struct CreditAccountFilter {
51
- address owner;
52
- bool includeZeroDebt;
53
- uint16 minHealthFactor;
54
- uint16 maxHealthFactor;
55
- bool reverting;
56
- }
57
-
58
- /// @notice Credit manager filters
59
- /// @param curators If set, match credit managers managed by given curators
60
- /// @param pools If set, match credit managers connected to given pools
61
- /// @param underlying If set, match credit managers with given underlying
62
- struct MarketFilter {
63
- address[] curators;
64
- address[] pools;
65
- address underlying;
66
- }
67
-
68
46
  /// @notice Info on credit account's holdings of a token
69
47
  /// @param token Token address
70
48
  /// @param mask Token mask in the credit manager
@@ -7,17 +7,14 @@ import {BaseParams} from "./BaseState.sol";
7
7
 
8
8
  struct CreditFacadeState {
9
9
  BaseParams baseParams;
10
- uint256 maxQuotaMultiplier;
11
10
  address creditManager;
12
- address treasury;
13
- bool expirable;
14
11
  address degenNFT;
12
+ address botList;
13
+ bool expirable;
15
14
  uint40 expirationDate;
16
15
  uint8 maxDebtPerBlockMultiplier;
17
- address botList;
18
16
  uint256 minDebt;
19
17
  uint256 maxDebt;
20
18
  uint256 forbiddenTokenMask;
21
- address lossLiquidator;
22
19
  bool isPaused;
23
20
  }
@@ -5,6 +5,11 @@ pragma solidity ^0.8.17;
5
5
 
6
6
  import {BaseParams} from "./BaseState.sol";
7
7
 
8
+ struct CollateralToken {
9
+ address token;
10
+ uint16 liquidationThreshold;
11
+ }
12
+
8
13
  struct CreditManagerState {
9
14
  BaseParams baseParams;
10
15
  string name;
@@ -13,13 +18,11 @@ struct CreditManagerState {
13
18
  address pool;
14
19
  address creditFacade;
15
20
  address creditConfigurator;
16
- address priceOracle;
17
21
  uint8 maxEnabledTokens;
18
- address[] collateralTokens;
19
- uint16[] liquidationThresholds;
20
- uint16 feeInterest; // Interest fee protocol charges: fee = interest accrues * feeInterest
21
- uint16 feeLiquidation; // Liquidation fee protocol charges: fee = totalValue * feeLiquidation
22
- uint16 liquidationDiscount; // Miltiplier to get amount which liquidator should pay: amount = totalValue * liquidationDiscount
23
- uint16 feeLiquidationExpired; // Liquidation fee protocol charges on expired accounts
24
- uint16 liquidationDiscountExpired; // Multiplier for the amount the liquidator has to pay when closing an expired account
22
+ CollateralToken[] collateralTokens;
23
+ uint16 feeInterest;
24
+ uint16 feeLiquidation;
25
+ uint16 liquidationDiscount;
26
+ uint16 feeLiquidationExpired;
27
+ uint16 liquidationDiscountExpired;
25
28
  }
@@ -0,0 +1,20 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Gearbox Protocol. Generalized leverage for DeFi protocols
3
+ // (c) Gearbox Foundation, 2024.
4
+ pragma solidity ^0.8.23;
5
+
6
+ import {CreditManagerState} from "./CreditManagerState.sol";
7
+ import {CreditFacadeState} from "./CreditFacadeState.sol";
8
+ import {BaseState, BaseParams} from "./BaseState.sol";
9
+
10
+ struct AdapterState {
11
+ BaseParams baseParams;
12
+ address targetContract;
13
+ }
14
+
15
+ struct CreditSuiteData {
16
+ CreditFacadeState creditFacade;
17
+ CreditManagerState creditManager;
18
+ BaseState creditConfigurator;
19
+ AdapterState[] adapters;
20
+ }
@@ -0,0 +1,30 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Gearbox Protocol. Generalized leverage for DeFi protocols
3
+ // (c) Gearbox Foundation, 2024.
4
+ pragma solidity ^0.8.23;
5
+
6
+ // TODO: might need separate filters for markets and credit suites
7
+
8
+ /// @notice Credit account filters
9
+ /// @param owner If set, match credit accounts owned by given address
10
+ /// @param includeZeroDebt If set, also match accounts with zero debt
11
+ /// @param minHealthFactor If set, only return accounts with health factor above this value
12
+ /// @param maxHealthFactor If set, only return accounts with health factor below this value
13
+ /// @param reverting If set, only match accounts with reverting collateral calculation
14
+ struct CreditAccountFilter {
15
+ address owner;
16
+ bool includeZeroDebt;
17
+ uint16 minHealthFactor;
18
+ uint16 maxHealthFactor;
19
+ bool reverting;
20
+ }
21
+
22
+ /// @notice Credit manager filters
23
+ /// @param configurators If set, match credit managers by given market configurators
24
+ /// @param pools If set, match credit managers connected to given pools
25
+ /// @param underlying If set, match credit managers with given underlying
26
+ struct MarketFilter {
27
+ address[] configurators;
28
+ address[] pools;
29
+ address underlying;
30
+ }
@@ -3,57 +3,38 @@
3
3
  // (c) Gearbox Holdings, 2024
4
4
  pragma solidity ^0.8.17;
5
5
 
6
- import {ACLState} from "./ACLState.sol";
7
6
  import {PoolState} from "./PoolState.sol";
8
7
  import {PoolQuotaKeeperState} from "./PoolQuotaKeeperState.sol";
9
8
  import {RateKeeperState} from "./RateKeeperState.sol";
10
9
  import {PriceOracleState} from "./PriceOracleState.sol";
11
10
  import {CreditManagerState} from "./CreditManagerState.sol";
12
11
  import {CreditFacadeState} from "./CreditFacadeState.sol";
12
+ import {CreditSuiteData} from "./CreditSuiteData.sol";
13
13
  import {BaseState, BaseParams} from "./BaseState.sol";
14
14
  import {TokenData} from "./TokenData.sol";
15
15
 
16
16
  struct MarketData {
17
- // MarketConfigurator baseParams
18
- BaseParams baseParams;
19
- // Owner who manages market
20
- address owner;
17
+ // TODO: add risk curator once structure is figured
21
18
  address acl;
22
- // Syntax sugar ?
23
- // address underlying;
24
- // Risk curator name
25
- string name;
19
+ address contractsRegister;
20
+ address treasury;
26
21
  PoolState pool;
27
22
  PoolQuotaKeeperState poolQuotaKeeper;
28
23
  BaseState interestRateModel;
29
24
  RateKeeperState rateKeeper;
30
25
  PriceOracleState priceOracleData;
31
- TokenData[] tokens; // <- V3: collateral tokens, V3.1. from local price oracle
32
- CreditManagerData[] creditManagers;
33
- // ZappersInfo
34
- ZapperInfo[] zappers;
35
- // Roles
26
+ BaseState lossPolicy;
27
+ TokenData[] tokens;
28
+ CreditSuiteData[] creditManagers;
29
+ address configurator;
30
+ address[] pausableAdmins;
31
+ address[] unpausableAdmins;
36
32
  address[] emergencyLiquidators;
33
+ ZapperState[] zappers;
37
34
  }
38
- // LossLiquidatorPolicy
39
35
 
40
- struct ZapperInfo {
36
+ struct ZapperState {
41
37
  BaseParams baseParams;
42
38
  TokenData tokenIn;
43
39
  TokenData tokenOut;
44
40
  }
45
-
46
- struct ContractAdapter {
47
- BaseParams baseParams;
48
- address targetContract;
49
- }
50
-
51
- struct CreditManagerData {
52
- CreditFacadeState creditFacade;
53
- CreditManagerState creditManager;
54
- BaseState creditConfigurator;
55
- ContractAdapter[] adapters;
56
- uint256 totalDebt;
57
- uint256 totalDebtLimit;
58
- uint256 availableToBorrow;
59
- }
@@ -17,18 +17,16 @@ struct PoolState {
17
17
  // connected contracts
18
18
  address poolQuotaKeeper; // +
19
19
  address interestRateModel; // +
20
- address treasury; // +
21
20
  address underlying; // +
22
21
  uint256 availableLiquidity; // +
23
22
  uint256 expectedLiquidity; // +
24
23
  uint256 baseInterestIndex; // +
25
24
  uint256 baseInterestRate; // +
26
25
  uint256 dieselRate;
27
- uint256 totalBorrowed; // +
28
- uint256 totalAssets; // +
29
26
  uint256 supplyRate; // +
30
27
  uint256 withdrawFee; // +
31
28
  // Limits
29
+ uint256 totalBorrowed; // +
32
30
  uint256 totalDebtLimit; // +
33
31
  CreditManagerDebtParams[] creditManagerDebtParams; // +
34
32
  //
@@ -47,4 +45,5 @@ struct CreditManagerDebtParams {
47
45
  address creditManager;
48
46
  uint256 borrowed;
49
47
  uint256 limit;
48
+ uint256 available;
50
49
  }
@@ -31,6 +31,7 @@ struct PriceFeedMapEntry {
31
31
  uint32 stalenessPeriod;
32
32
  }
33
33
 
34
+ // TODO: revise fields
34
35
  /// @notice Represents a node in the price feed "tree"
35
36
  /// @param priceFeed Price feed address
36
37
  /// @param decimals Price feed's decimals (might not be equal to 8 for lower-level)
@@ -49,7 +50,6 @@ struct PriceFeedTreeNode {
49
50
  uint8 decimals;
50
51
  bool skipCheck;
51
52
  bool updatable;
52
- // TODO: better naming, underlying is confusing
53
53
  address[] underlyingFeeds;
54
54
  uint32[] underlyingStalenessPeriods;
55
55
  PriceFeedAnswer answer;
@@ -9,12 +9,3 @@ struct TokenData {
9
9
  string name;
10
10
  uint8 decimals;
11
11
  }
12
-
13
- /// 3 sources:
14
- /// "PriceOracleFather"
15
- /// Pools | on the fly in SDK
16
- /// Farming pools | on the fly in SDK
17
- /// subscribe on new token addition event
18
- ///
19
- /// POV3 -> POV3.1
20
- ///
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/periphery-v3",
3
- "version": "1.7.0-next.36",
3
+ "version": "1.7.0-next.38",
4
4
  "main": "index.js",
5
5
  "repository": "git@github.com:Gearbox-protocol/periphery-v3.git",
6
6
  "author": "Mikael <26343374+0xmikko@users.noreply.github.com>",
@@ -1,9 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- // Gearbox Protocol. Generalized leverage for DeFi protocols
3
- // (c) Gearbox Foundation, 2024.
4
- pragma solidity ^0.8.17;
5
-
6
- import {IVersion} from "./IVersion.sol";
7
- import {IStateSerializer} from "./IStateSerializer.sol";
8
-
9
- interface ITreasurySplitter is IVersion, IStateSerializer {}
@@ -1,13 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- // Gearbox Protocol. Generalized leverage for DeFi protocols
3
- // (c) Gearbox Foundation, 2024.
4
- pragma solidity ^0.8.17;
5
-
6
- /// @title Version interface
7
- /// @notice Defines contract version
8
- interface IVersion {
9
- /// @notice Contract version
10
- function version() external view returns (uint256);
11
-
12
- function contractType() external view returns (bytes32);
13
- }
@@ -1,15 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- // Gearbox Protocol. Generalized leverage for DeFi protocols
3
- // (c) Gearbox Holdings, 2024
4
- pragma solidity ^0.8.17;
5
-
6
- import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
7
-
8
- contract MarketManager is Ownable {
9
- address public riskCurator;
10
- /// PriceOracleStore priceOracleStore;
11
- address public pool;
12
-
13
- // @dev Updates PriceOracles on all connected credit managers
14
- function updatePriceOracle() external onlyOwner {}
15
- }
@@ -1,13 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- // Gearbox Protocol. Generalized leverage for DeFi protocols
3
- // (c) Gearbox Holdings, 2024
4
- pragma solidity ^0.8.17;
5
-
6
- struct ACLState {
7
- address addr;
8
- uint256 version;
9
- address owner;
10
- address[] pausableAdmins;
11
- address[] unpausableAdmins;
12
- bytes serializedParams;
13
- }