@gearbox-protocol/periphery-v3 1.7.0-next.25 → 1.7.0-next.27
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/contracts/compressors/MarketCompressor.sol +10 -1
- package/contracts/compressors/PoolCompressor.sol +34 -86
- package/contracts/compressors/PriceFeedCompressor.sol +59 -46
- package/contracts/interfaces/IPriceFeedCompressor.sol +1 -1
- package/contracts/libraries/BaseLib.sol +42 -0
- package/contracts/types/PriceOracleState.sol +4 -7
- package/package.json +1 -1
- package/contracts/types/ZapperRegisterState.sol +0 -10
|
@@ -22,7 +22,7 @@ import {TokenCompressor} from "./TokenCompressor.sol";
|
|
|
22
22
|
// // EXCEPTIONS
|
|
23
23
|
// import "@gearbox-protocol/core-v3/contracts/interfaces/IExceptions.sol";
|
|
24
24
|
|
|
25
|
-
import {MarketData} from "../types/MarketData.sol";
|
|
25
|
+
import {MarketData, CreditManagerData} from "../types/MarketData.sol";
|
|
26
26
|
import {TokenData} from "../types/TokenData.sol";
|
|
27
27
|
import {PoolState} from "../types/PoolState.sol";
|
|
28
28
|
|
|
@@ -84,6 +84,15 @@ contract MarketCompressor is IMarketCompressor {
|
|
|
84
84
|
result.tokens[i + 1] = tokenCompressor.getTokenInfo(tokens[i]);
|
|
85
85
|
underlyingAndTokens[i + 1] = tokens[i];
|
|
86
86
|
}
|
|
87
|
+
|
|
88
|
+
// creditManager
|
|
89
|
+
|
|
90
|
+
uint256 len = result.pool.creditManagerDebtParams.length;
|
|
91
|
+
result.creditManagers = new CreditManagerData[](len);
|
|
92
|
+
for (uint256 i = 0; i < len; i++) {
|
|
93
|
+
result.creditManagers[i] =
|
|
94
|
+
poolCompressor.getCreditManagerData(result.pool.creditManagerDebtParams[i].creditManager);
|
|
95
|
+
}
|
|
87
96
|
// How to query if no credit mangers are deployed?
|
|
88
97
|
result.priceOracleData = priceOracleCompressor.getPriceOracleState(priceOracle, underlyingAndTokens);
|
|
89
98
|
}
|
|
@@ -17,6 +17,8 @@ import {BaseParams, BaseState} from "../types/BaseState.sol";
|
|
|
17
17
|
import {PoolState, CreditManagerDebtParams} from "../types/PoolState.sol";
|
|
18
18
|
import {PoolQuotaKeeperState, QuotaTokenParams} from "../types/PoolQuotaKeeperState.sol";
|
|
19
19
|
import {RateKeeperState, Rate} from "../types/RateKeeperState.sol";
|
|
20
|
+
|
|
21
|
+
import {CreditManagerData} from "../types/MarketData.sol";
|
|
20
22
|
import {CreditManagerState} from "../types/CreditManagerState.sol";
|
|
21
23
|
import {CreditFacadeState} from "../types/CreditFacadeState.sol";
|
|
22
24
|
|
|
@@ -24,8 +26,8 @@ import {PERCENTAGE_FACTOR, RAY} from "@gearbox-protocol/core-v3/contracts/librar
|
|
|
24
26
|
import {IRateKeeper} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IRateKeeper.sol";
|
|
25
27
|
|
|
26
28
|
// Serializers
|
|
27
|
-
import {
|
|
28
|
-
|
|
29
|
+
import {BaseLib} from "../libraries/BaseLib.sol";
|
|
30
|
+
|
|
29
31
|
import {GaugeSerializer} from "../serializers/pool/GaugeSerializer.sol";
|
|
30
32
|
import {LinearInterestModelSerializer} from "../serializers/pool/LinearInterestModelSerializer.sol";
|
|
31
33
|
|
|
@@ -42,19 +44,15 @@ contract PoolCompressorV3 {
|
|
|
42
44
|
|
|
43
45
|
constructor() {
|
|
44
46
|
gaugeSerializer = address(new GaugeSerializer());
|
|
45
|
-
linearInterestModelSerializer = address(
|
|
46
|
-
new LinearInterestModelSerializer()
|
|
47
|
-
);
|
|
47
|
+
linearInterestModelSerializer = address(new LinearInterestModelSerializer());
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
function getPoolState(
|
|
51
|
-
address pool
|
|
52
|
-
) public view returns (PoolState memory result) {
|
|
50
|
+
function getPoolState(address pool) public view returns (PoolState memory result) {
|
|
53
51
|
PoolV3 _pool = PoolV3(pool);
|
|
54
52
|
//
|
|
55
53
|
// CONTRACT PARAMETERS
|
|
56
54
|
//
|
|
57
|
-
result.baseParams = getBaseParams(pool, "POOL", address(0));
|
|
55
|
+
result.baseParams = BaseLib.getBaseParams(pool, "POOL", address(0));
|
|
58
56
|
|
|
59
57
|
//
|
|
60
58
|
// ERC20 Properties
|
|
@@ -139,12 +137,10 @@ contract PoolCompressorV3 {
|
|
|
139
137
|
result.isPaused = _pool.paused();
|
|
140
138
|
}
|
|
141
139
|
|
|
142
|
-
function getPoolQuotaKeeperState(
|
|
143
|
-
address pqk
|
|
144
|
-
) external view returns (PoolQuotaKeeperState memory result) {
|
|
140
|
+
function getPoolQuotaKeeperState(address pqk) external view returns (PoolQuotaKeeperState memory result) {
|
|
145
141
|
IPoolQuotaKeeperV3 _pqk = IPoolQuotaKeeperV3(pqk);
|
|
146
142
|
|
|
147
|
-
result.baseParams = getBaseParams(pqk, "POOL_QUOTA_KEEPER", address(0));
|
|
143
|
+
result.baseParams = BaseLib.getBaseParams(pqk, "POOL_QUOTA_KEEPER", address(0));
|
|
148
144
|
|
|
149
145
|
// address rateKeeper;
|
|
150
146
|
result.rateKeeper = _pqk.gauge();
|
|
@@ -173,18 +169,14 @@ contract PoolCompressorV3 {
|
|
|
173
169
|
result.lastQuotaRateUpdate = _pqk.lastQuotaRateUpdate();
|
|
174
170
|
}
|
|
175
171
|
|
|
176
|
-
function getRateKeeperState(
|
|
177
|
-
address rateKeeper
|
|
178
|
-
) external view returns (RateKeeperState memory result) {
|
|
172
|
+
function getRateKeeperState(address rateKeeper) external view returns (RateKeeperState memory result) {
|
|
179
173
|
IRateKeeper _rateKeeper = IRateKeeper(rateKeeper);
|
|
180
174
|
|
|
181
175
|
bytes32 contractType;
|
|
182
176
|
|
|
183
|
-
result.baseParams = getBaseParams(rateKeeper, "GAUGE", gaugeSerializer);
|
|
177
|
+
result.baseParams = BaseLib.getBaseParams(rateKeeper, "GAUGE", gaugeSerializer);
|
|
184
178
|
|
|
185
|
-
IPoolQuotaKeeperV3 _pqk = IPoolQuotaKeeperV3(
|
|
186
|
-
PoolV3(_rateKeeper.pool()).poolQuotaKeeper()
|
|
187
|
-
);
|
|
179
|
+
IPoolQuotaKeeperV3 _pqk = IPoolQuotaKeeperV3(PoolV3(_rateKeeper.pool()).poolQuotaKeeper());
|
|
188
180
|
|
|
189
181
|
address[] memory quotaTokens = _pqk.quotedTokens();
|
|
190
182
|
uint256 quotaTokensLen = quotaTokens.length;
|
|
@@ -200,18 +192,12 @@ contract PoolCompressorV3 {
|
|
|
200
192
|
|
|
201
193
|
/// @dev Returns CreditManagerData for a particular _cm
|
|
202
194
|
/// @param _cm CreditManager address
|
|
203
|
-
function getCreditManagerState(
|
|
204
|
-
address _cm
|
|
205
|
-
) public view returns (CreditManagerState memory result) {
|
|
195
|
+
function getCreditManagerState(address _cm) public view returns (CreditManagerState memory result) {
|
|
206
196
|
ICreditManagerV3 creditManager = ICreditManagerV3(_cm);
|
|
207
|
-
ICreditConfiguratorV3 creditConfigurator = ICreditConfiguratorV3(
|
|
208
|
-
|
|
209
|
-
);
|
|
210
|
-
CreditFacadeV3 creditFacade = CreditFacadeV3(
|
|
211
|
-
creditManager.creditFacade()
|
|
212
|
-
);
|
|
197
|
+
ICreditConfiguratorV3 creditConfigurator = ICreditConfiguratorV3(creditManager.creditConfigurator());
|
|
198
|
+
CreditFacadeV3 creditFacade = CreditFacadeV3(creditManager.creditFacade());
|
|
213
199
|
|
|
214
|
-
result.baseParams = getBaseParams(_cm, "CREDIT_MANAGER", address(0));
|
|
200
|
+
result.baseParams = BaseLib.getBaseParams(_cm, "CREDIT_MANAGER", address(0));
|
|
215
201
|
// string name;
|
|
216
202
|
result.name = ICreditManagerV3(_cm).name();
|
|
217
203
|
|
|
@@ -232,18 +218,15 @@ contract PoolCompressorV3 {
|
|
|
232
218
|
// address[] collateralTokens;
|
|
233
219
|
// uint16[] liquidationThresholds;
|
|
234
220
|
{
|
|
235
|
-
uint256 collateralTokenCount = creditManager
|
|
236
|
-
.collateralTokensCount();
|
|
221
|
+
uint256 collateralTokenCount = creditManager.collateralTokensCount();
|
|
237
222
|
|
|
238
223
|
result.collateralTokens = new address[](collateralTokenCount);
|
|
239
224
|
result.liquidationThresholds = new uint16[](collateralTokenCount);
|
|
240
225
|
|
|
241
226
|
unchecked {
|
|
242
227
|
for (uint256 i = 0; i < collateralTokenCount; ++i) {
|
|
243
|
-
(
|
|
244
|
-
|
|
245
|
-
result.liquidationThresholds[i]
|
|
246
|
-
) = creditManager.collateralTokenByMask(1 << i);
|
|
228
|
+
(result.collateralTokens[i], result.liquidationThresholds[i]) =
|
|
229
|
+
creditManager.collateralTokenByMask(1 << i);
|
|
247
230
|
}
|
|
248
231
|
}
|
|
249
232
|
}
|
|
@@ -265,16 +248,14 @@ contract PoolCompressorV3 {
|
|
|
265
248
|
|
|
266
249
|
/// @dev Returns CreditManagerData for a particular _cm
|
|
267
250
|
/// @param _cf CreditFacade address
|
|
268
|
-
function getCreditFacadeState(
|
|
269
|
-
address _cf
|
|
270
|
-
) public view returns (CreditFacadeState memory result) {
|
|
251
|
+
function getCreditFacadeState(address _cf) public view returns (CreditFacadeState memory result) {
|
|
271
252
|
CreditFacadeV3 creditFacade = CreditFacadeV3(_cf);
|
|
272
253
|
|
|
273
|
-
result.baseParams = getBaseParams(_cf, "CREDIT_FACADE", address(0));
|
|
254
|
+
result.baseParams = BaseLib.getBaseParams(_cf, "CREDIT_FACADE", address(0));
|
|
274
255
|
//
|
|
275
256
|
result.maxQuotaMultiplier = creditFacade.maxQuotaMultiplier();
|
|
276
257
|
// address treasury;
|
|
277
|
-
result.treasury = creditFacade.treasury();
|
|
258
|
+
// result.treasury = creditFacade.treasury();
|
|
278
259
|
// bool expirable;
|
|
279
260
|
result.expirable = creditFacade.expirable();
|
|
280
261
|
// address degenNFT;
|
|
@@ -282,8 +263,7 @@ contract PoolCompressorV3 {
|
|
|
282
263
|
// uint40 expirationDate;
|
|
283
264
|
result.expirationDate = creditFacade.expirationDate();
|
|
284
265
|
// uint8 maxDebtPerBlockMultiplier;
|
|
285
|
-
result.maxDebtPerBlockMultiplier = creditFacade
|
|
286
|
-
.maxDebtPerBlockMultiplier();
|
|
266
|
+
result.maxDebtPerBlockMultiplier = creditFacade.maxDebtPerBlockMultiplier();
|
|
287
267
|
// address botList;
|
|
288
268
|
result.botList = creditFacade.botList();
|
|
289
269
|
// uint256 minDebt;
|
|
@@ -297,52 +277,20 @@ contract PoolCompressorV3 {
|
|
|
297
277
|
result.isPaused = creditFacade.paused();
|
|
298
278
|
}
|
|
299
279
|
|
|
300
|
-
function
|
|
301
|
-
|
|
302
|
-
bytes32 defaultContractType,
|
|
303
|
-
address legacySerializer
|
|
304
|
-
) public view returns (BaseParams memory baseParams) {
|
|
305
|
-
baseParams.addr = addr;
|
|
306
|
-
try IVersion(addr).contractType() returns (bytes32 contractType) {
|
|
307
|
-
baseParams.contractType = contractType;
|
|
308
|
-
} catch {
|
|
309
|
-
baseParams.version = 3_00;
|
|
310
|
-
baseParams.contractType = defaultContractType;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
baseParams.version = IVersion(addr).version();
|
|
314
|
-
try IStateSerializer(addr).serialize() returns (
|
|
315
|
-
bytes memory serializedParams
|
|
316
|
-
) {
|
|
317
|
-
baseParams.serializedParams = serializedParams;
|
|
318
|
-
} catch {
|
|
319
|
-
if (legacySerializer != address(0)) {
|
|
320
|
-
baseParams.serializedParams = IStateSerializerLegacy(
|
|
321
|
-
legacySerializer
|
|
322
|
-
).serialize(addr);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
280
|
+
function getInterestModelState(address addr) public view returns (BaseState memory baseState) {
|
|
281
|
+
baseState = BaseLib.getBaseState(addr, "INTEREST_MODEL", linearInterestModelSerializer);
|
|
325
282
|
}
|
|
326
283
|
|
|
327
|
-
function
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
baseState.baseParams = getBaseParams(
|
|
333
|
-
addr,
|
|
334
|
-
defaultContractType,
|
|
335
|
-
legacySerializer
|
|
284
|
+
function getCreditManagerData(address creditManager) public view returns (CreditManagerData memory result) {
|
|
285
|
+
result.creditManager = getCreditManagerState(creditManager);
|
|
286
|
+
result.creditFacade = getCreditFacadeState(ICreditManagerV3(creditManager).creditFacade());
|
|
287
|
+
result.creditConfigurator = BaseLib.getBaseState(
|
|
288
|
+
ICreditManagerV3(creditManager).creditConfigurator(), "CREDIT_CONFIGURATOR", address(0)
|
|
336
289
|
);
|
|
337
|
-
}
|
|
338
290
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
addr,
|
|
344
|
-
"INTEREST_MODEL",
|
|
345
|
-
linearInterestModelSerializer
|
|
346
|
-
);
|
|
291
|
+
PoolV3 _pool = PoolV3(result.creditManager.pool);
|
|
292
|
+
result.totalDebt = _pool.creditManagerBorrowed(creditManager);
|
|
293
|
+
result.totalDebtLimit = _pool.creditManagerDebtLimit(creditManager);
|
|
294
|
+
result.availableToBorrow = _pool.creditManagerBorrowable(creditManager);
|
|
347
295
|
}
|
|
348
296
|
}
|
|
@@ -10,6 +10,8 @@ import {IPriceFeedCompressor} from "../interfaces/IPriceFeedCompressor.sol";
|
|
|
10
10
|
import {PriceFeedType} from "@gearbox-protocol/sdk-gov/contracts/PriceFeedType.sol";
|
|
11
11
|
import {IVersion} from "../interfaces/IVersion.sol";
|
|
12
12
|
|
|
13
|
+
import {BaseLib} from "../libraries/BaseLib.sol";
|
|
14
|
+
|
|
13
15
|
import {IStateSerializerLegacy} from "../interfaces/IStateSerializerLegacy.sol";
|
|
14
16
|
import {IStateSerializer} from "../interfaces/IStateSerializer.sol";
|
|
15
17
|
import {NestedPriceFeeds} from "../libraries/NestedPriceFeeds.sol";
|
|
@@ -45,32 +47,54 @@ contract PriceFeedCompressor is IPriceFeedCompressor {
|
|
|
45
47
|
|
|
46
48
|
/// @notice Map of state serializers for different price feed types
|
|
47
49
|
/// @dev Serializers only apply to feeds that don't implement `IStateSerializer` themselves
|
|
48
|
-
mapping(
|
|
50
|
+
mapping(bytes32 => address) public serializers;
|
|
51
|
+
|
|
52
|
+
mapping(uint8 => bytes32) public contractTypes;
|
|
49
53
|
|
|
50
54
|
/// @notice Constructor
|
|
51
55
|
/// @dev Sets serializers for existing price feed types.
|
|
52
56
|
/// It is recommended to implement `IStateSerializer` in new price feeds.
|
|
53
57
|
constructor() {
|
|
54
58
|
address lpSerializer = address(new LPPriceFeedSerializer());
|
|
59
|
+
|
|
60
|
+
contractTypes[uint8(PriceFeedType.ZERO_ORACLE)] = "PF_ZERO_ORACLE";
|
|
61
|
+
contractTypes[uint8(PriceFeedType.CHAINLINK_ORACLE)] = "PF_CHAINLINK_ORACLE";
|
|
62
|
+
contractTypes[uint8(PriceFeedType.COMPOSITE_ORACLE)] = "PF_COMPOSITE_ORACLE";
|
|
63
|
+
|
|
64
|
+
contractTypes[uint8(PriceFeedType.BALANCER_STABLE_LP_ORACLE)] = "PF_BALANCER_STABLE_LP_ORACLE";
|
|
65
|
+
contractTypes[uint8(PriceFeedType.COMPOUND_V2_ORACLE)] = "NOT_USED";
|
|
66
|
+
contractTypes[uint8(PriceFeedType.CURVE_2LP_ORACLE)] = "PF_CURVE_STABLE_LP_ORACLE";
|
|
67
|
+
contractTypes[uint8(PriceFeedType.CURVE_3LP_ORACLE)] = "PF_CURVE_STABLE_LP_ORACLE";
|
|
68
|
+
contractTypes[uint8(PriceFeedType.CURVE_4LP_ORACLE)] = "PF_CURVE_STABLE_LP_ORACLE";
|
|
69
|
+
contractTypes[uint8(PriceFeedType.CURVE_CRYPTO_ORACLE)] = "PF_CURVE_CRYPTO_LP_ORACLE";
|
|
70
|
+
contractTypes[uint8(PriceFeedType.CURVE_USD_ORACLE)] = "PF_CURVE_USD_ORACLE";
|
|
71
|
+
contractTypes[uint8(PriceFeedType.ERC4626_VAULT_ORACLE)] = "PF_ERC4626_ORACLE";
|
|
72
|
+
contractTypes[uint8(PriceFeedType.WRAPPED_AAVE_V2_ORACLE)] = "NOT_USER";
|
|
73
|
+
contractTypes[uint8(PriceFeedType.WSTETH_ORACLE)] = "PF_WSTETH_ORACLE";
|
|
74
|
+
contractTypes[uint8(PriceFeedType.YEARN_ORACLE)] = "PF_YEARN_ORACLE";
|
|
75
|
+
contractTypes[uint8(PriceFeedType.MELLOW_LRT_ORACLE)] = "PF_MELLOW_LRT_ORACLE";
|
|
76
|
+
|
|
77
|
+
// these types need special serialization
|
|
78
|
+
contractTypes[uint8(PriceFeedType.BALANCER_WEIGHTED_LP_ORACLE)] = "PF_BALANCER_WEIGHTED_LP_ORACLE";
|
|
79
|
+
contractTypes[uint8(PriceFeedType.BOUNDED_ORACLE)] = "PF_BOUNDED_ORACLE";
|
|
80
|
+
contractTypes[uint8(PriceFeedType.PYTH_ORACLE)] = "PF_PYTH_ORACLE";
|
|
81
|
+
contractTypes[uint8(PriceFeedType.REDSTONE_ORACLE)] = "PF_REDSTONE_ORACLE";
|
|
82
|
+
|
|
55
83
|
// these types can be serialized as generic LP price feeds
|
|
56
|
-
_setSerializer(
|
|
57
|
-
_setSerializer(
|
|
58
|
-
_setSerializer(
|
|
59
|
-
_setSerializer(
|
|
60
|
-
_setSerializer(
|
|
61
|
-
_setSerializer(
|
|
62
|
-
_setSerializer(
|
|
63
|
-
_setSerializer(
|
|
64
|
-
_setSerializer(uint8(PriceFeedType.WRAPPED_AAVE_V2_ORACLE), lpSerializer);
|
|
65
|
-
_setSerializer(uint8(PriceFeedType.WSTETH_ORACLE), lpSerializer);
|
|
66
|
-
_setSerializer(uint8(PriceFeedType.YEARN_ORACLE), lpSerializer);
|
|
67
|
-
_setSerializer(uint8(PriceFeedType.MELLOW_LRT_ORACLE), lpSerializer);
|
|
84
|
+
_setSerializer("PF_BALANCER_STABLE_LP_ORACLE", lpSerializer);
|
|
85
|
+
_setSerializer("PF_CURVE_STABLE_LP_ORACLE", lpSerializer);
|
|
86
|
+
_setSerializer("PF_CURVE_CRYPTO_LP_ORACLE", lpSerializer);
|
|
87
|
+
_setSerializer("PF_CURVE_USD_ORACLE", lpSerializer);
|
|
88
|
+
_setSerializer("PF_ERC4626_ORACLE", lpSerializer);
|
|
89
|
+
_setSerializer("PF_WSTETH_ORACLE", lpSerializer);
|
|
90
|
+
_setSerializer("PF_YEARN_ORACLE", lpSerializer);
|
|
91
|
+
_setSerializer("PF_MELLOW_LRT_ORACLE", lpSerializer);
|
|
68
92
|
|
|
69
93
|
// these types need special serialization
|
|
70
|
-
_setSerializer(
|
|
71
|
-
_setSerializer(
|
|
72
|
-
_setSerializer(
|
|
73
|
-
_setSerializer(
|
|
94
|
+
_setSerializer("PF_BALANCER_WEIGHTED_LP_ORACLE", address(new BPTWeightedPriceFeedSerializer()));
|
|
95
|
+
_setSerializer("PF_BOUNDED_ORACLE", address(new BoundedPriceFeedSerializer()));
|
|
96
|
+
_setSerializer("PF_PYTH_ORACLE", address(new PythPriceFeedSerializer()));
|
|
97
|
+
_setSerializer("PF_REDSTONE_ORACLE", address(new RedstonePriceFeedSerializer()));
|
|
74
98
|
}
|
|
75
99
|
|
|
76
100
|
/// @notice Returns all potentially useful price feeds data for a given price oracle in the form of two arrays:
|
|
@@ -94,14 +118,7 @@ contract PriceFeedCompressor is IPriceFeedCompressor {
|
|
|
94
118
|
view
|
|
95
119
|
returns (PriceOracleState memory result)
|
|
96
120
|
{
|
|
97
|
-
result.
|
|
98
|
-
result.version = IPriceOracleV3(priceOracle).version();
|
|
99
|
-
try IVersion(priceOracle).contractType() returns (bytes32 contractType) {
|
|
100
|
-
result.contractType = contractType;
|
|
101
|
-
} catch {
|
|
102
|
-
result.contractType = "PRICE_ORACLE";
|
|
103
|
-
}
|
|
104
|
-
|
|
121
|
+
result.baseParams = BaseLib.getBaseParams(priceOracle, "PRICE_ORACLE", address(0));
|
|
105
122
|
(result.priceFeedMapping, result.priceFeedStructure) = getPriceFeeds(priceOracle, tokens);
|
|
106
123
|
}
|
|
107
124
|
|
|
@@ -177,10 +194,10 @@ contract PriceFeedCompressor is IPriceFeedCompressor {
|
|
|
177
194
|
// --------- //
|
|
178
195
|
|
|
179
196
|
/// @dev Sets `serializer` for `priceFeedType`
|
|
180
|
-
function _setSerializer(
|
|
181
|
-
if (serializers[
|
|
182
|
-
serializers[
|
|
183
|
-
emit SetSerializer(
|
|
197
|
+
function _setSerializer(bytes32 contractType, address serializer) internal {
|
|
198
|
+
if (serializers[contractType] != serializer) {
|
|
199
|
+
serializers[contractType] = serializer;
|
|
200
|
+
emit SetSerializer(contractType, serializer);
|
|
184
201
|
}
|
|
185
202
|
}
|
|
186
203
|
|
|
@@ -218,7 +235,7 @@ contract PriceFeedCompressor is IPriceFeedCompressor {
|
|
|
218
235
|
// duplicates are possible since price feed can be in `priceFeedMap` for more than one (token, reserve) pair
|
|
219
236
|
// or serve as an underlying in more than one nested feed, and the whole subtree can be skipped in this case
|
|
220
237
|
for (uint256 i; i < offset; ++i) {
|
|
221
|
-
if (priceFeedTree[i].
|
|
238
|
+
if (priceFeedTree[i].baseParams.addr == priceFeed) return offset;
|
|
222
239
|
}
|
|
223
240
|
|
|
224
241
|
PriceFeedTreeNode memory node = _getPriceFeedTreeNode(priceFeed);
|
|
@@ -231,16 +248,21 @@ contract PriceFeedCompressor is IPriceFeedCompressor {
|
|
|
231
248
|
|
|
232
249
|
/// @dev Returns price feed tree node, see `PriceFeedTreeNode` for detailed description of struct fields
|
|
233
250
|
function _getPriceFeedTreeNode(address priceFeed) internal view returns (PriceFeedTreeNode memory data) {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
data.version = IPriceFeed(priceFeed).version();
|
|
237
|
-
|
|
238
|
-
try ImplementsPriceFeedType(priceFeed).priceFeedType() returns (uint8 priceFeedType) {
|
|
239
|
-
data.priceFeedType = priceFeedType;
|
|
251
|
+
try IVersion(priceFeed).contractType() returns (bytes32 contractType) {
|
|
252
|
+
data.baseParams.contractType = contractType;
|
|
240
253
|
} catch {
|
|
241
|
-
|
|
254
|
+
try ImplementsPriceFeedType(priceFeed).priceFeedType() returns (uint8 priceFeedType) {
|
|
255
|
+
data.baseParams.contractType = contractTypes[priceFeedType];
|
|
256
|
+
} catch {
|
|
257
|
+
data.baseParams.contractType = "PF_CHAINLINK_ORACLE";
|
|
258
|
+
}
|
|
242
259
|
}
|
|
243
260
|
|
|
261
|
+
data.baseParams =
|
|
262
|
+
BaseLib.getBaseParams(priceFeed, data.baseParams.contractType, serializers[data.baseParams.contractType]);
|
|
263
|
+
|
|
264
|
+
data.decimals = IPriceFeed(priceFeed).decimals();
|
|
265
|
+
|
|
244
266
|
try IPriceFeed(priceFeed).skipPriceCheck() returns (bool skipCheck) {
|
|
245
267
|
data.skipCheck = skipCheck;
|
|
246
268
|
} catch {}
|
|
@@ -249,15 +271,6 @@ contract PriceFeedCompressor is IPriceFeedCompressor {
|
|
|
249
271
|
data.updatable = updatable;
|
|
250
272
|
} catch {}
|
|
251
273
|
|
|
252
|
-
try IStateSerializer(priceFeed).serialize() returns (bytes memory specificParams) {
|
|
253
|
-
data.specificParams = specificParams;
|
|
254
|
-
} catch {
|
|
255
|
-
address serializer = serializers[data.priceFeedType];
|
|
256
|
-
if (serializer != address(0)) {
|
|
257
|
-
data.specificParams = IStateSerializerLegacy(serializer).serialize(priceFeed);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
274
|
(data.underlyingFeeds, data.underlyingStalenessPeriods) = IPriceFeed(priceFeed).getUnderlyingFeeds();
|
|
262
275
|
|
|
263
276
|
try IPriceFeed(priceFeed).latestRoundData() returns (uint80, int256 price, uint256, uint256 updatedAt, uint80) {
|
|
@@ -9,7 +9,7 @@ import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVer
|
|
|
9
9
|
|
|
10
10
|
interface IPriceFeedCompressor is IVersion {
|
|
11
11
|
/// @notice Emitted when new state serializer is set for a given price feed type
|
|
12
|
-
event SetSerializer(
|
|
12
|
+
event SetSerializer(bytes32 indexed contractType, address indexed serializer);
|
|
13
13
|
|
|
14
14
|
function getPriceFeeds(address priceOracle)
|
|
15
15
|
external
|
|
@@ -0,0 +1,42 @@
|
|
|
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 {BaseParams, BaseState} from "../types/BaseState.sol";
|
|
7
|
+
import {IVersion} from "../interfaces/IVersion.sol";
|
|
8
|
+
import {IStateSerializer} from "../interfaces/IStateSerializer.sol";
|
|
9
|
+
import {IStateSerializerLegacy} from "../interfaces/IStateSerializerLegacy.sol";
|
|
10
|
+
|
|
11
|
+
library BaseLib {
|
|
12
|
+
function getBaseParams(address addr, bytes32 defaultContractType, address legacySerializer)
|
|
13
|
+
internal
|
|
14
|
+
view
|
|
15
|
+
returns (BaseParams memory baseParams)
|
|
16
|
+
{
|
|
17
|
+
baseParams.addr = addr;
|
|
18
|
+
try IVersion(addr).contractType() returns (bytes32 contractType) {
|
|
19
|
+
baseParams.contractType = contractType;
|
|
20
|
+
} catch {
|
|
21
|
+
baseParams.version = 3_00;
|
|
22
|
+
baseParams.contractType = defaultContractType;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
baseParams.version = IVersion(addr).version();
|
|
26
|
+
try IStateSerializer(addr).serialize() returns (bytes memory serializedParams) {
|
|
27
|
+
baseParams.serializedParams = serializedParams;
|
|
28
|
+
} catch {
|
|
29
|
+
if (legacySerializer != address(0)) {
|
|
30
|
+
baseParams.serializedParams = IStateSerializerLegacy(legacySerializer).serialize(addr);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function getBaseState(address addr, bytes32 defaultContractType, address legacySerializer)
|
|
36
|
+
internal
|
|
37
|
+
view
|
|
38
|
+
returns (BaseState memory baseState)
|
|
39
|
+
{
|
|
40
|
+
baseState.baseParams = getBaseParams(addr, defaultContractType, legacySerializer);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
// (c) Gearbox Holdings, 2024
|
|
4
4
|
pragma solidity ^0.8.17;
|
|
5
5
|
|
|
6
|
+
import {BaseParams} from "./BaseState.sol";
|
|
7
|
+
|
|
6
8
|
struct PriceOracleState {
|
|
7
|
-
|
|
8
|
-
uint256 version;
|
|
9
|
-
bytes32 contractType;
|
|
9
|
+
BaseParams baseParams;
|
|
10
10
|
PriceFeedMapEntry[] priceFeedMapping;
|
|
11
11
|
PriceFeedTreeNode[] priceFeedStructure;
|
|
12
12
|
}
|
|
@@ -45,9 +45,7 @@ struct PriceFeedMapEntry {
|
|
|
45
45
|
/// @param underlyingStalenessPeriods Staleness periods of underlying feeds, filled when `priceFeed` is nested
|
|
46
46
|
/// @param answer Price feed answer packed in a struct
|
|
47
47
|
struct PriceFeedTreeNode {
|
|
48
|
-
|
|
49
|
-
uint8 priceFeedType;
|
|
50
|
-
uint256 version;
|
|
48
|
+
BaseParams baseParams;
|
|
51
49
|
uint8 decimals;
|
|
52
50
|
bool skipCheck;
|
|
53
51
|
bool updatable;
|
|
@@ -55,5 +53,4 @@ struct PriceFeedTreeNode {
|
|
|
55
53
|
address[] underlyingFeeds;
|
|
56
54
|
uint32[] underlyingStalenessPeriods;
|
|
57
55
|
PriceFeedAnswer answer;
|
|
58
|
-
bytes specificParams;
|
|
59
56
|
}
|
package/package.json
CHANGED