@gearbox-protocol/periphery-v3 1.7.0 → 1.8.0
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 +6 -0
- package/contracts/compressors/PriceFeedCompressor.sol +5 -12
- package/contracts/test/migration/cloners/IntegrationCloner.sol +20 -58
- package/contracts/test/migration/cloners/PriceFeedCloner.sol +0 -149
- package/package.json +1 -1
- package/contracts/serializers/oracles/BPTWeightedPriceFeedSerializer.sol +0 -26
- package/contracts/test/ForkTest.sol +0 -63
package/README.md
CHANGED
|
@@ -64,3 +64,9 @@ $ forge --help
|
|
|
64
64
|
$ anvil --help
|
|
65
65
|
$ cast --help
|
|
66
66
|
```
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
### Important information for contributors
|
|
71
|
+
|
|
72
|
+
As a contributor to the Gearbox Protocol GitHub repository, your pull requests indicate acceptance of our Gearbox Contribution Agreement. This agreement outlines that you assign the Intellectual Property Rights of your contributions to the Gearbox Foundation. This helps safeguard the Gearbox protocol and ensure the accumulation of its intellectual property. Contributions become part of the repository and may be used for various purposes, including commercial. As recognition for your expertise and work, you receive the opportunity to participate in the protocol's development and the potential to see your work integrated within it. The full Gearbox Contribution Agreement is accessible within the [repository](/ContributionAgreement) for comprehensive understanding. [Let's innovate together!]
|
|
@@ -14,7 +14,6 @@ import {ILegacyPriceFeed, ILegacyPriceOracle, Legacy} from "../libraries/Legacy.
|
|
|
14
14
|
import {AP_PRICE_FEED_COMPRESSOR} from "../libraries/Literals.sol";
|
|
15
15
|
import {NestedPriceFeeds} from "../libraries/NestedPriceFeeds.sol";
|
|
16
16
|
|
|
17
|
-
import {BPTWeightedPriceFeedSerializer} from "../serializers/oracles/BPTWeightedPriceFeedSerializer.sol";
|
|
18
17
|
import {BoundedPriceFeedSerializer} from "../serializers/oracles/BoundedPriceFeedSerializer.sol";
|
|
19
18
|
import {LPPriceFeedSerializer} from "../serializers/oracles/LPPriceFeedSerializer.sol";
|
|
20
19
|
import {PendleTWAPPTPriceFeedSerializer} from "../serializers/oracles/PendleTWAPPTPriceFeedSerializer.sol";
|
|
@@ -35,7 +34,7 @@ contract PriceFeedCompressor is BaseCompressor, IPriceFeedCompressor {
|
|
|
35
34
|
using NestedPriceFeeds for IPriceFeed;
|
|
36
35
|
|
|
37
36
|
/// @notice Contract version
|
|
38
|
-
uint256 public constant override version =
|
|
37
|
+
uint256 public constant override version = 3_11;
|
|
39
38
|
|
|
40
39
|
/// @notice Contract type
|
|
41
40
|
bytes32 public constant override contractType = AP_PRICE_FEED_COMPRESSOR;
|
|
@@ -49,17 +48,12 @@ contract PriceFeedCompressor is BaseCompressor, IPriceFeedCompressor {
|
|
|
49
48
|
constructor(address addressProvider_) BaseCompressor(addressProvider_) {
|
|
50
49
|
// these types can be serialized as generic LP price feeds
|
|
51
50
|
address lpSerializer = address(new LPPriceFeedSerializer());
|
|
52
|
-
serializers["PRICE_FEED::BALANCER_STABLE"] = lpSerializer;
|
|
53
51
|
serializers["PRICE_FEED::CURVE_STABLE"] = lpSerializer;
|
|
54
52
|
serializers["PRICE_FEED::CURVE_CRYPTO"] = lpSerializer;
|
|
55
|
-
serializers["PRICE_FEED::CURVE_USD"] = lpSerializer;
|
|
56
53
|
serializers["PRICE_FEED::ERC4626"] = lpSerializer;
|
|
57
|
-
serializers["PRICE_FEED::MELLOW_LRT"] = lpSerializer;
|
|
58
54
|
serializers["PRICE_FEED::WSTETH"] = lpSerializer;
|
|
59
|
-
serializers["PRICE_FEED::YEARN"] = lpSerializer;
|
|
60
55
|
|
|
61
56
|
// these types need special serialization
|
|
62
|
-
serializers["PRICE_FEED::BALANCER_WEIGHTED"] = address(new BPTWeightedPriceFeedSerializer());
|
|
63
57
|
serializers["PRICE_FEED::BOUNDED"] = address(new BoundedPriceFeedSerializer());
|
|
64
58
|
serializers["PRICE_FEED::PENDLE_PT_TWAP"] = address(new PendleTWAPPTPriceFeedSerializer());
|
|
65
59
|
serializers["PRICE_FEED::PYTH"] = address(new PythPriceFeedSerializer());
|
|
@@ -150,10 +144,7 @@ contract PriceFeedCompressor is BaseCompressor, IPriceFeedCompressor {
|
|
|
150
144
|
if (priceFeed == address(0)) continue;
|
|
151
145
|
|
|
152
146
|
priceFeedMap[priceFeedMapSize++] = PriceFeedMapEntry({
|
|
153
|
-
token: token,
|
|
154
|
-
reserve: reserve,
|
|
155
|
-
priceFeed: priceFeed,
|
|
156
|
-
stalenessPeriod: stalenessPeriod
|
|
147
|
+
token: token, reserve: reserve, priceFeed: priceFeed, stalenessPeriod: stalenessPeriod
|
|
157
148
|
});
|
|
158
149
|
}
|
|
159
150
|
// trim array to its actual size in case some tokens don't have reserve price feeds
|
|
@@ -275,7 +266,9 @@ contract PriceFeedCompressor is BaseCompressor, IPriceFeedCompressor {
|
|
|
275
266
|
data.baseParams =
|
|
276
267
|
priceFeed.getBaseParams(data.baseParams.contractType, serializers[data.baseParams.contractType]);
|
|
277
268
|
|
|
278
|
-
|
|
269
|
+
try IPriceFeed(priceFeed).decimals() returns (uint8 decimals) {
|
|
270
|
+
data.decimals = decimals;
|
|
271
|
+
} catch {}
|
|
279
272
|
|
|
280
273
|
try IPriceFeed(priceFeed).skipPriceCheck() returns (bool skipCheck) {
|
|
281
274
|
data.skipCheck = skipCheck;
|
|
@@ -10,10 +10,12 @@ import {IACL} from "@gearbox-protocol/permissionless/contracts/interfaces/IACL.s
|
|
|
10
10
|
import {IAdapter} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IAdapter.sol";
|
|
11
11
|
import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
|
|
12
12
|
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
import {
|
|
14
|
+
ConvexStakedPositionToken
|
|
15
|
+
} from "@gearbox-protocol/integrations-v3/contracts/helpers/convex/ConvexV1_StakedPositionToken.sol";
|
|
16
|
+
import {
|
|
17
|
+
StakingRewardsPhantomToken
|
|
18
|
+
} from "@gearbox-protocol/integrations-v3/contracts/helpers/sky/StakingRewardsPhantomToken.sol";
|
|
17
19
|
import {IBaseRewardPool} from "@gearbox-protocol/integrations-v3/contracts/integrations/convex/IBaseRewardPool.sol";
|
|
18
20
|
|
|
19
21
|
import {
|
|
@@ -24,12 +26,9 @@ import {
|
|
|
24
26
|
UniswapV3Adapter,
|
|
25
27
|
UniswapV3PoolStatus
|
|
26
28
|
} from "@gearbox-protocol/integrations-v3/contracts/adapters/uniswap/UniswapV3.sol";
|
|
27
|
-
import {YearnV2Adapter} from "@gearbox-protocol/integrations-v3/contracts/adapters/yearn/YearnV2.sol";
|
|
28
29
|
import {ERC4626Adapter} from "@gearbox-protocol/integrations-v3/contracts/adapters/erc4626/ERC4626Adapter.sol";
|
|
29
30
|
import {LidoV1Adapter} from "@gearbox-protocol/integrations-v3/contracts/adapters/lido/LidoV1.sol";
|
|
30
31
|
import {WstETHV1Adapter} from "@gearbox-protocol/integrations-v3/contracts/adapters/lido/WstETHV1.sol";
|
|
31
|
-
import {BalancerV2VaultAdapter} from
|
|
32
|
-
"@gearbox-protocol/integrations-v3/contracts/adapters/balancer/BalancerV2VaultAdapter.sol";
|
|
33
32
|
import {
|
|
34
33
|
CamelotV3Adapter,
|
|
35
34
|
CamelotV3PoolStatus
|
|
@@ -40,23 +39,25 @@ import {CurveV1Adapter2Assets} from "@gearbox-protocol/integrations-v3/contracts
|
|
|
40
39
|
import {CurveV1Adapter3Assets} from "@gearbox-protocol/integrations-v3/contracts/adapters/curve/CurveV1_3.sol";
|
|
41
40
|
import {CurveV1Adapter4Assets} from "@gearbox-protocol/integrations-v3/contracts/adapters/curve/CurveV1_4.sol";
|
|
42
41
|
import {CurveV1AdapterStableNG} from "@gearbox-protocol/integrations-v3/contracts/adapters/curve/CurveV1_StableNG.sol";
|
|
43
|
-
import {
|
|
44
|
-
|
|
42
|
+
import {
|
|
43
|
+
ConvexV1BaseRewardPoolAdapter
|
|
44
|
+
} from "@gearbox-protocol/integrations-v3/contracts/adapters/convex/ConvexV1_BaseRewardPool.sol";
|
|
45
45
|
import {ConvexV1BoosterAdapter} from "@gearbox-protocol/integrations-v3/contracts/adapters/convex/ConvexV1_Booster.sol";
|
|
46
46
|
import {
|
|
47
47
|
VelodromeV2RouterAdapter,
|
|
48
48
|
VelodromeV2PoolStatus
|
|
49
49
|
} from "@gearbox-protocol/integrations-v3/contracts/adapters/velodrome/VelodromeV2RouterAdapter.sol";
|
|
50
50
|
import {DaiUsdsAdapter} from "@gearbox-protocol/integrations-v3/contracts/adapters/sky/DaiUsdsAdapter.sol";
|
|
51
|
-
import {StakingRewardsAdapter} from "@gearbox-protocol/integrations-v3/contracts/adapters/sky/StakingRewardsAdapter.sol";
|
|
52
|
-
import {BalancerV3RouterAdapter} from
|
|
53
|
-
"@gearbox-protocol/integrations-v3/contracts/adapters/balancer/BalancerV3RouterAdapter.sol";
|
|
54
51
|
import {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
StakingRewardsAdapter
|
|
53
|
+
} from "@gearbox-protocol/integrations-v3/contracts/adapters/sky/StakingRewardsAdapter.sol";
|
|
54
|
+
import {
|
|
55
|
+
BalancerV3RouterAdapter,
|
|
56
|
+
BalancerV3PoolStatus
|
|
57
|
+
} from "@gearbox-protocol/integrations-v3/contracts/adapters/balancer/BalancerV3RouterAdapter.sol";
|
|
58
|
+
import {
|
|
59
|
+
Mellow4626VaultAdapter
|
|
60
|
+
} from "@gearbox-protocol/integrations-v3/contracts/adapters/mellow/Mellow4626VaultAdapter.sol";
|
|
60
61
|
|
|
61
62
|
interface IOldAdapter {
|
|
62
63
|
function _gearboxAdapterType() external view returns (AdapterType aType);
|
|
@@ -170,11 +171,6 @@ contract IntegrationCloner is Test {
|
|
|
170
171
|
// }
|
|
171
172
|
// }
|
|
172
173
|
}
|
|
173
|
-
/// YEARN V2
|
|
174
|
-
else if (aType == AdapterType.YEARN_V2) {
|
|
175
|
-
vm.prank(configurator);
|
|
176
|
-
newAdapter = address(new YearnV2Adapter(newCreditManager, targetContract));
|
|
177
|
-
}
|
|
178
174
|
/// ERC4626
|
|
179
175
|
else if (aType == AdapterType.ERC4626_VAULT) {
|
|
180
176
|
vm.prank(configurator);
|
|
@@ -190,15 +186,6 @@ contract IntegrationCloner is Test {
|
|
|
190
186
|
vm.prank(configurator);
|
|
191
187
|
newAdapter = address(new WstETHV1Adapter(newCreditManager, targetContract));
|
|
192
188
|
}
|
|
193
|
-
/// BALANCER VAULT
|
|
194
|
-
else if (aType == AdapterType.BALANCER_VAULT) {
|
|
195
|
-
vm.prank(configurator);
|
|
196
|
-
newAdapter = address(new BalancerV2VaultAdapter(newCreditManager, targetContract));
|
|
197
|
-
|
|
198
|
-
/// CLONE BALANCER POOLS
|
|
199
|
-
/// event: SetPoolStatus(poolId, newStatus);
|
|
200
|
-
/// function: setPoolStatus(bytes32 poolId, PoolStatus newStatus)
|
|
201
|
-
}
|
|
202
189
|
/// CAMELOT V3
|
|
203
190
|
else if (aType == AdapterType.CAMELOT_V3_ROUTER) {
|
|
204
191
|
vm.prank(configurator);
|
|
@@ -329,40 +316,15 @@ contract IntegrationCloner is Test {
|
|
|
329
316
|
vm.prank(configurator);
|
|
330
317
|
newAdapter = address(new StakingRewardsAdapter(newCreditManager, targetContract, stakedPhantomToken, 0));
|
|
331
318
|
}
|
|
332
|
-
/// MELLOW LRT VAULT
|
|
333
|
-
else if (aType == AdapterType.MELLOW_LRT_VAULT) {
|
|
334
|
-
vm.prank(configurator);
|
|
335
|
-
newAdapter = address(new MellowVaultAdapter(newCreditManager, targetContract));
|
|
336
|
-
|
|
337
|
-
// uint256 collateralTokensCount = ICreditManagerV3(newCreditManager).collateralTokensCount();
|
|
338
|
-
|
|
339
|
-
// for (uint256 i = 0; i < collateralTokensCount; ++i) {
|
|
340
|
-
// address token = ICreditManagerV3(oldCreditManager).getTokenByMask(1 << i);
|
|
341
|
-
|
|
342
|
-
// if (IOldMellowVaultAdapter(oldAdapter).isUnderlyingAllowed(token)) {
|
|
343
|
-
// MellowUnderlyingStatus[] memory underlyings = new MellowUnderlyingStatus[](1);
|
|
344
|
-
// underlyings[0] = MellowUnderlyingStatus({underlying: token, allowed: true});
|
|
345
|
-
|
|
346
|
-
// vm.prank(configurator);
|
|
347
|
-
// MellowVaultAdapter(newAdapter).setUnderlyingStatusBatch(underlyings);
|
|
348
|
-
// }
|
|
349
|
-
// }
|
|
350
|
-
}
|
|
351
319
|
/// BALANCER V3
|
|
352
320
|
else if (aType == AdapterType.BALANCER_V3_ROUTER) {
|
|
353
321
|
vm.prank(configurator);
|
|
354
322
|
newAdapter = address(new BalancerV3RouterAdapter(newCreditManager, targetContract));
|
|
355
323
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
bool[] memory statuses = new bool[](pools.length);
|
|
359
|
-
|
|
360
|
-
for (uint256 i = 0; i < pools.length; ++i) {
|
|
361
|
-
statuses[i] = true;
|
|
362
|
-
}
|
|
324
|
+
BalancerV3PoolStatus[] memory pools = BalancerV3RouterAdapter(oldAdapter).getAllowedPools();
|
|
363
325
|
|
|
364
326
|
vm.prank(configurator);
|
|
365
|
-
BalancerV3RouterAdapter(newAdapter).setPoolStatusBatch(pools
|
|
327
|
+
BalancerV3RouterAdapter(newAdapter).setPoolStatusBatch(pools);
|
|
366
328
|
}
|
|
367
329
|
/// MELLOW ERC4626 VAULT
|
|
368
330
|
else if (aType == AdapterType.MELLOW_ERC4626_VAULT) {
|
|
@@ -20,17 +20,10 @@ import {CompositePriceFeed} from "@gearbox-protocol/oracles-v3/contracts/oracles
|
|
|
20
20
|
import {BoundedPriceFeed} from "@gearbox-protocol/oracles-v3/contracts/oracles/BoundedPriceFeed.sol";
|
|
21
21
|
import {RedstonePriceFeed} from "@gearbox-protocol/oracles-v3/contracts/oracles/updatable/RedstonePriceFeed.sol";
|
|
22
22
|
import {ERC4626PriceFeed} from "@gearbox-protocol/oracles-v3/contracts/oracles/erc4626/ERC4626PriceFeed.sol";
|
|
23
|
-
import {MellowLRTPriceFeed} from "@gearbox-protocol/oracles-v3/contracts/oracles/mellow/MellowLRTPriceFeed.sol";
|
|
24
|
-
import {YearnPriceFeed} from "@gearbox-protocol/oracles-v3/contracts/oracles/yearn/YearnPriceFeed.sol";
|
|
25
23
|
import {WstETHPriceFeed} from "@gearbox-protocol/oracles-v3/contracts/oracles/lido/WstETHPriceFeed.sol";
|
|
26
24
|
import {PendleTWAPPTPriceFeed} from "@gearbox-protocol/oracles-v3/contracts/oracles/pendle/PendleTWAPPTPriceFeed.sol";
|
|
27
25
|
import {CurveStableLPPriceFeed} from "@gearbox-protocol/oracles-v3/contracts/oracles/curve/CurveStableLPPriceFeed.sol";
|
|
28
26
|
import {CurveCryptoLPPriceFeed} from "@gearbox-protocol/oracles-v3/contracts/oracles/curve/CurveCryptoLPPriceFeed.sol";
|
|
29
|
-
import {BPTStablePriceFeed} from "@gearbox-protocol/oracles-v3/contracts/oracles/balancer/BPTStablePriceFeed.sol";
|
|
30
|
-
import {BPTWeightedPriceFeed} from "@gearbox-protocol/oracles-v3/contracts/oracles/balancer/BPTWeightedPriceFeed.sol";
|
|
31
|
-
|
|
32
|
-
import {IBalancerWeightedPool} from
|
|
33
|
-
"@gearbox-protocol/oracles-v3/contracts/interfaces/balancer/IBalancerWeightedPool.sol";
|
|
34
27
|
|
|
35
28
|
interface IOldPriceOracle {
|
|
36
29
|
function priceFeedParams(address token)
|
|
@@ -177,28 +170,6 @@ contract PriceFeedCloner is Test {
|
|
|
177
170
|
newPriceFeed =
|
|
178
171
|
address(new ERC4626PriceFeed(configurator, lowerBound, vault, underlyingFeed, stalenessPeriod));
|
|
179
172
|
}
|
|
180
|
-
/// MELLOW LRT ORACLE
|
|
181
|
-
else if (pfType == PriceFeedType.MELLOW_LRT_ORACLE) {
|
|
182
|
-
address vault = MellowLRTPriceFeed(oldPriceFeed).lpContract();
|
|
183
|
-
uint256 lowerBound = IERC4626(vault).convertToAssets(1e18);
|
|
184
|
-
uint32 stalenessPeriod = MellowLRTPriceFeed(oldPriceFeed).stalenessPeriod();
|
|
185
|
-
address underlyingFeed =
|
|
186
|
-
_migrateFromOld(token, MellowLRTPriceFeed(oldPriceFeed).priceFeed(), stalenessPeriod);
|
|
187
|
-
|
|
188
|
-
vm.prank(configurator);
|
|
189
|
-
newPriceFeed =
|
|
190
|
-
address(new ERC4626PriceFeed(configurator, lowerBound, vault, underlyingFeed, stalenessPeriod));
|
|
191
|
-
}
|
|
192
|
-
/// YEARN ORACLE
|
|
193
|
-
else if (pfType == PriceFeedType.YEARN_ORACLE) {
|
|
194
|
-
uint256 lowerBound = YearnPriceFeed(oldPriceFeed).getLPExchangeRate();
|
|
195
|
-
address vault = YearnPriceFeed(oldPriceFeed).lpContract();
|
|
196
|
-
uint32 stalenessPeriod = YearnPriceFeed(oldPriceFeed).stalenessPeriod();
|
|
197
|
-
address underlyingFeed = _migrateFromOld(token, YearnPriceFeed(oldPriceFeed).priceFeed(), stalenessPeriod);
|
|
198
|
-
|
|
199
|
-
vm.prank(configurator);
|
|
200
|
-
newPriceFeed = address(new YearnPriceFeed(configurator, lowerBound, vault, underlyingFeed, stalenessPeriod));
|
|
201
|
-
}
|
|
202
173
|
/// WSTETH ORACLE
|
|
203
174
|
else if (pfType == PriceFeedType.WSTETH_ORACLE) {
|
|
204
175
|
uint256 lowerBound = WstETHPriceFeed(oldPriceFeed).getLPExchangeRate();
|
|
@@ -272,47 +243,6 @@ contract PriceFeedCloner is Test {
|
|
|
272
243
|
vm.prank(configurator);
|
|
273
244
|
newPriceFeed = address(new CurveCryptoLPPriceFeed(configurator, lowerBound, lpToken, pool, pfParams));
|
|
274
245
|
}
|
|
275
|
-
/// BPT STABLE PRICE FEED
|
|
276
|
-
else if (pfType == PriceFeedType.BALANCER_STABLE_LP_ORACLE) {
|
|
277
|
-
uint256 lowerBound = BPTStablePriceFeed(oldPriceFeed).getLPExchangeRate();
|
|
278
|
-
address balancerPool = BPTStablePriceFeed(oldPriceFeed).lpContract();
|
|
279
|
-
|
|
280
|
-
PriceFeedParams[5] memory pfParams;
|
|
281
|
-
|
|
282
|
-
pfParams[0].stalenessPeriod = BPTStablePriceFeed(oldPriceFeed).stalenessPeriod0();
|
|
283
|
-
pfParams[0].priceFeed =
|
|
284
|
-
_migrateFromOld(token, BPTStablePriceFeed(oldPriceFeed).priceFeed0(), pfParams[0].stalenessPeriod);
|
|
285
|
-
|
|
286
|
-
pfParams[1].stalenessPeriod = BPTStablePriceFeed(oldPriceFeed).stalenessPeriod1();
|
|
287
|
-
pfParams[1].priceFeed =
|
|
288
|
-
_migrateFromOld(token, BPTStablePriceFeed(oldPriceFeed).priceFeed1(), pfParams[1].stalenessPeriod);
|
|
289
|
-
|
|
290
|
-
pfParams[2].stalenessPeriod = BPTStablePriceFeed(oldPriceFeed).stalenessPeriod2();
|
|
291
|
-
pfParams[2].priceFeed =
|
|
292
|
-
_migrateFromOld(token, BPTStablePriceFeed(oldPriceFeed).priceFeed2(), pfParams[2].stalenessPeriod);
|
|
293
|
-
|
|
294
|
-
pfParams[3].stalenessPeriod = BPTStablePriceFeed(oldPriceFeed).stalenessPeriod3();
|
|
295
|
-
pfParams[3].priceFeed =
|
|
296
|
-
_migrateFromOld(token, BPTStablePriceFeed(oldPriceFeed).priceFeed3(), pfParams[3].stalenessPeriod);
|
|
297
|
-
|
|
298
|
-
pfParams[4].stalenessPeriod = BPTStablePriceFeed(oldPriceFeed).stalenessPeriod4();
|
|
299
|
-
pfParams[4].priceFeed =
|
|
300
|
-
_migrateFromOld(token, BPTStablePriceFeed(oldPriceFeed).priceFeed4(), pfParams[4].stalenessPeriod);
|
|
301
|
-
|
|
302
|
-
vm.prank(configurator);
|
|
303
|
-
newPriceFeed = address(new BPTStablePriceFeed(configurator, lowerBound, balancerPool, pfParams));
|
|
304
|
-
}
|
|
305
|
-
/// BPT WEIGHTED PRICE FEED
|
|
306
|
-
else if (pfType == PriceFeedType.BALANCER_WEIGHTED_LP_ORACLE) {
|
|
307
|
-
PriceFeedParams[] memory pfParams = _getBPTWeightedPriceFeedParams(token, oldPriceFeed);
|
|
308
|
-
|
|
309
|
-
uint256 lowerBound = BPTWeightedPriceFeed(oldPriceFeed).getLPExchangeRate();
|
|
310
|
-
address balancerPool = BPTWeightedPriceFeed(oldPriceFeed).lpContract();
|
|
311
|
-
address vault = BPTWeightedPriceFeed(oldPriceFeed).vault();
|
|
312
|
-
|
|
313
|
-
vm.prank(configurator);
|
|
314
|
-
newPriceFeed = address(new BPTWeightedPriceFeed(configurator, lowerBound, vault, balancerPool, pfParams));
|
|
315
|
-
}
|
|
316
246
|
|
|
317
247
|
oldToNewPriceFeed[oldPriceFeed] = newPriceFeed;
|
|
318
248
|
stalenessPeriods[newPriceFeed] = oldStalenessPeriod;
|
|
@@ -365,85 +295,6 @@ contract PriceFeedCloner is Test {
|
|
|
365
295
|
|| pft == PriceFeedType.CURVE_4LP_ORACLE;
|
|
366
296
|
}
|
|
367
297
|
|
|
368
|
-
function _getBPTWeightedPriceFeedParams(address token, address balancerPf)
|
|
369
|
-
internal
|
|
370
|
-
returns (PriceFeedParams[] memory pfParams)
|
|
371
|
-
{
|
|
372
|
-
address pool = BPTWeightedPriceFeed(balancerPf).lpContract();
|
|
373
|
-
|
|
374
|
-
uint256[] memory weights = IBalancerWeightedPool(pool).getNormalizedWeights();
|
|
375
|
-
uint256[] memory indices = _sort(weights);
|
|
376
|
-
|
|
377
|
-
uint256 numAssets = weights.length;
|
|
378
|
-
pfParams = new PriceFeedParams[](numAssets);
|
|
379
|
-
|
|
380
|
-
for (uint256 i = 0; i < numAssets; ++i) {
|
|
381
|
-
(address pf, uint32 sp) = _getBPTWeightedPriceFeedUPF(balancerPf, i);
|
|
382
|
-
pfParams[indices[i]].stalenessPeriod = sp;
|
|
383
|
-
pfParams[indices[i]].priceFeed = _migrateFromOld(token, pf, sp);
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
/// @dev Sorts array in-place in ascending order, also returns the resulting permutation
|
|
388
|
-
function _sort(uint256[] memory data) internal pure returns (uint256[] memory indices) {
|
|
389
|
-
uint256 len = data.length;
|
|
390
|
-
indices = new uint256[](len);
|
|
391
|
-
for (uint256 i; i < len; ++i) {
|
|
392
|
-
indices[i] = i;
|
|
393
|
-
}
|
|
394
|
-
_quickSort(data, indices, 0, len - 1);
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
/// @dev Quick sort sub-routine
|
|
398
|
-
function _quickSort(uint256[] memory data, uint256[] memory indices, uint256 low, uint256 high) private pure {
|
|
399
|
-
unchecked {
|
|
400
|
-
if (low < high) {
|
|
401
|
-
uint256 pVal = data[(low + high) / 2];
|
|
402
|
-
|
|
403
|
-
uint256 i = low;
|
|
404
|
-
uint256 j = high;
|
|
405
|
-
for (;;) {
|
|
406
|
-
while (data[i] < pVal) i++;
|
|
407
|
-
while (data[j] > pVal) j--;
|
|
408
|
-
if (i >= j) break;
|
|
409
|
-
if (data[i] != data[j]) {
|
|
410
|
-
(data[i], data[j]) = (data[j], data[i]);
|
|
411
|
-
(indices[i], indices[j]) = (indices[j], indices[i]);
|
|
412
|
-
}
|
|
413
|
-
i++;
|
|
414
|
-
j--;
|
|
415
|
-
}
|
|
416
|
-
if (low < j) _quickSort(data, indices, low, j);
|
|
417
|
-
j++;
|
|
418
|
-
if (j < high) _quickSort(data, indices, j, high);
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
function _getBPTWeightedPriceFeedUPF(address balancerPf, uint256 pfNum)
|
|
424
|
-
internal
|
|
425
|
-
view
|
|
426
|
-
returns (address priceFeed, uint32 stalenessPeriod)
|
|
427
|
-
{
|
|
428
|
-
if (pfNum == 0) {
|
|
429
|
-
return (BPTWeightedPriceFeed(balancerPf).priceFeed0(), BPTWeightedPriceFeed(balancerPf).stalenessPeriod0());
|
|
430
|
-
} else if (pfNum == 1) {
|
|
431
|
-
return (BPTWeightedPriceFeed(balancerPf).priceFeed1(), BPTWeightedPriceFeed(balancerPf).stalenessPeriod1());
|
|
432
|
-
} else if (pfNum == 2) {
|
|
433
|
-
return (BPTWeightedPriceFeed(balancerPf).priceFeed2(), BPTWeightedPriceFeed(balancerPf).stalenessPeriod2());
|
|
434
|
-
} else if (pfNum == 3) {
|
|
435
|
-
return (BPTWeightedPriceFeed(balancerPf).priceFeed3(), BPTWeightedPriceFeed(balancerPf).stalenessPeriod3());
|
|
436
|
-
} else if (pfNum == 4) {
|
|
437
|
-
return (BPTWeightedPriceFeed(balancerPf).priceFeed4(), BPTWeightedPriceFeed(balancerPf).stalenessPeriod4());
|
|
438
|
-
} else if (pfNum == 5) {
|
|
439
|
-
return (BPTWeightedPriceFeed(balancerPf).priceFeed5(), BPTWeightedPriceFeed(balancerPf).stalenessPeriod5());
|
|
440
|
-
} else if (pfNum == 6) {
|
|
441
|
-
return (BPTWeightedPriceFeed(balancerPf).priceFeed6(), BPTWeightedPriceFeed(balancerPf).stalenessPeriod6());
|
|
442
|
-
} else if (pfNum == 7) {
|
|
443
|
-
return (BPTWeightedPriceFeed(balancerPf).priceFeed7(), BPTWeightedPriceFeed(balancerPf).stalenessPeriod7());
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
|
|
447
298
|
function _updateRedstonePriceFeed(address priceFeed) internal {
|
|
448
299
|
uint256 initialTS = block.timestamp;
|
|
449
300
|
|
package/package.json
CHANGED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
// Gearbox Protocol. Generalized leverage for DeFi protocols
|
|
3
|
-
// (c) Gearbox Foundation, 2025.
|
|
4
|
-
pragma solidity ^0.8.23;
|
|
5
|
-
|
|
6
|
-
import {BPTWeightedPriceFeed} from "@gearbox-protocol/oracles-v3/contracts/oracles/balancer/BPTWeightedPriceFeed.sol";
|
|
7
|
-
import {LPPriceFeedSerializer} from "./LPPriceFeedSerializer.sol";
|
|
8
|
-
|
|
9
|
-
contract BPTWeightedPriceFeedSerializer is LPPriceFeedSerializer {
|
|
10
|
-
function serialize(address priceFeed) public view override returns (bytes memory) {
|
|
11
|
-
BPTWeightedPriceFeed pf = BPTWeightedPriceFeed(priceFeed);
|
|
12
|
-
|
|
13
|
-
uint256[8] memory weights = [
|
|
14
|
-
pf.weight0(),
|
|
15
|
-
pf.weight1(),
|
|
16
|
-
pf.weight2(),
|
|
17
|
-
pf.weight3(),
|
|
18
|
-
pf.weight4(),
|
|
19
|
-
pf.weight5(),
|
|
20
|
-
pf.weight6(),
|
|
21
|
-
pf.weight7()
|
|
22
|
-
];
|
|
23
|
-
|
|
24
|
-
return abi.encode(super.serialize(priceFeed), pf.vault(), pf.poolId(), weights);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: UNLICENSED
|
|
2
|
-
// Gearbox Protocol. Generalized leverage for DeFi protocols
|
|
3
|
-
// (c) Gearbox Foundation, 2024.
|
|
4
|
-
pragma solidity ^0.8.17;
|
|
5
|
-
|
|
6
|
-
import {Test} from "forge-std/Test.sol";
|
|
7
|
-
|
|
8
|
-
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
|
|
9
|
-
|
|
10
|
-
import {IAddressProvider} from "@gearbox-protocol/permissionless/contracts/interfaces/IAddressProvider.sol";
|
|
11
|
-
|
|
12
|
-
import {
|
|
13
|
-
AP_ACL,
|
|
14
|
-
AP_CONTRACTS_REGISTER,
|
|
15
|
-
NO_VERSION_CONTROL
|
|
16
|
-
} from "@gearbox-protocol/permissionless/contracts/libraries/ContractLiterals.sol";
|
|
17
|
-
|
|
18
|
-
import {ACL} from "@gearbox-protocol/permissionless/contracts/market/ACL.sol";
|
|
19
|
-
import {IACLLegacy} from "@gearbox-protocol/permissionless/contracts/market/legacy/MarketConfiguratorLegacy.sol";
|
|
20
|
-
import {IContractsRegister} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IContractsRegister.sol";
|
|
21
|
-
|
|
22
|
-
abstract contract ForkTest is Test {
|
|
23
|
-
IAddressProvider addressProvider;
|
|
24
|
-
ACL acl;
|
|
25
|
-
IACLLegacy aclLegacy;
|
|
26
|
-
IContractsRegister register;
|
|
27
|
-
address configurator;
|
|
28
|
-
|
|
29
|
-
modifier onlyFork() {
|
|
30
|
-
if (address(addressProvider) != address(0)) _;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function _createFork() internal {
|
|
34
|
-
string memory rpcUrl = vm.envOr("FORK_RPC_URL", string(""));
|
|
35
|
-
if (bytes(rpcUrl).length == 0) return;
|
|
36
|
-
|
|
37
|
-
uint256 blockNumber = vm.envOr("FORK_BLOCK_NUMBER", type(uint256).max);
|
|
38
|
-
if (blockNumber == type(uint256).max) {
|
|
39
|
-
vm.createSelectFork(rpcUrl);
|
|
40
|
-
} else {
|
|
41
|
-
vm.createSelectFork(rpcUrl, blockNumber);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
addressProvider = IAddressProvider(vm.envAddress("FORK_ADDRESS_PROVIDER"));
|
|
45
|
-
|
|
46
|
-
aclLegacy = IACLLegacy(addressProvider.getAddressOrRevert(AP_ACL, NO_VERSION_CONTROL));
|
|
47
|
-
register = IContractsRegister(addressProvider.getAddressOrRevert(AP_CONTRACTS_REGISTER, NO_VERSION_CONTROL));
|
|
48
|
-
configurator = Ownable(address(aclLegacy)).owner();
|
|
49
|
-
acl = new ACL(configurator);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function _grantRole(bytes32 role, address account) internal {
|
|
53
|
-
acl.grantRole(role, account);
|
|
54
|
-
if (role == "PAUSABLE_ADMIN") IACLLegacy(aclLegacy).addPausableAdmin(account);
|
|
55
|
-
else if (role == "UNPAUSABLE_ADMIN") IACLLegacy(aclLegacy).addUnpausableAdmin(account);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function _revokeRole(bytes32 role, address account) internal {
|
|
59
|
-
acl.revokeRole(role, account);
|
|
60
|
-
if (role == "PAUSABLE_ADMIN") IACLLegacy(aclLegacy).removePausableAdmin(account);
|
|
61
|
-
else if (role == "UNPAUSABLE_ADMIN") IACLLegacy(aclLegacy).removeUnpausableAdmin(account);
|
|
62
|
-
}
|
|
63
|
-
}
|