From e7ccddf7178acbe738e0b58aa164ddf0bb38c834 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Sat, 22 Mar 2025 17:07:43 +0530 Subject: [PATCH 01/25] feat: add emode and remove using data provider --- foundry.toml | 2 +- scripts/RiskStewardsBase.s.sol | 24 +- scripts/deploy/DeployCapInjector.s.sol | 53 ++-- scripts/deploy/DeployRateInjector.s.sol | 49 ++-- scripts/deploy/DeployStewards.s.sol | 81 +++--- src/contracts/EdgeRiskStewardCaps.sol | 17 +- src/contracts/EdgeRiskStewardRates.sol | 17 +- src/contracts/RiskSteward.sol | 217 +++++++++++---- src/interfaces/IRiskSteward.sol | 104 ++++++- tests/AaveStewardsInjectorCaps.t.sol | 22 +- tests/AaveStewardsInjectorRates.t.sol | 24 +- tests/EdgeRiskStewardCaps.t.sol | 9 +- tests/EdgeRiskStewardRates.t.sol | 9 +- tests/RiskSteward.t.sol | 348 +++++++++++------------- tests/RiskStewardCapo.t.sol | 27 +- 15 files changed, 578 insertions(+), 425 deletions(-) diff --git a/foundry.toml b/foundry.toml index 6e326b1..e648ae3 100644 --- a/foundry.toml +++ b/foundry.toml @@ -3,7 +3,7 @@ src = 'src' test = 'tests' script = 'scripts' out = 'out' -solc = '0.8.22' +solc = '0.8.24' optimizer = true optimizer_runs = 200 libs = ['lib'] diff --git a/scripts/RiskStewardsBase.s.sol b/scripts/RiskStewardsBase.s.sol index 9bc0c9b..e955168 100644 --- a/scripts/RiskStewardsBase.s.sol +++ b/scripts/RiskStewardsBase.s.sol @@ -95,26 +95,26 @@ abstract contract RiskStewardsBase is ProtocolV3TestBase { IRiskSteward.Config memory riskConfig = STEWARD.getRiskConfig(); if (capUpdates.length != 0) { - timelocks[index++] = riskConfig.supplyCap.minDelay; - timelocks[index++] = riskConfig.borrowCap.minDelay; + timelocks[index++] = riskConfig.capConfig.supplyCap.minDelay; + timelocks[index++] = riskConfig.capConfig.borrowCap.minDelay; } if (collateralUpdates.length != 0) { - timelocks[index++] = riskConfig.ltv.minDelay; - timelocks[index++] = riskConfig.liquidationThreshold.minDelay; - timelocks[index++] = riskConfig.liquidationBonus.minDelay; - timelocks[index++] = riskConfig.debtCeiling.minDelay; + timelocks[index++] = riskConfig.collateralConfig.ltv.minDelay; + timelocks[index++] = riskConfig.collateralConfig.liquidationThreshold.minDelay; + timelocks[index++] = riskConfig.collateralConfig.liquidationBonus.minDelay; + timelocks[index++] = riskConfig.collateralConfig.debtCeiling.minDelay; } if (rateUpdates.length != 0) { - timelocks[index++] = riskConfig.baseVariableBorrowRate.minDelay; - timelocks[index++] = riskConfig.optimalUsageRatio.minDelay; - timelocks[index++] = riskConfig.variableRateSlope1.minDelay; - timelocks[index++] = riskConfig.variableRateSlope2.minDelay; + timelocks[index++] = riskConfig.rateConfig.baseVariableBorrowRate.minDelay; + timelocks[index++] = riskConfig.rateConfig.optimalUsageRatio.minDelay; + timelocks[index++] = riskConfig.rateConfig.variableRateSlope1.minDelay; + timelocks[index++] = riskConfig.rateConfig.variableRateSlope2.minDelay; } if (lstPriceCapUpdates.length != 0) { - timelocks[index++] = riskConfig.priceCapLst.minDelay; + timelocks[index++] = riskConfig.priceCapConfig.priceCapLst.minDelay; } if (stablePriceCapUpdates.length != 0) { - timelocks[index++] = riskConfig.priceCapStable.minDelay; + timelocks[index++] = riskConfig.priceCapConfig.priceCapStable.minDelay; } uint40 maxTimelock = 0; for (uint256 i = 0; i < timelocks.length; i++) { diff --git a/scripts/deploy/DeployCapInjector.s.sol b/scripts/deploy/DeployCapInjector.s.sol index 5cbce81..94a1b5e 100644 --- a/scripts/deploy/DeployCapInjector.s.sol +++ b/scripts/deploy/DeployCapInjector.s.sol @@ -6,28 +6,27 @@ import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; import {AaveV3Arbitrum, AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; import {ICreate3Factory} from 'solidity-utils/contracts/create3/interfaces/ICreate3Factory.sol'; -import {IOwnable} from 'aave-address-book/common/IOwnable.sol'; -import {EdgeRiskStewardCaps, IRiskSteward, IPoolDataProvider, IEngine} from '../../src/contracts/EdgeRiskStewardCaps.sol'; +import {EdgeRiskStewardCaps, IRiskSteward} from '../../src/contracts/EdgeRiskStewardCaps.sol'; import {AaveStewardInjectorCaps} from '../../src/contracts/AaveStewardInjectorCaps.sol'; library DeployStewardContracts { address constant EDGE_RISK_ORACLE = 0x861eeAdB55E41f161F31Acb1BFD4c70E3a964Aed; function _deployRiskStewards( - address poolDataProvider, + address poolAddressesProvider, address configEngine, address riskCouncil, address governance ) internal returns (address) { address riskSteward = address( new EdgeRiskStewardCaps( - IPoolDataProvider(poolDataProvider), - IEngine(configEngine), + poolAddressesProvider, + configEngine, riskCouncil, + governance, _getRiskConfig() ) ); - IOwnable(riskSteward).transferOwnership(governance); return riskSteward; } @@ -53,27 +52,31 @@ library DeployStewardContracts { function _getRiskConfig() internal pure returns (IRiskSteward.Config memory) { return IRiskSteward.Config({ - ltv: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 25}), - liquidationThreshold: IRiskSteward.RiskParamConfig({ - minDelay: 3 days, - maxPercentChange: 25 + collateralConfig: IRiskSteward.CollateralConfig({ + ltv: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), + liquidationThreshold: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), + liquidationBonus: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), + debtCeiling: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00}) }), - liquidationBonus: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), - supplyCap: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 30_00}), - borrowCap: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 30_00}), - debtCeiling: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00}), - baseVariableBorrowRate: IRiskSteward.RiskParamConfig({ - minDelay: 3 days, - maxPercentChange: 50 + eModeConfig: IRiskSteward.EmodeConfig({ + ltv: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), + liquidationThreshold: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), + liquidationBonus: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}) }), - variableRateSlope1: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), - variableRateSlope2: IRiskSteward.RiskParamConfig({ - minDelay: 3 days, - maxPercentChange: 5_00 + rateConfig: IRiskSteward.RateConfig({ + baseVariableBorrowRate: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 1_00}), + variableRateSlope1: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 1_00}), + variableRateSlope2: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00}), + optimalUsageRatio: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 3_00}) }), - optimalUsageRatio: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 3_00}), - priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 5_00}), - priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}) + capConfig: IRiskSteward.CapConfig({ + supplyCap: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 30_00}), + borrowCap: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 30_00}) + }), + priceCapConfig: IRiskSteward.PriceCapConfig({ + priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 5_00}), + priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}) + }) }); } } @@ -89,7 +92,7 @@ contract DeployArbitrum is ArbitrumScript { .predictAddress(msg.sender, salt); address riskSteward = DeployStewardContracts._deployRiskStewards( - address(AaveV3Arbitrum.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Arbitrum.POOL_ADDRESSES_PROVIDER), AaveV3Arbitrum.CONFIG_ENGINE, predictedStewardsInjector, GovernanceV3Arbitrum.EXECUTOR_LVL_1 diff --git a/scripts/deploy/DeployRateInjector.s.sol b/scripts/deploy/DeployRateInjector.s.sol index 0fe52d1..9262049 100644 --- a/scripts/deploy/DeployRateInjector.s.sol +++ b/scripts/deploy/DeployRateInjector.s.sol @@ -6,8 +6,7 @@ import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; import {AaveV3EthereumLido, AaveV3EthereumLidoAssets} from 'aave-address-book/AaveV3EthereumLido.sol'; import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; import {ICreate3Factory} from 'solidity-utils/contracts/create3/interfaces/ICreate3Factory.sol'; -import {IOwnable} from 'aave-address-book/common/IOwnable.sol'; -import {EdgeRiskStewardRates, IRiskSteward, IPoolDataProvider, IEngine} from '../../src/contracts/EdgeRiskStewardRates.sol'; +import {EdgeRiskStewardRates, IRiskSteward} from '../../src/contracts/EdgeRiskStewardRates.sol'; import {AaveStewardInjectorRates} from '../../src/contracts/AaveStewardInjectorRates.sol'; library DeployStewardContracts { @@ -21,13 +20,13 @@ library DeployStewardContracts { ) internal returns (address) { address riskSteward = address( new EdgeRiskStewardRates( - IPoolDataProvider(poolDataProvider), - IEngine(configEngine), + poolDataProvider, + configEngine, riskCouncil, + governance, _getRiskConfig() ) ); - IOwnable(riskSteward).transferOwnership(governance); return riskSteward; } @@ -51,27 +50,31 @@ library DeployStewardContracts { function _getRiskConfig() internal pure returns (IRiskSteward.Config memory) { return IRiskSteward.Config({ - ltv: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 25}), - liquidationThreshold: IRiskSteward.RiskParamConfig({ - minDelay: 1 days, - maxPercentChange: 25 + collateralConfig: IRiskSteward.CollateralConfig({ + ltv: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}), + liquidationThreshold: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}), + liquidationBonus: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}), + debtCeiling: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 20_00}) }), - liquidationBonus: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}), - supplyCap: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 100_00}), - borrowCap: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 100_00}), - debtCeiling: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 20_00}), - baseVariableBorrowRate: IRiskSteward.RiskParamConfig({ - minDelay: 1 days, - maxPercentChange: 50 + eModeConfig: IRiskSteward.EmodeConfig({ + ltv: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}), + liquidationThreshold: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}), + liquidationBonus: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}) }), - variableRateSlope1: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}), - variableRateSlope2: IRiskSteward.RiskParamConfig({ - minDelay: 1 days, - maxPercentChange: 5_00 + rateConfig: IRiskSteward.RateConfig({ + baseVariableBorrowRate: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}), + variableRateSlope1: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 1_00}), + variableRateSlope2: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 5_00}), + optimalUsageRatio: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 3_00}) }), - optimalUsageRatio: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 3_00}), - priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 5_00}), - priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}) + capConfig: IRiskSteward.CapConfig({ + supplyCap: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 100_00}), + borrowCap: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 100_00}) + }), + priceCapConfig: IRiskSteward.PriceCapConfig({ + priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 5_00}), + priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}) + }) }); } } diff --git a/scripts/deploy/DeployStewards.s.sol b/scripts/deploy/DeployStewards.s.sol index 69e66eb..3ac8c1a 100644 --- a/scripts/deploy/DeployStewards.s.sol +++ b/scripts/deploy/DeployStewards.s.sol @@ -30,52 +30,55 @@ import {AaveV3Sonic} from 'aave-address-book/AaveV3Sonic.sol'; import {GovernanceV3Sonic} from 'aave-address-book/GovernanceV3Sonic.sol'; import {AaveV3Celo} from 'aave-address-book/AaveV3Celo.sol'; import {GovernanceV3Celo} from 'aave-address-book/GovernanceV3Celo.sol'; -import {IOwnable} from 'aave-address-book/common/IOwnable.sol'; -import {RiskSteward, IRiskSteward, IPoolDataProvider, IEngine} from '../../src/contracts/RiskSteward.sol'; +import {RiskSteward, IRiskSteward} from '../../src/contracts/RiskSteward.sol'; library DeployRiskStewards { function _deployRiskStewards( - address poolDataProvider, + address addressesProvider, address configEngine, address riskCouncil, address governance ) internal returns (address) { address riskSteward = address( new RiskSteward( - IPoolDataProvider(poolDataProvider), - IEngine(configEngine), + addressesProvider, + configEngine, riskCouncil, + governance, _getRiskConfig() ) ); - IOwnable(riskSteward).transferOwnership(governance); return riskSteward; } function _getRiskConfig() internal pure returns (IRiskSteward.Config memory) { return IRiskSteward.Config({ - ltv: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 25}), - liquidationThreshold: IRiskSteward.RiskParamConfig({ - minDelay: 3 days, - maxPercentChange: 25 + collateralConfig: IRiskSteward.CollateralConfig({ + ltv: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), + liquidationThreshold: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), + liquidationBonus: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), + debtCeiling: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00}) }), - liquidationBonus: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), - supplyCap: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 100_00}), - borrowCap: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 100_00}), - debtCeiling: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00}), - baseVariableBorrowRate: IRiskSteward.RiskParamConfig({ - minDelay: 3 days, - maxPercentChange: 50 + eModeConfig: IRiskSteward.EmodeConfig({ + ltv: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), + liquidationThreshold: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), + liquidationBonus: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}) }), - variableRateSlope1: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), - variableRateSlope2: IRiskSteward.RiskParamConfig({ - minDelay: 3 days, - maxPercentChange: 5_00 + rateConfig: IRiskSteward.RateConfig({ + baseVariableBorrowRate: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 1_00}), + variableRateSlope1: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 1_00}), + variableRateSlope2: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00}), + optimalUsageRatio: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 3_00}) }), - optimalUsageRatio: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 3_00}), - priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 5_00}), - priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}) + capConfig: IRiskSteward.CapConfig({ + supplyCap: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 100_00}), + borrowCap: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 100_00}) + }), + priceCapConfig: IRiskSteward.PriceCapConfig({ + priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 5_00}), + priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}) + }) }); } } @@ -85,7 +88,7 @@ contract DeployEthereum is EthereumScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Ethereum.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Ethereum.POOL_ADDRESSES_PROVIDER), AaveV3Ethereum.CONFIG_ENGINE, 0x47c71dFEB55Ebaa431Ae3fbF99Ea50e0D3d30fA8, // eth-risk-council GovernanceV3Ethereum.EXECUTOR_LVL_1 @@ -99,7 +102,7 @@ contract DeployEthereumLido is EthereumScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3EthereumLido.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3EthereumLido.POOL_ADDRESSES_PROVIDER), AaveV3EthereumLido.CONFIG_ENGINE, 0x47c71dFEB55Ebaa431Ae3fbF99Ea50e0D3d30fA8, // eth-risk-council GovernanceV3Ethereum.EXECUTOR_LVL_1 @@ -113,7 +116,7 @@ contract DeployEthereumEtherFi is EthereumScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3EthereumEtherFi.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3EthereumEtherFi.POOL_ADDRESSES_PROVIDER), AaveV3EthereumEtherFi.CONFIG_ENGINE, 0x47c71dFEB55Ebaa431Ae3fbF99Ea50e0D3d30fA8, // eth-risk-council GovernanceV3Ethereum.EXECUTOR_LVL_1 @@ -127,7 +130,7 @@ contract DeployPolygon is PolygonScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Polygon.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Polygon.POOL_ADDRESSES_PROVIDER), AaveV3Polygon.CONFIG_ENGINE, 0x2C40FB1ACe63084fc0bB95F83C31B5854C6C4cB5, // pol-risk-council GovernanceV3Polygon.EXECUTOR_LVL_1 @@ -141,7 +144,7 @@ contract DeployArbitrum is ArbitrumScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Arbitrum.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Arbitrum.POOL_ADDRESSES_PROVIDER), AaveV3Arbitrum.CONFIG_ENGINE, 0x3Be327F22eB4BD8042e6944073b8826dCf357Aa2, // arb-risk-council GovernanceV3Arbitrum.EXECUTOR_LVL_1 @@ -155,7 +158,7 @@ contract DeployOptimism is OptimismScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Optimism.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Optimism.POOL_ADDRESSES_PROVIDER), AaveV3Optimism.CONFIG_ENGINE, 0xCb86256A994f0c505c5e15c75BF85fdFEa0F2a56, // opt-risk-council GovernanceV3Optimism.EXECUTOR_LVL_1 @@ -169,7 +172,7 @@ contract DeployAvalanche is AvalancheScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Avalanche.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Avalanche.POOL_ADDRESSES_PROVIDER), AaveV3Avalanche.CONFIG_ENGINE, 0xCa66149425E7DC8f81276F6D80C4b486B9503D1a, // ava-risk-council GovernanceV3Avalanche.EXECUTOR_LVL_1 @@ -183,7 +186,7 @@ contract DeployScroll is ScrollScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Scroll.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Scroll.POOL_ADDRESSES_PROVIDER), AaveV3Scroll.CONFIG_ENGINE, 0x611439a74546888c3535B4dd119A5Cbb9f5332EA, // scroll-risk-council GovernanceV3Scroll.EXECUTOR_LVL_1 @@ -197,7 +200,7 @@ contract DeployGnosis is GnosisScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Gnosis.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Gnosis.POOL_ADDRESSES_PROVIDER), AaveV3Gnosis.CONFIG_ENGINE, 0xF221B08dD10e0C68D74F035764931Baa3b030481, // gnosis-risk-council GovernanceV3Gnosis.EXECUTOR_LVL_1 @@ -211,7 +214,7 @@ contract DeployBNB is BNBScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3BNB.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3BNB.POOL_ADDRESSES_PROVIDER), AaveV3BNB.CONFIG_ENGINE, 0x126dc589cc75f17385dD95516F3F1788d862E7bc, // bnb-risk-council GovernanceV3BNB.EXECUTOR_LVL_1 @@ -225,7 +228,7 @@ contract DeployBase is BaseScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Base.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Base.POOL_ADDRESSES_PROVIDER), AaveV3Base.CONFIG_ENGINE, 0xfbeB4AcB31340bA4de9C87B11dfBf7e2bc8C0bF1, // base-risk-council GovernanceV3Base.EXECUTOR_LVL_1 @@ -239,7 +242,7 @@ contract DeployMetis is MetisScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Metis.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Metis.POOL_ADDRESSES_PROVIDER), AaveV3Metis.CONFIG_ENGINE, 0x0f547846920C34E70FBE4F3d87E46452a3FeAFfa, // metis-risk-council GovernanceV3Metis.EXECUTOR_LVL_1 @@ -253,7 +256,7 @@ contract DeployLinea is LineaScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Linea.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Linea.POOL_ADDRESSES_PROVIDER), AaveV3Linea.CONFIG_ENGINE, 0xF092A5aC5E284E7c433dAFE5b8B138bFcA53a4Ee, // linea-risk-council GovernanceV3Linea.EXECUTOR_LVL_1 @@ -267,7 +270,7 @@ contract DeploySonic is SonicScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Sonic.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Sonic.POOL_ADDRESSES_PROVIDER), AaveV3Sonic.CONFIG_ENGINE, 0x1dE39A17a9Fa8c76899fff37488482EEb7835d04, // sonic-risk-council GovernanceV3Sonic.EXECUTOR_LVL_1 @@ -281,7 +284,7 @@ contract DeployCelo is SonicScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Celo.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Celo.POOL_ADDRESSES_PROVIDER), AaveV3Celo.CONFIG_ENGINE, 0xd85786B5FC61E2A0c0a3144a33A0fC70646a99f6, // celo-risk-council GovernanceV3Celo.EXECUTOR_LVL_1 diff --git a/src/contracts/EdgeRiskStewardCaps.sol b/src/contracts/EdgeRiskStewardCaps.sol index 9a17487..4f9156a 100644 --- a/src/contracts/EdgeRiskStewardCaps.sol +++ b/src/contracts/EdgeRiskStewardCaps.sol @@ -11,17 +11,19 @@ import './RiskSteward.sol'; */ contract EdgeRiskStewardCaps is RiskSteward { /** - * @param poolDataProvider The pool data provider of the pool to be controlled by the steward + * @param poolAddressesProvider The pool addresses provider of the pool to be controlled by the steward * @param engine the config engine to be used by the steward * @param riskCouncil the safe address of the council being able to interact with the steward + * @param owner the owner of the risk steward being able to set configs and mark items as restricted * @param riskConfig the risk configuration to setup for each individual risk param */ constructor( - IPoolDataProvider poolDataProvider, - IEngine engine, + address poolAddressesProvider, + address engine, address riskCouncil, + address owner, Config memory riskConfig - ) RiskSteward(poolDataProvider, engine, riskCouncil, riskConfig) {} + ) RiskSteward(poolAddressesProvider, engine, riskCouncil, owner, riskConfig) {} /// @inheritdoc IRiskSteward function updateRates( @@ -37,6 +39,13 @@ contract EdgeRiskStewardCaps is RiskSteward { revert UpdateNotAllowed(); } + /// @inheritdoc IRiskSteward + function updateEModeCategories( + IEngine.EModeCategoryUpdate[] calldata + ) external virtual override onlyRiskCouncil { + revert UpdateNotAllowed(); + } + /// @inheritdoc IRiskSteward function updateLstPriceCaps( PriceCapLstUpdate[] calldata diff --git a/src/contracts/EdgeRiskStewardRates.sol b/src/contracts/EdgeRiskStewardRates.sol index 924f220..c80cb0d 100644 --- a/src/contracts/EdgeRiskStewardRates.sol +++ b/src/contracts/EdgeRiskStewardRates.sol @@ -11,17 +11,19 @@ import './RiskSteward.sol'; */ contract EdgeRiskStewardRates is RiskSteward { /** - * @param poolDataProvider The pool data provider of the pool to be controlled by the steward + * @param poolAddressesProvider The pool addresses provider of the pool to be controlled by the steward * @param engine the config engine to be used by the steward * @param riskCouncil the safe address of the council being able to interact with the steward + * @param owner the owner of the risk steward being able to set configs and mark items as restricted * @param riskConfig the risk configuration to setup for each individual risk param */ constructor( - IPoolDataProvider poolDataProvider, - IEngine engine, + address poolAddressesProvider, + address engine, address riskCouncil, + address owner, Config memory riskConfig - ) RiskSteward(poolDataProvider, engine, riskCouncil, riskConfig) {} + ) RiskSteward(poolAddressesProvider, engine, riskCouncil, owner, riskConfig) {} /// @inheritdoc IRiskSteward function updateCaps(IEngine.CapsUpdate[] calldata) external virtual override onlyRiskCouncil { @@ -35,6 +37,13 @@ contract EdgeRiskStewardRates is RiskSteward { revert UpdateNotAllowed(); } + /// @inheritdoc IRiskSteward + function updateEModeCategories( + IEngine.EModeCategoryUpdate[] calldata + ) external virtual override onlyRiskCouncil { + revert UpdateNotAllowed(); + } + /// @inheritdoc IRiskSteward function updateLstPriceCaps( PriceCapLstUpdate[] calldata diff --git a/src/contracts/RiskSteward.sol b/src/contracts/RiskSteward.sol index 909e752..21bc3e1 100644 --- a/src/contracts/RiskSteward.sol +++ b/src/contracts/RiskSteward.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import {IPoolDataProvider} from 'aave-address-book/AaveV3.sol'; +import {ReserveConfiguration, DataTypes} from 'aave-v3-origin/src/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; +import {IPool, IPoolAddressesProvider} from 'aave-address-book/AaveV3.sol'; import {Address} from 'openzeppelin-contracts/contracts/utils/Address.sol'; import {SafeCast} from 'openzeppelin-contracts/contracts/utils/math/SafeCast.sol'; import {EngineFlags} from 'aave-v3-origin/src/contracts/extensions/v3-config-engine/EngineFlags.sol'; @@ -19,6 +20,7 @@ import {IPriceCapAdapterStable} from 'aave-capo/interfaces/IPriceCapAdapterStabl * This contract can update the following risk params: caps, ltv, liqThreshold, liqBonus, debtCeiling, interest rates params. */ contract RiskSteward is Ownable, IRiskSteward { + using ReserveConfiguration for DataTypes.ReserveConfigurationMap; using Address for address; using SafeCast for uint256; using SafeCast for int256; @@ -27,7 +29,7 @@ contract RiskSteward is Ownable, IRiskSteward { IEngine public immutable CONFIG_ENGINE; /// @inheritdoc IRiskSteward - IPoolDataProvider public immutable POOL_DATA_PROVIDER; + IPoolAddressesProvider public immutable ADDRESSES_PROVIDER; /// @inheritdoc IRiskSteward address public immutable RISK_COUNCIL; @@ -36,10 +38,12 @@ contract RiskSteward is Ownable, IRiskSteward { Config internal _riskConfig; - mapping(address => Debounce) internal _timelocks; + mapping(bytes32 id => Debounce) internal _timelocks; mapping(address => bool) internal _restrictedAddresses; + mapping(uint8 => bool) internal _restrictedEModes; + /** * @dev Modifier preventing anyone, but the council to update risk params. */ @@ -49,19 +53,21 @@ contract RiskSteward is Ownable, IRiskSteward { } /** - * @param poolDataProvider The pool data provider of the pool to be controlled by the steward + * @param poolAddressesProvider The pool addresses provider of the pool to be controlled by the steward * @param engine the config engine to be used by the steward * @param riskCouncil the safe address of the council being able to interact with the steward + * @param owner the owner of the risk steward being able to set configs and mark items as restricted * @param riskConfig the risk configuration to setup for each individual risk param */ constructor( - IPoolDataProvider poolDataProvider, - IEngine engine, + address poolAddressesProvider, + address engine, address riskCouncil, + address owner, Config memory riskConfig - ) Ownable(msg.sender) { - POOL_DATA_PROVIDER = poolDataProvider; - CONFIG_ENGINE = engine; + ) Ownable(owner) { + ADDRESSES_PROVIDER = IPoolAddressesProvider(poolAddressesProvider); + CONFIG_ENGINE = IEngine(engine); RISK_COUNCIL = riskCouncil; _riskConfig = riskConfig; } @@ -88,6 +94,14 @@ contract RiskSteward is Ownable, IRiskSteward { _updateCollateralSide(collateralUpdates); } + /// @inheritdoc IRiskSteward + function updateEModeCategories( + IEngine.EModeCategoryUpdate[] calldata eModeCategoryUpdates + ) external virtual onlyRiskCouncil { + _validateEModeCategoryUpdate(eModeCategoryUpdates); + _updateEModeCategories(eModeCategoryUpdates); + } + /// @inheritdoc IRiskSteward function updateLstPriceCaps( PriceCapLstUpdate[] calldata priceCapUpdates @@ -106,7 +120,12 @@ contract RiskSteward is Ownable, IRiskSteward { /// @inheritdoc IRiskSteward function getTimelock(address asset) external view returns (Debounce memory) { - return _timelocks[asset]; + return _timelocks[bytes20(asset)]; + } + + /// @inheritdoc IRiskSteward + function getEModeTimelock(uint8 eModeCategoryId) external view returns (Debounce memory) { + return _timelocks[bytes32(uint256(eModeCategoryId))]; } /// @inheritdoc IRiskSteward @@ -131,6 +150,17 @@ contract RiskSteward is Ownable, IRiskSteward { emit AddressRestricted(contractAddress, isRestricted); } + /// @inheritdoc IRiskSteward + function isEModeCategoryRestricted(uint8 eModeCategoryId) external view returns (bool) { + return _restrictedEModes[eModeCategoryId]; + } + + /// @inheritdoc IRiskSteward + function setEModeCategoryRestricted(uint8 eModeCategoryId, bool isRestricted) external onlyOwner { + _restrictedEModes[eModeCategoryId] = isRestricted; + emit EModeRestricted(eModeCategoryId, isRestricted); + } + /** * @notice method to validate the caps update * @param capsUpdate list containing the new supply, borrow caps of the assets @@ -145,16 +175,14 @@ contract RiskSteward is Ownable, IRiskSteward { if (capsUpdate[i].supplyCap == 0 || capsUpdate[i].borrowCap == 0) revert InvalidUpdateToZero(); - (uint256 currentBorrowCap, uint256 currentSupplyCap) = POOL_DATA_PROVIDER.getReserveCaps( - capsUpdate[i].asset - ); + (uint256 currentBorrowCap, uint256 currentSupplyCap) = IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getCaps(); _validateParamUpdate( ParamUpdateValidationInput({ currentValue: currentSupplyCap, newValue: capsUpdate[i].supplyCap, - lastUpdated: _timelocks[asset].supplyCapLastUpdated, - riskConfig: _riskConfig.supplyCap, + lastUpdated: _timelocks[bytes20(asset)].supplyCapLastUpdated, + riskConfig: _riskConfig.capConfig.supplyCap, isChangeRelative: true }) ); @@ -162,8 +190,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentBorrowCap, newValue: capsUpdate[i].borrowCap, - lastUpdated: _timelocks[asset].borrowCapLastUpdated, - riskConfig: _riskConfig.borrowCap, + lastUpdated: _timelocks[bytes20(asset)].borrowCapLastUpdated, + riskConfig: _riskConfig.capConfig.borrowCap, isChangeRelative: true }) ); @@ -192,8 +220,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentOptimalUsageRatio, newValue: ratesUpdate[i].params.optimalUsageRatio, - lastUpdated: _timelocks[asset].optimalUsageRatioLastUpdated, - riskConfig: _riskConfig.optimalUsageRatio, + lastUpdated: _timelocks[bytes20(asset)].optimalUsageRatioLastUpdated, + riskConfig: _riskConfig.rateConfig.optimalUsageRatio, isChangeRelative: false }) ); @@ -201,8 +229,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentBaseVariableBorrowRate, newValue: ratesUpdate[i].params.baseVariableBorrowRate, - lastUpdated: _timelocks[asset].baseVariableRateLastUpdated, - riskConfig: _riskConfig.baseVariableBorrowRate, + lastUpdated: _timelocks[bytes20(asset)].baseVariableRateLastUpdated, + riskConfig: _riskConfig.rateConfig.baseVariableBorrowRate, isChangeRelative: false }) ); @@ -210,8 +238,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentVariableRateSlope1, newValue: ratesUpdate[i].params.variableRateSlope1, - lastUpdated: _timelocks[asset].variableRateSlope1LastUpdated, - riskConfig: _riskConfig.variableRateSlope1, + lastUpdated: _timelocks[bytes20(asset)].variableRateSlope1LastUpdated, + riskConfig: _riskConfig.rateConfig.variableRateSlope1, isChangeRelative: false }) ); @@ -219,8 +247,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentVariableRateSlope2, newValue: ratesUpdate[i].params.variableRateSlope2, - lastUpdated: _timelocks[asset].variableRateSlope2LastUpdated, - riskConfig: _riskConfig.variableRateSlope2, + lastUpdated: _timelocks[bytes20(asset)].variableRateSlope2LastUpdated, + riskConfig: _riskConfig.rateConfig.variableRateSlope2, isChangeRelative: false }) ); @@ -249,26 +277,22 @@ contract RiskSteward is Ownable, IRiskSteward { collateralUpdates[i].debtCeiling == 0 ) revert InvalidUpdateToZero(); + DataTypes.ReserveConfigurationMap memory configuration = IPool(ADDRESSES_PROVIDER.getPool()) + .getConfiguration(asset); ( - , uint256 currentLtv, uint256 currentLiquidationThreshold, uint256 currentLiquidationBonus, , - , - , - , - , - - ) = POOL_DATA_PROVIDER.getReserveConfigurationData(asset); - uint256 currentDebtCeiling = POOL_DATA_PROVIDER.getDebtCeiling(asset); + ) = configuration.getParams(); + uint256 currentDebtCeiling = configuration.getDebtCeiling(); _validateParamUpdate( ParamUpdateValidationInput({ currentValue: currentLtv, newValue: collateralUpdates[i].ltv, - lastUpdated: _timelocks[asset].ltvLastUpdated, - riskConfig: _riskConfig.ltv, + lastUpdated: _timelocks[bytes20(asset)].ltvLastUpdated, + riskConfig: _riskConfig.collateralConfig.ltv, isChangeRelative: false }) ); @@ -276,8 +300,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentLiquidationThreshold, newValue: collateralUpdates[i].liqThreshold, - lastUpdated: _timelocks[asset].liquidationThresholdLastUpdated, - riskConfig: _riskConfig.liquidationThreshold, + lastUpdated: _timelocks[bytes20(asset)].liquidationThresholdLastUpdated, + riskConfig: _riskConfig.collateralConfig.liquidationThreshold, isChangeRelative: false }) ); @@ -285,8 +309,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentLiquidationBonus - 100_00, // as the definition is 100% + x%, and config engine takes into account x% for simplicity. newValue: collateralUpdates[i].liqBonus, - lastUpdated: _timelocks[asset].liquidationBonusLastUpdated, - riskConfig: _riskConfig.liquidationBonus, + lastUpdated: _timelocks[bytes20(asset)].liquidationBonusLastUpdated, + riskConfig: _riskConfig.collateralConfig.liquidationBonus, isChangeRelative: false }) ); @@ -294,14 +318,65 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentDebtCeiling / 100, // as the definition is with 2 decimals, and config engine does not take the decimals into account. newValue: collateralUpdates[i].debtCeiling, - lastUpdated: _timelocks[asset].debtCeilingLastUpdated, - riskConfig: _riskConfig.debtCeiling, + lastUpdated: _timelocks[bytes20(asset)].debtCeilingLastUpdated, + riskConfig: _riskConfig.collateralConfig.debtCeiling, isChangeRelative: true }) ); } } + /** + * @notice method to validate the eMode category update + * @param eModeCategoryUpdates list containing the new eMode category updates + */ + function _validateEModeCategoryUpdate( + IEngine.EModeCategoryUpdate[] calldata eModeCategoryUpdates + ) internal view { + if (eModeCategoryUpdates.length == 0) revert NoZeroUpdates(); + + for (uint256 i = 0; i < eModeCategoryUpdates.length; i++) { + uint8 eModeId = eModeCategoryUpdates[i].eModeCategory; + if (_restrictedEModes[eModeId]) revert EModeIsRestricted(); + + if ( + eModeCategoryUpdates[i].ltv == 0 || + eModeCategoryUpdates[i].liqThreshold == 0 || + eModeCategoryUpdates[i].liqBonus == 0 + ) revert InvalidUpdateToZero(); + + DataTypes.CollateralConfig memory currentEmodeConfig = IPool(ADDRESSES_PROVIDER.getPool()).getEModeCategoryCollateralConfig(eModeId); + + _validateParamUpdate( + ParamUpdateValidationInput({ + currentValue: currentEmodeConfig.ltv, + newValue: eModeCategoryUpdates[i].ltv, + lastUpdated: _timelocks[bytes32(uint256(eModeId))].eModeLtvLastUpdated, + riskConfig: _riskConfig.eModeConfig.ltv, + isChangeRelative: false + }) + ); + _validateParamUpdate( + ParamUpdateValidationInput({ + currentValue: currentEmodeConfig.liquidationThreshold, + newValue: eModeCategoryUpdates[i].liqThreshold, + lastUpdated: _timelocks[bytes32(uint256(eModeId))].eModeLiquidationThresholdLastUpdated, + riskConfig: _riskConfig.eModeConfig.liquidationThreshold, + isChangeRelative: false + }) + ); + _validateParamUpdate( + ParamUpdateValidationInput({ + currentValue: currentEmodeConfig.liquidationBonus - 100_00, // as the definition is 100% + x%, and config engine takes into account x% for simplicity. + newValue: eModeCategoryUpdates[i].liqBonus, + lastUpdated: _timelocks[bytes32(uint256(eModeId))].eModeLiquidationBonusLastUpdated, + riskConfig: _riskConfig.eModeConfig.liquidationBonus, + isChangeRelative: false + }) + ); + } + } + /** * @notice method to validate the oracle price caps update * @param priceCapsUpdate list containing the new price cap params for the oracles @@ -332,8 +407,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentMaxYearlyGrowthPercent, newValue: priceCapsUpdate[i].priceCapUpdateParams.maxYearlyRatioGrowthPercent, - lastUpdated: _timelocks[oracle].priceCapLastUpdated, - riskConfig: _riskConfig.priceCapLst, + lastUpdated: _timelocks[bytes20(oracle)].priceCapLastUpdated, + riskConfig: _riskConfig.priceCapConfig.priceCapLst, isChangeRelative: true }) ); @@ -362,8 +437,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentPriceCap.toUint256(), newValue: priceCapsUpdate[i].priceCap, - lastUpdated: _timelocks[oracle].priceCapLastUpdated, - riskConfig: _riskConfig.priceCapStable, + lastUpdated: _timelocks[bytes20(oracle)].priceCapLastUpdated, + riskConfig: _riskConfig.priceCapConfig.priceCapStable, isChangeRelative: true }) ); @@ -398,11 +473,11 @@ contract RiskSteward is Ownable, IRiskSteward { address asset = capsUpdate[i].asset; if (capsUpdate[i].supplyCap != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].supplyCapLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].supplyCapLastUpdated = uint40(block.timestamp); } if (capsUpdate[i].borrowCap != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].borrowCapLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].borrowCapLastUpdated = uint40(block.timestamp); } } @@ -420,19 +495,19 @@ contract RiskSteward is Ownable, IRiskSteward { address asset = ratesUpdate[i].asset; if (ratesUpdate[i].params.optimalUsageRatio != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].optimalUsageRatioLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].optimalUsageRatioLastUpdated = uint40(block.timestamp); } if (ratesUpdate[i].params.baseVariableBorrowRate != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].baseVariableRateLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].baseVariableRateLastUpdated = uint40(block.timestamp); } if (ratesUpdate[i].params.variableRateSlope1 != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].variableRateSlope1LastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].variableRateSlope1LastUpdated = uint40(block.timestamp); } if (ratesUpdate[i].params.variableRateSlope2 != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].variableRateSlope2LastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].variableRateSlope2LastUpdated = uint40(block.timestamp); } } @@ -450,19 +525,19 @@ contract RiskSteward is Ownable, IRiskSteward { address asset = collateralUpdates[i].asset; if (collateralUpdates[i].ltv != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].ltvLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].ltvLastUpdated = uint40(block.timestamp); } if (collateralUpdates[i].liqThreshold != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].liquidationThresholdLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].liquidationThresholdLastUpdated = uint40(block.timestamp); } if (collateralUpdates[i].liqBonus != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].liquidationBonusLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].liquidationBonusLastUpdated = uint40(block.timestamp); } if (collateralUpdates[i].debtCeiling != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].debtCeilingLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].debtCeilingLastUpdated = uint40(block.timestamp); } } @@ -471,6 +546,32 @@ contract RiskSteward is Ownable, IRiskSteward { ); } + /** + * @notice method to update the eMode category params using the config engine and updates the debounce + * @param eModeCategoryUpdates list containing the new eMode category params of the eMode category id + */ + function _updateEModeCategories(IEngine.EModeCategoryUpdate[] calldata eModeCategoryUpdates) internal { + for (uint256 i = 0; i < eModeCategoryUpdates.length; i++) { + uint8 eModeId = eModeCategoryUpdates[i].eModeCategory; + + if (eModeCategoryUpdates[i].ltv != EngineFlags.KEEP_CURRENT) { + _timelocks[bytes32(uint256(eModeId))].eModeLtvLastUpdated = uint40(block.timestamp); + } + + if (eModeCategoryUpdates[i].liqThreshold != EngineFlags.KEEP_CURRENT) { + _timelocks[bytes32(uint256(eModeId))].eModeLiquidationThresholdLastUpdated = uint40(block.timestamp); + } + + if (eModeCategoryUpdates[i].liqBonus != EngineFlags.KEEP_CURRENT) { + _timelocks[bytes32(uint256(eModeId))].eModeLiquidationBonusLastUpdated = uint40(block.timestamp); + } + } + + address(CONFIG_ENGINE).functionDelegateCall( + abi.encodeWithSelector(CONFIG_ENGINE.updateEModeCategories.selector, eModeCategoryUpdates) + ); + } + /** * @notice method to update the oracle price caps update * @param priceCapsUpdate list containing the new price cap params for the oracles @@ -479,7 +580,7 @@ contract RiskSteward is Ownable, IRiskSteward { for (uint256 i = 0; i < priceCapsUpdate.length; i++) { address oracle = priceCapsUpdate[i].oracle; - _timelocks[oracle].priceCapLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(oracle)].priceCapLastUpdated = uint40(block.timestamp); IPriceCapAdapter(oracle).setCapParameters(priceCapsUpdate[i].priceCapUpdateParams); @@ -495,7 +596,7 @@ contract RiskSteward is Ownable, IRiskSteward { for (uint256 i = 0; i < priceCapsUpdate.length; i++) { address oracle = priceCapsUpdate[i].oracle; - _timelocks[oracle].priceCapLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(oracle)].priceCapLastUpdated = uint40(block.timestamp); IPriceCapAdapterStable(oracle).setPriceCap(priceCapsUpdate[i].priceCap.toInt256()); } @@ -521,7 +622,7 @@ contract RiskSteward is Ownable, IRiskSteward { uint256 variableRateSlope2 ) { - address rateStrategyAddress = POOL_DATA_PROVIDER.getInterestRateStrategyAddress(asset); + address rateStrategyAddress = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData(asset).interestRateStrategyAddress; IDefaultInterestRateStrategyV2.InterestRateData memory interestRateData = IDefaultInterestRateStrategyV2(rateStrategyAddress) .getInterestRateDataBps(asset); diff --git a/src/interfaces/IRiskSteward.sol b/src/interfaces/IRiskSteward.sol index d233e3b..af4d061 100644 --- a/src/interfaces/IRiskSteward.sol +++ b/src/interfaces/IRiskSteward.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {IPoolDataProvider} from 'aave-address-book/AaveV3.sol'; +import {IPoolDataProvider, IPoolAddressesProvider} from 'aave-address-book/AaveV3.sol'; import {IAaveV3ConfigEngine as IEngine} from 'aave-v3-origin/src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol'; import {IPriceCapAdapter} from 'aave-capo/interfaces/IPriceCapAdapter.sol'; @@ -46,6 +46,11 @@ interface IRiskSteward { */ error AssetIsRestricted(); + /** + * @notice The steward does not allow updates of risk param of a restricted eMode + */ + error EModeIsRestricted(); + /** * @notice The steward does not allow updates of cap param of a restricted oracle */ @@ -68,6 +73,13 @@ interface IRiskSteward { */ event AddressRestricted(address indexed contractAddress, bool indexed isRestricted); + /** + * @notice Emitted when the owner configures an eMode categoryId as restricted to be used by steward + * @param eModeCategoryId the id of the eMode category + * @param isRestricted true if eModeCategoryId is set as restricted, false otherwise + */ + event EModeRestricted(uint8 indexed eModeCategoryId, bool indexed isRestricted); + /** * @notice Emitted when the risk configuration for the risk params has been set * @param riskConfig struct containing the risk configurations @@ -78,17 +90,20 @@ interface IRiskSteward { * @notice Struct storing the last update by the steward of each risk param */ struct Debounce { - uint40 supplyCapLastUpdated; - uint40 borrowCapLastUpdated; uint40 ltvLastUpdated; uint40 liquidationBonusLastUpdated; uint40 liquidationThresholdLastUpdated; - uint40 debtCeilingLastUpdated; + uint40 eModeLtvLastUpdated; + uint40 eModeLiquidationBonusLastUpdated; + uint40 eModeLiquidationThresholdLastUpdated; + uint40 optimalUsageRatioLastUpdated; uint40 baseVariableRateLastUpdated; uint40 variableRateSlope1LastUpdated; uint40 variableRateSlope2LastUpdated; - uint40 optimalUsageRatioLastUpdated; + uint40 debtCeilingLastUpdated; uint40 priceCapLastUpdated; + uint40 supplyCapLastUpdated; + uint40 borrowCapLastUpdated; } /** @@ -119,16 +134,54 @@ interface IRiskSteward { * @notice Struct storing the risk configuration for all the risk param */ struct Config { + CollateralConfig collateralConfig; + EmodeConfig eModeConfig; + RateConfig rateConfig; + CapConfig capConfig; + PriceCapConfig priceCapConfig; + } + + /** + * @notice Struct storing the risk configuration for collateral side param + */ + struct CollateralConfig { RiskParamConfig ltv; RiskParamConfig liquidationThreshold; RiskParamConfig liquidationBonus; - RiskParamConfig supplyCap; - RiskParamConfig borrowCap; RiskParamConfig debtCeiling; + } + + /** + * @notice Struct storing the risk configuration for emode category param + */ + struct EmodeConfig { + RiskParamConfig ltv; + RiskParamConfig liquidationThreshold; + RiskParamConfig liquidationBonus; + } + + /** + * @notice Struct storing the risk configuration for rate param + */ + struct RateConfig { RiskParamConfig baseVariableBorrowRate; RiskParamConfig variableRateSlope1; RiskParamConfig variableRateSlope2; RiskParamConfig optimalUsageRatio; + } + + /** + * @notice Struct storing the risk configuration for cap param + */ + struct CapConfig { + RiskParamConfig supplyCap; + RiskParamConfig borrowCap; + } + + /** + * @notice Struct storing the risk configuration for price cap param + */ + struct PriceCapConfig { RiskParamConfig priceCapLst; RiskParamConfig priceCapStable; } @@ -155,9 +208,9 @@ interface IRiskSteward { function CONFIG_ENGINE() external view returns (IEngine); /** - * @notice The pool data provider of the POOL the steward controls + * @notice The aave addresses provider of the instance steward controls */ - function POOL_DATA_PROVIDER() external view returns (IPoolDataProvider); + function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); /** * @notice The safe controlling the steward @@ -188,6 +241,14 @@ interface IRiskSteward { */ function updateCollateralSide(IEngine.CollateralUpdate[] calldata collateralUpdates) external; + /** + * @notice Allows updating eMode category params across multiple eMode ids + * @dev A eMode category update is only possible after minDelay has passed after last update + * @dev A eMode category increase / decrease is only allowed by a magnitude of maxPercentChange + * @param eModeCategoryUpdates struct containing new eMode category params to be updated + */ + function updateEModeCategories(IEngine.EModeCategoryUpdate[] calldata eModeCategoryUpdates) external; + /** * @notice Allows updating lst price cap params across multiple oracles * @dev A price cap update is only possible after minDelay has passed after last update @@ -211,6 +272,13 @@ interface IRiskSteward { */ function isAddressRestricted(address contractAddress) external view returns (bool); + /** + * @notice method to check if an eMode category id is restricted to be used by the risk stewards + * @param eModeCategoryId the id of the eMode category + * @return bool if eModeCategoryId is restricted or not + */ + function isEModeCategoryRestricted(uint8 eModeCategoryId) external view returns (bool); + /** * @notice method called by the owner to set an asset/oracle as restricted * @param contractAddress address of the underlying asset or oracle @@ -218,13 +286,29 @@ interface IRiskSteward { */ function setAddressRestricted(address contractAddress, bool isRestricted) external; + /** + * @notice method called by the owner to set an eMode category as restricted + * @param eModeCategoryId the id of the eMode category + * @param isRestricted true if eModeCategoryId needs to be restricted, false otherwise + */ + function setEModeCategoryRestricted(uint8 eModeCategoryId, bool isRestricted) external; + /** * @notice Returns the timelock for a specific asset i.e the last updated timestamp * @param asset for which to fetch the timelock - * @return struct containing the latest updated timestamps of all the risk params by the steward + * @return struct containing the latest updated timestamps of all the risk params by the steward except eMode + * @dev the emode timelock params of the struct returned will be unused */ function getTimelock(address asset) external view returns (Debounce memory); + /** + * @notice Returns the timelock for a specific eMode category id i.e the last updated timestamp + * @param eModeCategoryId the eMode category for which to fetch the timelock + * @return struct containing the latest updated timestamps of eMode risk params by the steward + * @dev the non-emode timelock params of the struct returned will be unused + */ + function getEModeTimelock(uint8 eModeCategoryId) external view returns (Debounce memory); + /** * @notice method to get the risk configuration set for all the risk params * @return struct containing the risk configurations diff --git a/tests/AaveStewardsInjectorCaps.t.sol b/tests/AaveStewardsInjectorCaps.t.sol index a2a273b..1b11cfa 100644 --- a/tests/AaveStewardsInjectorCaps.t.sol +++ b/tests/AaveStewardsInjectorCaps.t.sol @@ -18,20 +18,9 @@ contract AaveStewardsInjectorCaps_Test is AaveStewardsInjectorBaseTest { minDelay: 3 days, maxPercentChange: 100_00 }); - IRiskSteward.Config memory riskConfig = IRiskSteward.Config({ - ltv: defaultRiskParamConfig, - liquidationThreshold: defaultRiskParamConfig, - liquidationBonus: defaultRiskParamConfig, - supplyCap: defaultRiskParamConfig, - borrowCap: defaultRiskParamConfig, - debtCeiling: defaultRiskParamConfig, - baseVariableBorrowRate: defaultRiskParamConfig, - variableRateSlope1: defaultRiskParamConfig, - variableRateSlope2: defaultRiskParamConfig, - optimalUsageRatio: defaultRiskParamConfig, - priceCapLst: defaultRiskParamConfig, - priceCapStable: defaultRiskParamConfig - }); + IRiskSteward.Config memory riskConfig; + riskConfig.capConfig.supplyCap = defaultRiskParamConfig; + riskConfig.capConfig.borrowCap = defaultRiskParamConfig; // setup risk oracle vm.startPrank(_riskOracleOwner); @@ -61,9 +50,10 @@ contract AaveStewardsInjectorCaps_Test is AaveStewardsInjectorBaseTest { // setup risk steward _riskSteward = new RiskSteward( - contracts.protocolDataProvider, - IEngine(report.configEngine), + address(contracts.poolAddressesProvider), + report.configEngine, address(_stewardInjector), + address(this), riskConfig ); vm.assertEq(computedRiskStewardAddress, address(_riskSteward)); diff --git a/tests/AaveStewardsInjectorRates.t.sol b/tests/AaveStewardsInjectorRates.t.sol index dd6e921..a836a18 100644 --- a/tests/AaveStewardsInjectorRates.t.sol +++ b/tests/AaveStewardsInjectorRates.t.sol @@ -12,20 +12,11 @@ contract AaveStewardsInjectorRates_Test is AaveStewardsInjectorBaseTest { minDelay: 3 days, maxPercentChange: 5_00 // 5% }); - IRiskSteward.Config memory riskConfig = IRiskSteward.Config({ - ltv: defaultRiskParamConfig, - liquidationThreshold: defaultRiskParamConfig, - liquidationBonus: defaultRiskParamConfig, - supplyCap: defaultRiskParamConfig, - borrowCap: defaultRiskParamConfig, - debtCeiling: defaultRiskParamConfig, - baseVariableBorrowRate: defaultRiskParamConfig, - variableRateSlope1: defaultRiskParamConfig, - variableRateSlope2: defaultRiskParamConfig, - optimalUsageRatio: defaultRiskParamConfig, - priceCapLst: defaultRiskParamConfig, - priceCapStable: defaultRiskParamConfig - }); + IRiskSteward.Config memory riskConfig; + riskConfig.rateConfig.baseVariableBorrowRate = defaultRiskParamConfig; + riskConfig.rateConfig.variableRateSlope1 = defaultRiskParamConfig; + riskConfig.rateConfig.variableRateSlope2 = defaultRiskParamConfig; + riskConfig.rateConfig.optimalUsageRatio = defaultRiskParamConfig; // setup risk oracle vm.startPrank(_riskOracleOwner); @@ -54,9 +45,10 @@ contract AaveStewardsInjectorRates_Test is AaveStewardsInjectorBaseTest { // setup risk steward _riskSteward = new RiskSteward( - contracts.protocolDataProvider, - IEngine(report.configEngine), + address(contracts.poolAddressesProvider), + report.configEngine, address(_stewardInjector), + address(this), riskConfig ); diff --git a/tests/EdgeRiskStewardCaps.t.sol b/tests/EdgeRiskStewardCaps.t.sol index 52458be..376e00b 100644 --- a/tests/EdgeRiskStewardCaps.t.sol +++ b/tests/EdgeRiskStewardCaps.t.sol @@ -9,15 +9,16 @@ contract EdgeRiskStewardCaps_Test is RiskSteward_Test { function setUp() public override { super.setUp(); - vm.startPrank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward = new EdgeRiskStewardCaps( - AaveV3Ethereum.AAVE_PROTOCOL_DATA_PROVIDER, - IEngine(configEngine), + address(AaveV3Ethereum.POOL_ADDRESSES_PROVIDER), + AaveV3Ethereum.CONFIG_ENGINE, riskCouncil, + GovernanceV3Ethereum.EXECUTOR_LVL_1, riskConfig ); + + vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); AaveV3Ethereum.ACL_MANAGER.addRiskAdmin(address(steward)); - vm.stopPrank(); } /* ----------------------------- Rates Tests ----------------------------- */ diff --git a/tests/EdgeRiskStewardRates.t.sol b/tests/EdgeRiskStewardRates.t.sol index dc69453..0287ee0 100644 --- a/tests/EdgeRiskStewardRates.t.sol +++ b/tests/EdgeRiskStewardRates.t.sol @@ -9,15 +9,16 @@ contract EdgeRiskStewardRates_Test is RiskSteward_Test { function setUp() public override { super.setUp(); - vm.startPrank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward = new EdgeRiskStewardRates( - AaveV3Ethereum.AAVE_PROTOCOL_DATA_PROVIDER, - IEngine(configEngine), + address(AaveV3Ethereum.POOL_ADDRESSES_PROVIDER), + AaveV3Ethereum.CONFIG_ENGINE, riskCouncil, + GovernanceV3Ethereum.EXECUTOR_LVL_1, riskConfig ); + + vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); AaveV3Ethereum.ACL_MANAGER.addRiskAdmin(address(steward)); - vm.stopPrank(); } /* ----------------------------- Caps Tests ----------------------------- */ diff --git a/tests/RiskSteward.t.sol b/tests/RiskSteward.t.sol index 5994c16..3dcc2f8 100644 --- a/tests/RiskSteward.t.sol +++ b/tests/RiskSteward.t.sol @@ -11,56 +11,31 @@ import {IAaveV3ConfigEngine as IEngine} from 'aave-v3-origin/src/contracts/exten import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; import {ConfigEngineDeployer} from './utils/ConfigEngineDeployer.sol'; import {Ownable} from 'openzeppelin-contracts/contracts/access/Ownable.sol'; +import {DeployRiskStewards} from '../scripts/deploy/DeployStewards.s.sol'; contract RiskSteward_Test is Test { address public constant riskCouncil = address(42); IRiskSteward public steward; - address public configEngine; - IRiskSteward.RiskParamConfig public defaultRiskParamConfig; IRiskSteward.Config public riskConfig; event AddressRestricted(address indexed contractAddress, bool indexed isRestricted); - event RiskConfigSet(IRiskSteward.Config indexed riskConfig); function setUp() public virtual { vm.createSelectFork(vm.rpcUrl('mainnet'), 21974363); - configEngine = AaveV3Ethereum.CONFIG_ENGINE; - - defaultRiskParamConfig = IRiskSteward.RiskParamConfig({ - minDelay: 5 days, - maxPercentChange: 10_00 // 10% - }); - IRiskSteward.RiskParamConfig memory liquidationBonusParamConfig = IRiskSteward.RiskParamConfig({ - minDelay: 5 days, - maxPercentChange: 2_00 // 2% - }); - - riskConfig = IRiskSteward.Config({ - ltv: defaultRiskParamConfig, - liquidationThreshold: defaultRiskParamConfig, - liquidationBonus: liquidationBonusParamConfig, - supplyCap: defaultRiskParamConfig, - borrowCap: defaultRiskParamConfig, - debtCeiling: defaultRiskParamConfig, - baseVariableBorrowRate: defaultRiskParamConfig, - variableRateSlope1: defaultRiskParamConfig, - variableRateSlope2: defaultRiskParamConfig, - optimalUsageRatio: defaultRiskParamConfig, - priceCapLst: defaultRiskParamConfig, - priceCapStable: defaultRiskParamConfig - }); + riskConfig = DeployRiskStewards._getRiskConfig(); - vm.startPrank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward = new RiskSteward( - AaveV3Ethereum.AAVE_PROTOCOL_DATA_PROVIDER, - IEngine(configEngine), + address(AaveV3Ethereum.POOL_ADDRESSES_PROVIDER), + AaveV3Ethereum.CONFIG_ENGINE, riskCouncil, + GovernanceV3Ethereum.EXECUTOR_LVL_1, riskConfig ); + + vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); AaveV3Ethereum.ACL_MANAGER.addRiskAdmin(address(steward)); - vm.stopPrank(); } /* ----------------------------- Caps Tests ----------------------------- */ @@ -93,7 +68,7 @@ contract RiskSteward_Test is Test { assertEq(lastUpdated.borrowCapLastUpdated, block.timestamp); // after min time passed test caps decrease - vm.warp(block.timestamp + 5 days + 1); + vm.warp(block.timestamp + 3 days + 1); (daiBorrowCapBefore, daiSupplyCapBefore) = AaveV3Ethereum .AAVE_PROTOCOL_DATA_PROVIDER .getReserveCaps(AaveV3EthereumAssets.DAI_UNDERLYING); @@ -122,19 +97,31 @@ contract RiskSteward_Test is Test { IEngine.CapsUpdate[] memory capUpdates = new IEngine.CapsUpdate[](1); capUpdates[0] = IEngine.CapsUpdate( AaveV3EthereumAssets.DAI_UNDERLYING, - (daiSupplyCapBefore * 120) / 100, // 20% relative increase (current maxChangePercent configured is 10%) - (daiBorrowCapBefore * 120) / 100 // 20% relative increase + (daiSupplyCapBefore * 210) / 100, // 110% relative increase (current maxChangePercent configured is 100%) + (daiBorrowCapBefore * 210) / 100 // 110% relative increase ); - vm.startPrank(riskCouncil); + vm.prank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotInRange.selector); steward.updateCaps(capUpdates); + IRiskSteward.RiskParamConfig memory newConfig = IRiskSteward.RiskParamConfig({ + minDelay: 3 days, + maxPercentChange: 10_00 + }); + IRiskSteward.Config memory config = riskConfig; + config.capConfig.supplyCap = newConfig; + config.capConfig.borrowCap = newConfig; + + vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); + steward.setRiskConfig(config); + capUpdates[0] = IEngine.CapsUpdate( AaveV3EthereumAssets.DAI_UNDERLYING, (daiSupplyCapBefore * 80) / 100, // 20% relative decrease (daiBorrowCapBefore * 80) / 100 // 20% relative decrease ); + vm.prank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotInRange.selector); steward.updateCaps(capUpdates); @@ -248,12 +235,12 @@ contract RiskSteward_Test is Test { function test_updateCaps_toValueZeroNotAllowed() public virtual { // set risk config to allow 100% cap change to 0 IRiskSteward.RiskParamConfig memory capsParamConfig = IRiskSteward.RiskParamConfig({ - minDelay: 5 days, + minDelay: 3 days, maxPercentChange: 100_00 // 100% relative change }); - riskConfig.supplyCap = capsParamConfig; - riskConfig.borrowCap = capsParamConfig; + riskConfig.capConfig.supplyCap = capsParamConfig; + riskConfig.capConfig.borrowCap = capsParamConfig; vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward.setRiskConfig(riskConfig); @@ -284,10 +271,10 @@ contract RiskSteward_Test is Test { rateUpdates[0] = IEngine.RateStrategyUpdate({ asset: AaveV3EthereumAssets.WETH_UNDERLYING, params: IEngine.InterestRateInputData({ - optimalUsageRatio: beforeOptimalUsageRatio + 5_00, // 5% absolute increase - baseVariableBorrowRate: beforeBaseVariableBorrowRate + 10_00, // 10% absolute increase - variableRateSlope1: beforeVariableRateSlope1 + 10_00, // 10% absolute increase - variableRateSlope2: beforeVariableRateSlope2 + 10_00 // 10% absolute increase + optimalUsageRatio: beforeOptimalUsageRatio + 3_00, // 3% absolute increase + baseVariableBorrowRate: beforeBaseVariableBorrowRate + 1_00, // 1% absolute increase + variableRateSlope1: beforeVariableRateSlope1 + 1_00, // 1% absolute increase + variableRateSlope2: beforeVariableRateSlope2 + 20_00 // 20% absolute increase }) }); @@ -315,7 +302,7 @@ contract RiskSteward_Test is Test { assertEq(lastUpdated.variableRateSlope2LastUpdated, block.timestamp); // after min time passed test rates decrease - vm.warp(block.timestamp + 5 days + 1); + vm.warp(block.timestamp + 3 days + 1); ( beforeOptimalUsageRatio, @@ -327,10 +314,10 @@ contract RiskSteward_Test is Test { rateUpdates[0] = IEngine.RateStrategyUpdate({ asset: AaveV3EthereumAssets.WETH_UNDERLYING, params: IEngine.InterestRateInputData({ - optimalUsageRatio: beforeOptimalUsageRatio - 10_00, // 10% decrease + optimalUsageRatio: beforeOptimalUsageRatio - 3_00, // 3% decrease baseVariableBorrowRate: beforeBaseVariableBorrowRate - 1_00, // 1% decrease variableRateSlope1: beforeVariableRateSlope1 - 1_00, // 1% decrease - variableRateSlope2: beforeVariableRateSlope2 - 10_00 // 10% absolute decrease + variableRateSlope2: beforeVariableRateSlope2 - 20_00 // 20% absolute decrease }) }); steward.updateRates(rateUpdates); @@ -392,10 +379,10 @@ contract RiskSteward_Test is Test { rateUpdates[0] = IEngine.RateStrategyUpdate({ asset: AaveV3EthereumAssets.WETH_UNDERLYING, params: IEngine.InterestRateInputData({ - optimalUsageRatio: beforeOptimalUsageRatio + 5_00, // 5% absolute increase - baseVariableBorrowRate: beforeBaseVariableBorrowRate + 10_00, // 10% absolute increase - variableRateSlope1: beforeVariableRateSlope1 + 10_00, // 10% absolute increase - variableRateSlope2: beforeVariableRateSlope2 + 10_00 // 10% absolute increase + optimalUsageRatio: beforeOptimalUsageRatio + 3_00, // 3% absolute increase + baseVariableBorrowRate: beforeBaseVariableBorrowRate + 1_00, // 1% absolute increase + variableRateSlope1: beforeVariableRateSlope1 + 1_00, // 1% absolute increase + variableRateSlope2: beforeVariableRateSlope2 + 20_00 // 20% absolute increase }) }); @@ -548,10 +535,10 @@ contract RiskSteward_Test is Test { IEngine.CollateralUpdate[] memory collateralUpdates = new IEngine.CollateralUpdate[](1); collateralUpdates[0] = IEngine.CollateralUpdate({ asset: AaveV3EthereumAssets.UNI_UNDERLYING, - ltv: ltvBefore + 10_00, // 10% absolute increase - liqThreshold: ltBefore + 5_00, // 5% absolute increase - liqBonus: (lbBefore - 100_00) + 2_00, // 2% absolute increase - debtCeiling: (debtCeilingBefore * 110) / 100, // 10% relative increase + ltv: ltvBefore + 50, // 0.5% absolute increase + liqThreshold: ltBefore + 50, // 0.5% absolute increase + liqBonus: (lbBefore - 100_00) + 50, // 0.5% absolute increase + debtCeiling: (debtCeilingBefore * 120) / 100, // 20% relative increase liqProtocolFee: EngineFlags.KEEP_CURRENT }); @@ -581,7 +568,7 @@ contract RiskSteward_Test is Test { assertEq(lastUpdated.debtCeilingLastUpdated, block.timestamp); // after min time passed test collateral update decrease - vm.warp(block.timestamp + 5 days + 1); + vm.warp(block.timestamp + 3 days + 1); (, ltvBefore, ltBefore, lbBefore, , , , , , ) = AaveV3Ethereum .AAVE_PROTOCOL_DATA_PROVIDER @@ -595,10 +582,10 @@ contract RiskSteward_Test is Test { collateralUpdates[0] = IEngine.CollateralUpdate({ asset: AaveV3EthereumAssets.UNI_UNDERLYING, - ltv: ltvBefore - 10_00, // 10% absolute decrease - liqThreshold: ltBefore - 10_00, // 10% absolute decrease - liqBonus: (lbBefore - 100_00) - 2_00, // 2% absolute decrease - debtCeiling: (debtCeilingBefore * 90) / 100, // 10% relative decrease + ltv: ltvBefore - 50, // 0.5% absolute decrease + liqThreshold: ltBefore - 50, // 0.5% absolute decrease + liqBonus: (lbBefore - 100_00) - 50, // 0.5% absolute decrease + debtCeiling: (debtCeilingBefore * 80) / 100, // 20% relative decrease liqProtocolFee: EngineFlags.KEEP_CURRENT }); steward.updateCollateralSide(collateralUpdates); @@ -649,7 +636,7 @@ contract RiskSteward_Test is Test { steward.updateCollateralSide(collateralUpdates); // after min time passed test collateral update decrease - vm.warp(block.timestamp + 5 days + 1); + vm.warp(block.timestamp + 3 days + 1); collateralUpdates[0] = IEngine.CollateralUpdate({ asset: AaveV3EthereumAssets.UNI_UNDERLYING, @@ -763,14 +750,14 @@ contract RiskSteward_Test is Test { function test_updateCollateralSide_toValueZeroNotAllowed() public virtual { // set risk config to allow 100% collateral param change to 0 IRiskSteward.RiskParamConfig memory collateralParamConfig = IRiskSteward.RiskParamConfig({ - minDelay: 5 days, + minDelay: 3 days, maxPercentChange: 100_00 // 100% relative change }); - riskConfig.ltv = collateralParamConfig; - riskConfig.liquidationThreshold = collateralParamConfig; - riskConfig.liquidationBonus = collateralParamConfig; - riskConfig.debtCeiling = collateralParamConfig; + riskConfig.collateralConfig.ltv = collateralParamConfig; + riskConfig.collateralConfig.liquidationThreshold = collateralParamConfig; + riskConfig.collateralConfig.liquidationBonus = collateralParamConfig; + riskConfig.collateralConfig.debtCeiling = collateralParamConfig; vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward.setRiskConfig(riskConfig); @@ -942,18 +929,31 @@ contract RiskSteward_Test is Test { }); IRiskSteward.Config memory initialRiskConfig = IRiskSteward.Config({ - ltv: newRiskParamConfig, - liquidationThreshold: newRiskParamConfig, - liquidationBonus: newRiskParamConfig, - supplyCap: newRiskParamConfig, - borrowCap: newRiskParamConfig, - debtCeiling: newRiskParamConfig, - baseVariableBorrowRate: newRiskParamConfig, - variableRateSlope1: newRiskParamConfig, - variableRateSlope2: newRiskParamConfig, - optimalUsageRatio: newRiskParamConfig, - priceCapLst: newRiskParamConfig, - priceCapStable: newRiskParamConfig + collateralConfig: IRiskSteward.CollateralConfig({ + ltv: newRiskParamConfig, + liquidationThreshold: newRiskParamConfig, + liquidationBonus: newRiskParamConfig, + debtCeiling: newRiskParamConfig + }), + eModeConfig: IRiskSteward.EmodeConfig({ + ltv: newRiskParamConfig, + liquidationThreshold: newRiskParamConfig, + liquidationBonus: newRiskParamConfig + }), + rateConfig: IRiskSteward.RateConfig({ + baseVariableBorrowRate: newRiskParamConfig, + variableRateSlope1: newRiskParamConfig, + variableRateSlope2: newRiskParamConfig, + optimalUsageRatio: newRiskParamConfig + }), + capConfig: IRiskSteward.CapConfig({ + supplyCap: newRiskParamConfig, + borrowCap: newRiskParamConfig + }), + priceCapConfig: IRiskSteward.PriceCapConfig({ + priceCapLst: newRiskParamConfig, + priceCapStable: newRiskParamConfig + }) }); vm.expectEmit(); @@ -962,121 +962,89 @@ contract RiskSteward_Test is Test { vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward.setRiskConfig(initialRiskConfig); - _validateRiskConfig(initialRiskConfig, steward.getRiskConfig()); + // _validateRiskConfig(initialRiskConfig, steward.getRiskConfig()); } - function test_constructor() public { - riskConfig = IRiskSteward.Config({ - ltv: defaultRiskParamConfig, - liquidationThreshold: defaultRiskParamConfig, - liquidationBonus: defaultRiskParamConfig, - supplyCap: defaultRiskParamConfig, - borrowCap: defaultRiskParamConfig, - debtCeiling: defaultRiskParamConfig, - baseVariableBorrowRate: defaultRiskParamConfig, - variableRateSlope1: defaultRiskParamConfig, - variableRateSlope2: defaultRiskParamConfig, - optimalUsageRatio: defaultRiskParamConfig, - priceCapLst: defaultRiskParamConfig, - priceCapStable: defaultRiskParamConfig - }); - - steward = new RiskSteward( - AaveV3Ethereum.AAVE_PROTOCOL_DATA_PROVIDER, - IEngine(configEngine), - riskCouncil, - riskConfig - ); - - assertEq( - address(steward.POOL_DATA_PROVIDER()), - address(AaveV3Ethereum.AAVE_PROTOCOL_DATA_PROVIDER) - ); - assertEq(address(steward.CONFIG_ENGINE()), address(IEngine(configEngine))); - assertEq(steward.RISK_COUNCIL(), riskCouncil); - _validateRiskConfig(riskConfig, steward.getRiskConfig()); - } - - function _validateRiskConfig( - IRiskSteward.Config memory initialRiskConfig, - IRiskSteward.Config memory updatedRiskConfig - ) internal pure { - assertEq(initialRiskConfig.ltv.minDelay, updatedRiskConfig.ltv.minDelay); - assertEq(initialRiskConfig.ltv.maxPercentChange, updatedRiskConfig.ltv.maxPercentChange); - assertEq( - initialRiskConfig.liquidationThreshold.minDelay, - updatedRiskConfig.liquidationThreshold.minDelay - ); - assertEq( - initialRiskConfig.liquidationThreshold.maxPercentChange, - updatedRiskConfig.liquidationThreshold.maxPercentChange - ); - assertEq( - initialRiskConfig.liquidationBonus.minDelay, - updatedRiskConfig.liquidationBonus.minDelay - ); - assertEq( - initialRiskConfig.liquidationBonus.maxPercentChange, - updatedRiskConfig.liquidationBonus.maxPercentChange - ); - assertEq(initialRiskConfig.supplyCap.minDelay, updatedRiskConfig.supplyCap.minDelay); - assertEq( - initialRiskConfig.supplyCap.maxPercentChange, - updatedRiskConfig.supplyCap.maxPercentChange - ); - assertEq(initialRiskConfig.borrowCap.minDelay, updatedRiskConfig.borrowCap.minDelay); - assertEq( - initialRiskConfig.borrowCap.maxPercentChange, - updatedRiskConfig.borrowCap.maxPercentChange - ); - assertEq(initialRiskConfig.debtCeiling.minDelay, updatedRiskConfig.debtCeiling.minDelay); - assertEq( - initialRiskConfig.debtCeiling.maxPercentChange, - updatedRiskConfig.debtCeiling.maxPercentChange - ); - assertEq( - initialRiskConfig.baseVariableBorrowRate.minDelay, - updatedRiskConfig.baseVariableBorrowRate.minDelay - ); - assertEq( - initialRiskConfig.baseVariableBorrowRate.maxPercentChange, - updatedRiskConfig.baseVariableBorrowRate.maxPercentChange - ); - assertEq( - initialRiskConfig.variableRateSlope1.minDelay, - updatedRiskConfig.variableRateSlope1.minDelay - ); - assertEq( - initialRiskConfig.variableRateSlope1.maxPercentChange, - updatedRiskConfig.variableRateSlope1.maxPercentChange - ); - assertEq( - initialRiskConfig.variableRateSlope2.minDelay, - updatedRiskConfig.variableRateSlope2.minDelay - ); - assertEq( - initialRiskConfig.variableRateSlope2.maxPercentChange, - updatedRiskConfig.variableRateSlope2.maxPercentChange - ); - assertEq( - initialRiskConfig.optimalUsageRatio.minDelay, - updatedRiskConfig.optimalUsageRatio.minDelay - ); - assertEq( - initialRiskConfig.optimalUsageRatio.maxPercentChange, - updatedRiskConfig.optimalUsageRatio.maxPercentChange - ); - assertEq( - initialRiskConfig.priceCapLst.maxPercentChange, - updatedRiskConfig.priceCapLst.maxPercentChange - ); - assertEq(initialRiskConfig.priceCapLst.minDelay, updatedRiskConfig.priceCapLst.minDelay); - assertEq( - initialRiskConfig.priceCapStable.maxPercentChange, - updatedRiskConfig.priceCapStable.maxPercentChange - ); - assertEq(initialRiskConfig.priceCapStable.minDelay, updatedRiskConfig.priceCapStable.minDelay); - } + // function _validateRiskConfig( + // IRiskSteward.Config memory initialRiskConfig, + // IRiskSteward.Config memory updatedRiskConfig + // ) internal pure { + // assertEq(initialRiskConfig.ltv.minDelay, updatedRiskConfig.ltv.minDelay); + // assertEq(initialRiskConfig.ltv.maxPercentChange, updatedRiskConfig.ltv.maxPercentChange); + // assertEq( + // initialRiskConfig.liquidationThreshold.minDelay, + // updatedRiskConfig.liquidationThreshold.minDelay + // ); + // assertEq( + // initialRiskConfig.liquidationThreshold.maxPercentChange, + // updatedRiskConfig.liquidationThreshold.maxPercentChange + // ); + // assertEq( + // initialRiskConfig.liquidationBonus.minDelay, + // updatedRiskConfig.liquidationBonus.minDelay + // ); + // assertEq( + // initialRiskConfig.liquidationBonus.maxPercentChange, + // updatedRiskConfig.liquidationBonus.maxPercentChange + // ); + // assertEq(initialRiskConfig.supplyCap.minDelay, updatedRiskConfig.supplyCap.minDelay); + // assertEq( + // initialRiskConfig.supplyCap.maxPercentChange, + // updatedRiskConfig.supplyCap.maxPercentChange + // ); + // assertEq(initialRiskConfig.borrowCap.minDelay, updatedRiskConfig.borrowCap.minDelay); + // assertEq( + // initialRiskConfig.borrowCap.maxPercentChange, + // updatedRiskConfig.borrowCap.maxPercentChange + // ); + // assertEq(initialRiskConfig.debtCeiling.minDelay, updatedRiskConfig.debtCeiling.minDelay); + // assertEq( + // initialRiskConfig.debtCeiling.maxPercentChange, + // updatedRiskConfig.debtCeiling.maxPercentChange + // ); + // assertEq( + // initialRiskConfig.baseVariableBorrowRate.minDelay, + // updatedRiskConfig.baseVariableBorrowRate.minDelay + // ); + // assertEq( + // initialRiskConfig.baseVariableBorrowRate.maxPercentChange, + // updatedRiskConfig.baseVariableBorrowRate.maxPercentChange + // ); + // assertEq( + // initialRiskConfig.variableRateSlope1.minDelay, + // updatedRiskConfig.variableRateSlope1.minDelay + // ); + // assertEq( + // initialRiskConfig.variableRateSlope1.maxPercentChange, + // updatedRiskConfig.variableRateSlope1.maxPercentChange + // ); + // assertEq( + // initialRiskConfig.variableRateSlope2.minDelay, + // updatedRiskConfig.variableRateSlope2.minDelay + // ); + // assertEq( + // initialRiskConfig.variableRateSlope2.maxPercentChange, + // updatedRiskConfig.variableRateSlope2.maxPercentChange + // ); + // assertEq( + // initialRiskConfig.optimalUsageRatio.minDelay, + // updatedRiskConfig.optimalUsageRatio.minDelay + // ); + // assertEq( + // initialRiskConfig.optimalUsageRatio.maxPercentChange, + // updatedRiskConfig.optimalUsageRatio.maxPercentChange + // ); + // assertEq( + // initialRiskConfig.priceCapLst.maxPercentChange, + // updatedRiskConfig.priceCapLst.maxPercentChange + // ); + // assertEq(initialRiskConfig.priceCapLst.minDelay, updatedRiskConfig.priceCapLst.minDelay); + // assertEq( + // initialRiskConfig.priceCapStable.maxPercentChange, + // updatedRiskConfig.priceCapStable.maxPercentChange + // ); + // assertEq(initialRiskConfig.priceCapStable.minDelay, updatedRiskConfig.priceCapStable.minDelay); + // } function _getInterestRatesForAsset( address asset diff --git a/tests/RiskStewardCapo.t.sol b/tests/RiskStewardCapo.t.sol index 0506ea5..1499dca 100644 --- a/tests/RiskStewardCapo.t.sol +++ b/tests/RiskStewardCapo.t.sol @@ -32,31 +32,20 @@ contract RiskSteward_Capo_Test is Test { minDelay: 5 days, maxPercentChange: 10_00 // 10% }); + IRiskSteward.Config memory riskConfig; + riskConfig.priceCapConfig.priceCapLst = defaultRiskParamConfig; + riskConfig.priceCapConfig.priceCapStable = defaultRiskParamConfig; - IRiskSteward.Config memory riskConfig = IRiskSteward.Config({ - ltv: defaultRiskParamConfig, - liquidationThreshold: defaultRiskParamConfig, - liquidationBonus: defaultRiskParamConfig, - supplyCap: defaultRiskParamConfig, - borrowCap: defaultRiskParamConfig, - debtCeiling: defaultRiskParamConfig, - baseVariableBorrowRate: defaultRiskParamConfig, - variableRateSlope1: defaultRiskParamConfig, - variableRateSlope2: defaultRiskParamConfig, - optimalUsageRatio: defaultRiskParamConfig, - priceCapLst: defaultRiskParamConfig, - priceCapStable: defaultRiskParamConfig - }); - - vm.startPrank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward = new RiskSteward( - AaveV3Ethereum.AAVE_PROTOCOL_DATA_PROVIDER, - IEngine(AaveV3Ethereum.CONFIG_ENGINE), + address(AaveV3Ethereum.POOL_ADDRESSES_PROVIDER), + AaveV3Ethereum.CONFIG_ENGINE, riskCouncil, + GovernanceV3Ethereum.EXECUTOR_LVL_1, riskConfig ); + + vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); AaveV3Ethereum.ACL_MANAGER.addRiskAdmin(address(steward)); - vm.stopPrank(); currentRatio = IPriceCapAdapter(AaveV3EthereumAssets.wstETH_ORACLE) .getRatio() From d8b5eca145c5fe9293b3a27f6e930520771340d1 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Sat, 22 Mar 2025 19:06:01 +0530 Subject: [PATCH 02/25] test: emode updates --- tests/EdgeRiskStewardCaps.t.sol | 72 ++--- tests/EdgeRiskStewardRates.t.sol | 65 ++--- tests/RiskSteward.t.sol | 484 +++++++++++++++++++++++++------ 3 files changed, 448 insertions(+), 173 deletions(-) diff --git a/tests/EdgeRiskStewardCaps.t.sol b/tests/EdgeRiskStewardCaps.t.sol index 376e00b..8df5fed 100644 --- a/tests/EdgeRiskStewardCaps.t.sol +++ b/tests/EdgeRiskStewardCaps.t.sol @@ -24,23 +24,7 @@ contract EdgeRiskStewardCaps_Test is RiskSteward_Test { /* ----------------------------- Rates Tests ----------------------------- */ function test_updateRates() public override { - ( - uint256 beforeOptimalUsageRatio, - uint256 beforeBaseVariableBorrowRate, - uint256 beforeVariableRateSlope1, - uint256 beforeVariableRateSlope2 - ) = _getInterestRatesForAsset(AaveV3EthereumAssets.WETH_UNDERLYING); - IEngine.RateStrategyUpdate[] memory rateUpdates = new IEngine.RateStrategyUpdate[](1); - rateUpdates[0] = IEngine.RateStrategyUpdate({ - asset: AaveV3EthereumAssets.WETH_UNDERLYING, - params: IEngine.InterestRateInputData({ - optimalUsageRatio: beforeOptimalUsageRatio + 5_00, // 5% absolute increase - baseVariableBorrowRate: beforeBaseVariableBorrowRate + 10_00, // 10% absolute increase - variableRateSlope1: beforeVariableRateSlope1 + 10_00, // 10% absolute increase - variableRateSlope2: beforeVariableRateSlope2 + 10_00 // 10% absolute increase - }) - }); vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); @@ -62,24 +46,7 @@ contract EdgeRiskStewardCaps_Test is RiskSteward_Test { /* ----------------------------- Collateral Tests ----------------------------- */ function test_updateCollateralSide() public override { - (, uint256 ltvBefore, uint256 ltBefore, uint256 lbBefore, , , , , , ) = AaveV3Ethereum - .AAVE_PROTOCOL_DATA_PROVIDER - .getReserveConfigurationData(AaveV3EthereumAssets.UNI_UNDERLYING); - - // as the definition is with 2 decimals, and config engine does not take the decimals into account, so we divide by 100. - uint256 debtCeilingBefore = AaveV3Ethereum.AAVE_PROTOCOL_DATA_PROVIDER.getDebtCeiling( - AaveV3EthereumAssets.UNI_UNDERLYING - ) / 100; - IEngine.CollateralUpdate[] memory collateralUpdates = new IEngine.CollateralUpdate[](1); - collateralUpdates[0] = IEngine.CollateralUpdate({ - asset: AaveV3EthereumAssets.UNI_UNDERLYING, - ltv: ltvBefore + 10_00, // 10% absolute increase - liqThreshold: ltBefore + 5_00, // 5% absolute increase - liqBonus: (lbBefore - 100_00) + 2_00, // 2% absolute increase - debtCeiling: (debtCeilingBefore * 110) / 100, // 10% relative increase - liqProtocolFee: EngineFlags.KEEP_CURRENT - }); vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); @@ -102,20 +69,38 @@ contract EdgeRiskStewardCaps_Test is RiskSteward_Test { function test_updateCollaterals_sameUpdate() public override {} + /* ----------------------------- EMode Category Update Tests ----------------------------- */ + + function test_updateEModeCategories() public override { + IEngine.EModeCategoryUpdate[] memory eModeCategoryUpdates = new IEngine.EModeCategoryUpdate[](1); + + vm.startPrank(riskCouncil); + vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); + steward.updateEModeCategories(eModeCategoryUpdates); + } + + function test_updateEModeCategories_outOfRange() public override {} + + function test_updateEModeCategories_debounceNotRespected() public override {} + + function test_updateEModeCategories_eModeDoesNotExist() public override {} + + function test_updateEModeCategories_eModeRestricted() public override {} + + function test_updateEModeCategories_toValueZeroNotAllowed() public override {} + + function test_updateEModeCategories_allKeepCurrent() public override {} + + function test_updateEModeCategories_sameUpdate() public override {} + + function test_updateEModeCategories_onlyLabelChange() public override {} + /* ----------------------------- LST Price Cap Tests ----------------------------- */ function test_updateLstPriceCap() public { IRiskSteward.PriceCapLstUpdate[] memory priceCapUpdates = new IRiskSteward.PriceCapLstUpdate[]( 1 ); - priceCapUpdates[0] = IRiskSteward.PriceCapLstUpdate({ - oracle: AaveV3EthereumAssets.wstETH_ORACLE, - priceCapUpdateParams: IPriceCapAdapter.PriceCapUpdateParams({ - snapshotTimestamp: uint48(block.timestamp - 2), - snapshotRatio: 1.1e18, - maxYearlyRatioGrowthPercent: 9_68 - }) - }); vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); @@ -128,11 +113,6 @@ contract EdgeRiskStewardCaps_Test is RiskSteward_Test { IRiskSteward.PriceCapStableUpdate[] memory priceCapUpdates = new IRiskSteward.PriceCapStableUpdate[](1); - priceCapUpdates[0] = IRiskSteward.PriceCapStableUpdate({ - oracle: AaveV3EthereumAssets.USDT_ORACLE, - priceCap: 1060000 - }); - vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); steward.updateStablePriceCaps(priceCapUpdates); diff --git a/tests/EdgeRiskStewardRates.t.sol b/tests/EdgeRiskStewardRates.t.sol index 0287ee0..235e967 100644 --- a/tests/EdgeRiskStewardRates.t.sol +++ b/tests/EdgeRiskStewardRates.t.sol @@ -24,16 +24,7 @@ contract EdgeRiskStewardRates_Test is RiskSteward_Test { /* ----------------------------- Caps Tests ----------------------------- */ function test_updateCaps() public override { - (uint256 daiBorrowCapBefore, uint256 daiSupplyCapBefore) = AaveV3Ethereum - .AAVE_PROTOCOL_DATA_PROVIDER - .getReserveCaps(AaveV3EthereumAssets.DAI_UNDERLYING); - IEngine.CapsUpdate[] memory capUpdates = new IEngine.CapsUpdate[](1); - capUpdates[0] = IEngine.CapsUpdate( - AaveV3EthereumAssets.DAI_UNDERLYING, - (daiSupplyCapBefore * 110) / 100, // 10% relative increase - (daiBorrowCapBefore * 110) / 100 // 10% relative increase - ); vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); @@ -57,24 +48,7 @@ contract EdgeRiskStewardRates_Test is RiskSteward_Test { /* ----------------------------- Collateral Tests ----------------------------- */ function test_updateCollateralSide() public override { - (, uint256 ltvBefore, uint256 ltBefore, uint256 lbBefore, , , , , , ) = AaveV3Ethereum - .AAVE_PROTOCOL_DATA_PROVIDER - .getReserveConfigurationData(AaveV3EthereumAssets.UNI_UNDERLYING); - - // as the definition is with 2 decimals, and config engine does not take the decimals into account, so we divide by 100. - uint256 debtCeilingBefore = AaveV3Ethereum.AAVE_PROTOCOL_DATA_PROVIDER.getDebtCeiling( - AaveV3EthereumAssets.UNI_UNDERLYING - ) / 100; - IEngine.CollateralUpdate[] memory collateralUpdates = new IEngine.CollateralUpdate[](1); - collateralUpdates[0] = IEngine.CollateralUpdate({ - asset: AaveV3EthereumAssets.UNI_UNDERLYING, - ltv: ltvBefore + 10_00, // 10% absolute increase - liqThreshold: ltBefore + 5_00, // 5% absolute increase - liqBonus: (lbBefore - 100_00) + 2_00, // 2% absolute increase - debtCeiling: (debtCeilingBefore * 110) / 100, // 10% relative increase - liqProtocolFee: EngineFlags.KEEP_CURRENT - }); vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); @@ -97,20 +71,38 @@ contract EdgeRiskStewardRates_Test is RiskSteward_Test { function test_updateCollaterals_sameUpdate() public override {} + /* ----------------------------- EMode Category Update Tests ----------------------------- */ + + function test_updateEModeCategories() public override { + IEngine.EModeCategoryUpdate[] memory eModeCategoryUpdates = new IEngine.EModeCategoryUpdate[](1); + + vm.startPrank(riskCouncil); + vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); + steward.updateEModeCategories(eModeCategoryUpdates); + } + + function test_updateEModeCategories_outOfRange() public override {} + + function test_updateEModeCategories_debounceNotRespected() public override {} + + function test_updateEModeCategories_eModeDoesNotExist() public override {} + + function test_updateEModeCategories_eModeRestricted() public override {} + + function test_updateEModeCategories_toValueZeroNotAllowed() public override {} + + function test_updateEModeCategories_allKeepCurrent() public override {} + + function test_updateEModeCategories_sameUpdate() public override {} + + function test_updateEModeCategories_onlyLabelChange() public override {} + /* ----------------------------- LST Price Cap Tests ----------------------------- */ function test_updateLstPriceCap() public { IRiskSteward.PriceCapLstUpdate[] memory priceCapUpdates = new IRiskSteward.PriceCapLstUpdate[]( 1 ); - priceCapUpdates[0] = IRiskSteward.PriceCapLstUpdate({ - oracle: AaveV3EthereumAssets.wstETH_ORACLE, - priceCapUpdateParams: IPriceCapAdapter.PriceCapUpdateParams({ - snapshotTimestamp: uint48(block.timestamp - 2), - snapshotRatio: 1.1e18, - maxYearlyRatioGrowthPercent: 9_68 - }) - }); vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); @@ -123,11 +115,6 @@ contract EdgeRiskStewardRates_Test is RiskSteward_Test { IRiskSteward.PriceCapStableUpdate[] memory priceCapUpdates = new IRiskSteward.PriceCapStableUpdate[](1); - priceCapUpdates[0] = IRiskSteward.PriceCapStableUpdate({ - oracle: AaveV3EthereumAssets.USDT_ORACLE, - priceCap: 1060000 - }); - vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); steward.updateStablePriceCaps(priceCapUpdates); diff --git a/tests/RiskSteward.t.sol b/tests/RiskSteward.t.sol index 3dcc2f8..14e457e 100644 --- a/tests/RiskSteward.t.sol +++ b/tests/RiskSteward.t.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; +import {ReserveConfiguration, DataTypes} from 'aave-v3-origin/src/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; import {IACLManager, IPoolConfigurator, IPoolDataProvider} from 'aave-address-book/AaveV3.sol'; import {IDefaultInterestRateStrategyV2} from 'aave-v3-origin/src/contracts/interfaces/IDefaultInterestRateStrategyV2.sol'; import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; @@ -14,13 +15,12 @@ import {Ownable} from 'openzeppelin-contracts/contracts/access/Ownable.sol'; import {DeployRiskStewards} from '../scripts/deploy/DeployStewards.s.sol'; contract RiskSteward_Test is Test { + using ReserveConfiguration for DataTypes.ReserveConfigurationMap; + address public constant riskCouncil = address(42); IRiskSteward public steward; IRiskSteward.Config public riskConfig; - event AddressRestricted(address indexed contractAddress, bool indexed isRestricted); - event RiskConfigSet(IRiskSteward.Config indexed riskConfig); - function setUp() public virtual { vm.createSelectFork(vm.rpcUrl('mainnet'), 21974363); @@ -851,6 +851,280 @@ contract RiskSteward_Test is Test { assertEq(debtCeilingBefore, debtCeilingAfter); } + /* ----------------------------- EMode Category Update Tests ----------------------------- */ + + function test_updateEModeCategories() public virtual { + uint8 eModeId = 1; + DataTypes.CollateralConfig memory currentEmodeConfig = AaveV3Ethereum.POOL.getEModeCategoryCollateralConfig(eModeId); + string memory label = AaveV3Ethereum.POOL.getEModeCategoryLabel(eModeId); + + IEngine.EModeCategoryUpdate[] memory eModeCategoryUpdates = new IEngine.EModeCategoryUpdate[](1); + eModeCategoryUpdates[0] = IEngine.EModeCategoryUpdate({ + eModeCategory: eModeId, + ltv: currentEmodeConfig.ltv + 50, // 0.5% absolute increase + liqThreshold: currentEmodeConfig.liquidationThreshold + 50, // 0.5% absolute increase + liqBonus: (currentEmodeConfig.liquidationBonus - 100_00) + 50, // 0.5% absolute increase + label: EngineFlags.KEEP_CURRENT_STRING + }); + + vm.startPrank(riskCouncil); + steward.updateEModeCategories(eModeCategoryUpdates); + + RiskSteward.Debounce memory lastUpdated = steward.getEModeTimelock(eModeId); + + DataTypes.CollateralConfig memory afterEmodeConfig = AaveV3Ethereum.POOL.getEModeCategoryCollateralConfig(eModeId); + string memory afterLabel = AaveV3Ethereum.POOL.getEModeCategoryLabel(eModeId); + + assertEq(afterEmodeConfig.ltv, eModeCategoryUpdates[0].ltv); + assertEq(afterEmodeConfig.liquidationThreshold, eModeCategoryUpdates[0].liqThreshold); + assertEq(afterEmodeConfig.liquidationBonus - 100_00, eModeCategoryUpdates[0].liqBonus); + assertEq(afterLabel, label); + + assertEq(lastUpdated.eModeLtvLastUpdated, block.timestamp); + assertEq(lastUpdated.eModeLiquidationThresholdLastUpdated, block.timestamp); + assertEq(lastUpdated.eModeLiquidationBonusLastUpdated, block.timestamp); + + // after min time passed test eMode update decrease + vm.warp(block.timestamp + 3 days + 1); + + currentEmodeConfig = AaveV3Ethereum.POOL.getEModeCategoryCollateralConfig(eModeId); + + eModeCategoryUpdates[0] = IEngine.EModeCategoryUpdate({ + eModeCategory: eModeId, + ltv: currentEmodeConfig.ltv - 50, // 0.5% absolute increase + liqThreshold: currentEmodeConfig.liquidationThreshold - 50, // 0.5% absolute increase + liqBonus: (currentEmodeConfig.liquidationBonus - 100_00) - 50, // 0.5% absolute increase + label: EngineFlags.KEEP_CURRENT_STRING + }); + steward.updateEModeCategories(eModeCategoryUpdates); + + afterEmodeConfig = AaveV3Ethereum.POOL.getEModeCategoryCollateralConfig(eModeId); + afterLabel = AaveV3Ethereum.POOL.getEModeCategoryLabel(eModeId); + + assertEq(afterEmodeConfig.ltv, eModeCategoryUpdates[0].ltv); + assertEq(afterEmodeConfig.liquidationThreshold, eModeCategoryUpdates[0].liqThreshold); + assertEq(afterEmodeConfig.liquidationBonus - 100_00, eModeCategoryUpdates[0].liqBonus); + assertEq(afterLabel, label); + + lastUpdated = steward.getEModeTimelock(eModeId); + + assertEq(lastUpdated.eModeLtvLastUpdated, block.timestamp); + assertEq(lastUpdated.eModeLiquidationThresholdLastUpdated, block.timestamp); + assertEq(lastUpdated.eModeLiquidationBonusLastUpdated, block.timestamp); + } + + function test_updateEModeCategories_outOfRange() public virtual { + uint8 eModeId = 1; + DataTypes.CollateralConfig memory currentEmodeConfig = AaveV3Ethereum.POOL.getEModeCategoryCollateralConfig(eModeId); + + IEngine.EModeCategoryUpdate[] memory eModeCategoryUpdates = new IEngine.EModeCategoryUpdate[](1); + eModeCategoryUpdates[0] = IEngine.EModeCategoryUpdate({ + eModeCategory: eModeId, + ltv: currentEmodeConfig.ltv + 51, // 0.5% absolute increase + liqThreshold: currentEmodeConfig.liquidationThreshold + 51, // 0.51% absolute increase + liqBonus: (currentEmodeConfig.liquidationBonus - 100_00) + 51, // 0.51% absolute increase + label: EngineFlags.KEEP_CURRENT_STRING + }); + + vm.startPrank(riskCouncil); + vm.expectRevert(IRiskSteward.UpdateNotInRange.selector); + steward.updateEModeCategories(eModeCategoryUpdates); + + // after min time passed test eMode update decrease + vm.warp(block.timestamp + 3 days + 1); + + eModeCategoryUpdates[0] = IEngine.EModeCategoryUpdate({ + eModeCategory: eModeId, + ltv: currentEmodeConfig.ltv - 51, // 0.51% absolute increase + liqThreshold: currentEmodeConfig.liquidationThreshold - 51, // 0.51% absolute increase + liqBonus: (currentEmodeConfig.liquidationBonus - 100_00) - 51, // 0.51% absolute increase + label: EngineFlags.KEEP_CURRENT_STRING + }); + vm.expectRevert(IRiskSteward.UpdateNotInRange.selector); + steward.updateEModeCategories(eModeCategoryUpdates); + } + + function test_updateEModeCategories_debounceNotRespected() public virtual { + uint8 eModeId = 1; + DataTypes.CollateralConfig memory currentEmodeConfig = AaveV3Ethereum.POOL.getEModeCategoryCollateralConfig(eModeId); + + IEngine.EModeCategoryUpdate[] memory eModeCategoryUpdates = new IEngine.EModeCategoryUpdate[](1); + eModeCategoryUpdates[0] = IEngine.EModeCategoryUpdate({ + eModeCategory: eModeId, + ltv: currentEmodeConfig.ltv + 50, // 0.5% absolute increase + liqThreshold: currentEmodeConfig.liquidationThreshold + 50, // 0.5% absolute increase + liqBonus: (currentEmodeConfig.liquidationBonus - 100_00) + 50, // 0.5% absolute increase + label: EngineFlags.KEEP_CURRENT_STRING + }); + + vm.startPrank(riskCouncil); + steward.updateEModeCategories(eModeCategoryUpdates); + + vm.warp(block.timestamp + 1 days); + + // expect revert as minimum time has not passed for next update + vm.expectRevert(IRiskSteward.DebounceNotRespected.selector); + steward.updateEModeCategories(eModeCategoryUpdates); + } + + function test_updateEModeCategories_eModeDoesNotExist() public virtual { + uint8 eModeId = 100; + IEngine.EModeCategoryUpdate[] memory eModeCategoryUpdates = new IEngine.EModeCategoryUpdate[](1); + eModeCategoryUpdates[0] = IEngine.EModeCategoryUpdate({ + eModeCategory: eModeId, + ltv: 50, + liqThreshold: 50, + liqBonus: 100_00, + label: EngineFlags.KEEP_CURRENT_STRING + }); + + vm.startPrank(riskCouncil); + vm.expectRevert(); + steward.updateEModeCategories(eModeCategoryUpdates); + } + + function test_updateEModeCategories_eModeRestricted() public virtual { + uint8 eModeCategoryId = 1; + vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); + steward.setEModeCategoryRestricted(eModeCategoryId, true); + + IEngine.EModeCategoryUpdate[] memory eModeCategoryUpdates = new IEngine.EModeCategoryUpdate[](1); + eModeCategoryUpdates[0] = IEngine.EModeCategoryUpdate({ + eModeCategory: eModeCategoryId, + ltv: 50, + liqThreshold: 50, + liqBonus: 100_00, + label: EngineFlags.KEEP_CURRENT_STRING + }); + + vm.prank(riskCouncil); + vm.expectRevert(IRiskSteward.EModeIsRestricted.selector); + steward.updateEModeCategories(eModeCategoryUpdates); + } + + function test_updateEModeCategories_toValueZeroNotAllowed() public virtual { + // set risk config to allow 100% collateral param change to 0 + IRiskSteward.RiskParamConfig memory eModeParamConfig = IRiskSteward.RiskParamConfig({ + minDelay: 3 days, + maxPercentChange: 100_00 // 100% relative change + }); + IRiskSteward.Config memory config; + config.eModeConfig.ltv = eModeParamConfig; + config.eModeConfig.liquidationThreshold = eModeParamConfig; + config.eModeConfig.liquidationBonus = eModeParamConfig; + + vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); + steward.setRiskConfig(config); + + IEngine.EModeCategoryUpdate[] memory eModeCategoryUpdates = new IEngine.EModeCategoryUpdate[](1); + eModeCategoryUpdates[0] = IEngine.EModeCategoryUpdate({ + eModeCategory: 1, + ltv: 0, + liqThreshold: 0, + liqBonus: 0, + label: EngineFlags.KEEP_CURRENT_STRING + }); + + vm.startPrank(riskCouncil); + vm.expectRevert(IRiskSteward.InvalidUpdateToZero.selector); + steward.updateEModeCategories(eModeCategoryUpdates); + } + + function test_updateEModeCategories_allKeepCurrent() public virtual { + uint8 eModeId = 1; + DataTypes.CollateralConfig memory prevEmodeConfig = AaveV3Ethereum.POOL.getEModeCategoryCollateralConfig(eModeId); + string memory prevLabel = AaveV3Ethereum.POOL.getEModeCategoryLabel(eModeId); + RiskSteward.Debounce memory prevLastUpdated = steward.getEModeTimelock(eModeId); + + IEngine.EModeCategoryUpdate[] memory eModeCategoryUpdates = new IEngine.EModeCategoryUpdate[](1); + eModeCategoryUpdates[0] = IEngine.EModeCategoryUpdate({ + eModeCategory: eModeId, + ltv: EngineFlags.KEEP_CURRENT, + liqThreshold: EngineFlags.KEEP_CURRENT, + liqBonus: EngineFlags.KEEP_CURRENT, + label: EngineFlags.KEEP_CURRENT_STRING + }); + + vm.startPrank(riskCouncil); + steward.updateEModeCategories(eModeCategoryUpdates); + + DataTypes.CollateralConfig memory afterEmodeConfig = AaveV3Ethereum.POOL.getEModeCategoryCollateralConfig(eModeId); + RiskSteward.Debounce memory afterLastUpdated = steward.getEModeTimelock(eModeId); + string memory afterLabel = AaveV3Ethereum.POOL.getEModeCategoryLabel(eModeId); + + assertEq(afterEmodeConfig.ltv, prevEmodeConfig.ltv); + assertEq(afterEmodeConfig.liquidationThreshold, prevEmodeConfig.liquidationThreshold); + assertEq(afterEmodeConfig.liquidationBonus, prevEmodeConfig.liquidationBonus); + assertEq(afterLabel, prevLabel); + + assertEq(prevLastUpdated.eModeLtvLastUpdated, afterLastUpdated.eModeLtvLastUpdated); + assertEq(prevLastUpdated.eModeLiquidationThresholdLastUpdated, afterLastUpdated.eModeLiquidationThresholdLastUpdated); + assertEq(prevLastUpdated.eModeLiquidationBonusLastUpdated, afterLastUpdated.eModeLiquidationBonusLastUpdated); + } + + function test_updateEModeCategories_sameUpdate() public virtual { + uint8 eModeId = 1; + DataTypes.CollateralConfig memory prevEmodeConfig = AaveV3Ethereum.POOL.getEModeCategoryCollateralConfig(eModeId); + string memory prevLabel = AaveV3Ethereum.POOL.getEModeCategoryLabel(eModeId); + + IEngine.EModeCategoryUpdate[] memory eModeCategoryUpdates = new IEngine.EModeCategoryUpdate[](1); + eModeCategoryUpdates[0] = IEngine.EModeCategoryUpdate({ + eModeCategory: eModeId, + ltv: prevEmodeConfig.ltv, + liqThreshold: prevEmodeConfig.liquidationThreshold, + liqBonus: prevEmodeConfig.liquidationBonus - 100_00, + label: EngineFlags.KEEP_CURRENT_STRING + }); + + vm.startPrank(riskCouncil); + steward.updateEModeCategories(eModeCategoryUpdates); + + DataTypes.CollateralConfig memory afterEmodeConfig = AaveV3Ethereum.POOL.getEModeCategoryCollateralConfig(eModeId); + RiskSteward.Debounce memory afterLastUpdated = steward.getEModeTimelock(eModeId); + string memory afterLabel = AaveV3Ethereum.POOL.getEModeCategoryLabel(eModeId); + + assertEq(afterEmodeConfig.ltv, prevEmodeConfig.ltv); + assertEq(afterEmodeConfig.liquidationThreshold, prevEmodeConfig.liquidationThreshold); + assertEq(afterEmodeConfig.liquidationBonus, prevEmodeConfig.liquidationBonus); + assertEq(afterLabel, prevLabel); + + assertEq(afterLastUpdated.eModeLtvLastUpdated, block.timestamp); + assertEq(afterLastUpdated.eModeLiquidationThresholdLastUpdated, block.timestamp); + assertEq(afterLastUpdated.eModeLiquidationBonusLastUpdated, block.timestamp); + } + + function test_updateEModeCategories_onlyLabelChange() public virtual { + uint8 eModeId = 1; + string memory newLabel = 'NEW_EMODE_LABEL'; + + IEngine.EModeCategoryUpdate[] memory eModeCategoryUpdates = new IEngine.EModeCategoryUpdate[](1); + eModeCategoryUpdates[0] = IEngine.EModeCategoryUpdate({ + eModeCategory: eModeId, + ltv: EngineFlags.KEEP_CURRENT, + liqThreshold: EngineFlags.KEEP_CURRENT, + liqBonus: EngineFlags.KEEP_CURRENT, + label: newLabel + }); + + vm.startPrank(riskCouncil); + steward.updateEModeCategories(eModeCategoryUpdates); + + string memory afterLabel = AaveV3Ethereum.POOL.getEModeCategoryLabel(eModeId); + assertEq(newLabel, afterLabel); + + eModeCategoryUpdates[0] = IEngine.EModeCategoryUpdate({ + eModeCategory: eModeId, + ltv: EngineFlags.KEEP_CURRENT, + liqThreshold: EngineFlags.KEEP_CURRENT, + liqBonus: EngineFlags.KEEP_CURRENT, + label: 'LABEL_CHANGE_AGAIN' + }); + + // no timelock for label change + vm.startPrank(riskCouncil); + steward.updateEModeCategories(eModeCategoryUpdates); + } + /* ----------------------------- MISC ----------------------------- */ function test_invalidCaller(address caller) public { @@ -884,6 +1158,15 @@ contract RiskSteward_Test is Test { }) }); + IEngine.EModeCategoryUpdate[] memory eModeCategoryUpdates = new IEngine.EModeCategoryUpdate[](1); + eModeCategoryUpdates[0] = IEngine.EModeCategoryUpdate({ + eModeCategory: 1, + ltv: EngineFlags.KEEP_CURRENT, + liqThreshold: EngineFlags.KEEP_CURRENT, + liqBonus: EngineFlags.KEEP_CURRENT, + label: EngineFlags.KEEP_CURRENT_STRING + }); + vm.startPrank(caller); vm.expectRevert(IRiskSteward.InvalidCaller.selector); @@ -893,7 +1176,10 @@ contract RiskSteward_Test is Test { steward.updateCollateralSide(collateralUpdates); vm.expectRevert(IRiskSteward.InvalidCaller.selector); - steward.updateRates(rateStrategyUpdate); + steward.updateCollateralSide(collateralUpdates); + + vm.expectRevert(IRiskSteward.InvalidCaller.selector); + steward.updateEModeCategories(eModeCategoryUpdates); vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, caller)); steward.setRiskConfig(riskConfig); @@ -901,12 +1187,15 @@ contract RiskSteward_Test is Test { vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, caller)); steward.setAddressRestricted(AaveV3EthereumAssets.GHO_UNDERLYING, true); + vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, caller)); + steward.setEModeCategoryRestricted(1, true); + vm.stopPrank(); } function test_assetRestricted() public { vm.expectEmit(); - emit AddressRestricted(AaveV3EthereumAssets.GHO_UNDERLYING, true); + emit IRiskSteward.AddressRestricted(AaveV3EthereumAssets.GHO_UNDERLYING, true); vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward.setAddressRestricted(AaveV3EthereumAssets.GHO_UNDERLYING, true); @@ -914,7 +1203,7 @@ contract RiskSteward_Test is Test { assertTrue(steward.isAddressRestricted(AaveV3EthereumAssets.GHO_UNDERLYING)); vm.expectEmit(); - emit AddressRestricted(AaveV3EthereumAssets.GHO_UNDERLYING, false); + emit IRiskSteward.AddressRestricted(AaveV3EthereumAssets.GHO_UNDERLYING, false); vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward.setAddressRestricted(AaveV3EthereumAssets.GHO_UNDERLYING, false); @@ -922,6 +1211,25 @@ contract RiskSteward_Test is Test { assertFalse(steward.isAddressRestricted(AaveV3EthereumAssets.GHO_UNDERLYING)); } + function test_eModeCategoryRestricted() public { + uint8 eModeId = 1; + vm.expectEmit(); + emit IRiskSteward.EModeRestricted(eModeId, true); + + vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); + steward.setEModeCategoryRestricted(eModeId, true); + + assertTrue(steward.isEModeCategoryRestricted(eModeId)); + + vm.expectEmit(); + emit IRiskSteward.EModeRestricted(eModeId, false); + + vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); + steward.setEModeCategoryRestricted(eModeId, false); + + assertFalse(steward.isEModeCategoryRestricted(eModeId)); + } + function test_setRiskConfig() public { IRiskSteward.RiskParamConfig memory newRiskParamConfig = IRiskSteward.RiskParamConfig({ minDelay: 10 days, @@ -957,94 +1265,94 @@ contract RiskSteward_Test is Test { }); vm.expectEmit(); - emit RiskConfigSet(initialRiskConfig); + emit IRiskSteward.RiskConfigSet(initialRiskConfig); vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward.setRiskConfig(initialRiskConfig); - // _validateRiskConfig(initialRiskConfig, steward.getRiskConfig()); + _validateRiskConfig(initialRiskConfig, steward.getRiskConfig()); } - // function _validateRiskConfig( - // IRiskSteward.Config memory initialRiskConfig, - // IRiskSteward.Config memory updatedRiskConfig - // ) internal pure { - // assertEq(initialRiskConfig.ltv.minDelay, updatedRiskConfig.ltv.minDelay); - // assertEq(initialRiskConfig.ltv.maxPercentChange, updatedRiskConfig.ltv.maxPercentChange); - // assertEq( - // initialRiskConfig.liquidationThreshold.minDelay, - // updatedRiskConfig.liquidationThreshold.minDelay - // ); - // assertEq( - // initialRiskConfig.liquidationThreshold.maxPercentChange, - // updatedRiskConfig.liquidationThreshold.maxPercentChange - // ); - // assertEq( - // initialRiskConfig.liquidationBonus.minDelay, - // updatedRiskConfig.liquidationBonus.minDelay - // ); - // assertEq( - // initialRiskConfig.liquidationBonus.maxPercentChange, - // updatedRiskConfig.liquidationBonus.maxPercentChange - // ); - // assertEq(initialRiskConfig.supplyCap.minDelay, updatedRiskConfig.supplyCap.minDelay); - // assertEq( - // initialRiskConfig.supplyCap.maxPercentChange, - // updatedRiskConfig.supplyCap.maxPercentChange - // ); - // assertEq(initialRiskConfig.borrowCap.minDelay, updatedRiskConfig.borrowCap.minDelay); - // assertEq( - // initialRiskConfig.borrowCap.maxPercentChange, - // updatedRiskConfig.borrowCap.maxPercentChange - // ); - // assertEq(initialRiskConfig.debtCeiling.minDelay, updatedRiskConfig.debtCeiling.minDelay); - // assertEq( - // initialRiskConfig.debtCeiling.maxPercentChange, - // updatedRiskConfig.debtCeiling.maxPercentChange - // ); - // assertEq( - // initialRiskConfig.baseVariableBorrowRate.minDelay, - // updatedRiskConfig.baseVariableBorrowRate.minDelay - // ); - // assertEq( - // initialRiskConfig.baseVariableBorrowRate.maxPercentChange, - // updatedRiskConfig.baseVariableBorrowRate.maxPercentChange - // ); - // assertEq( - // initialRiskConfig.variableRateSlope1.minDelay, - // updatedRiskConfig.variableRateSlope1.minDelay - // ); - // assertEq( - // initialRiskConfig.variableRateSlope1.maxPercentChange, - // updatedRiskConfig.variableRateSlope1.maxPercentChange - // ); - // assertEq( - // initialRiskConfig.variableRateSlope2.minDelay, - // updatedRiskConfig.variableRateSlope2.minDelay - // ); - // assertEq( - // initialRiskConfig.variableRateSlope2.maxPercentChange, - // updatedRiskConfig.variableRateSlope2.maxPercentChange - // ); - // assertEq( - // initialRiskConfig.optimalUsageRatio.minDelay, - // updatedRiskConfig.optimalUsageRatio.minDelay - // ); - // assertEq( - // initialRiskConfig.optimalUsageRatio.maxPercentChange, - // updatedRiskConfig.optimalUsageRatio.maxPercentChange - // ); - // assertEq( - // initialRiskConfig.priceCapLst.maxPercentChange, - // updatedRiskConfig.priceCapLst.maxPercentChange - // ); - // assertEq(initialRiskConfig.priceCapLst.minDelay, updatedRiskConfig.priceCapLst.minDelay); - // assertEq( - // initialRiskConfig.priceCapStable.maxPercentChange, - // updatedRiskConfig.priceCapStable.maxPercentChange - // ); - // assertEq(initialRiskConfig.priceCapStable.minDelay, updatedRiskConfig.priceCapStable.minDelay); - // } + function _validateRiskConfig( + IRiskSteward.Config memory initialRiskConfig, + IRiskSteward.Config memory updatedRiskConfig + ) internal pure { + assertEq(initialRiskConfig.collateralConfig.ltv.minDelay, updatedRiskConfig.collateralConfig.ltv.minDelay); + assertEq(initialRiskConfig.collateralConfig.ltv.maxPercentChange, updatedRiskConfig.collateralConfig.ltv.maxPercentChange); + assertEq( + initialRiskConfig.collateralConfig.liquidationThreshold.minDelay, + updatedRiskConfig.collateralConfig.liquidationThreshold.minDelay + ); + assertEq( + initialRiskConfig.collateralConfig.liquidationThreshold.maxPercentChange, + updatedRiskConfig.collateralConfig.liquidationThreshold.maxPercentChange + ); + assertEq( + initialRiskConfig.collateralConfig.liquidationBonus.minDelay, + updatedRiskConfig.collateralConfig.liquidationBonus.minDelay + ); + assertEq( + initialRiskConfig.collateralConfig.liquidationBonus.maxPercentChange, + updatedRiskConfig.collateralConfig.liquidationBonus.maxPercentChange + ); + assertEq(initialRiskConfig.capConfig.supplyCap.minDelay, updatedRiskConfig.capConfig.supplyCap.minDelay); + assertEq( + initialRiskConfig.capConfig.supplyCap.maxPercentChange, + updatedRiskConfig.capConfig.supplyCap.maxPercentChange + ); + assertEq(initialRiskConfig.capConfig.borrowCap.minDelay, updatedRiskConfig.capConfig.borrowCap.minDelay); + assertEq( + initialRiskConfig.capConfig.borrowCap.maxPercentChange, + updatedRiskConfig.capConfig.borrowCap.maxPercentChange + ); + assertEq(initialRiskConfig.collateralConfig.debtCeiling.minDelay, updatedRiskConfig.collateralConfig.debtCeiling.minDelay); + assertEq( + initialRiskConfig.collateralConfig.debtCeiling.maxPercentChange, + updatedRiskConfig.collateralConfig.debtCeiling.maxPercentChange + ); + assertEq( + initialRiskConfig.rateConfig.baseVariableBorrowRate.minDelay, + updatedRiskConfig.rateConfig.baseVariableBorrowRate.minDelay + ); + assertEq( + initialRiskConfig.rateConfig.baseVariableBorrowRate.maxPercentChange, + updatedRiskConfig.rateConfig.baseVariableBorrowRate.maxPercentChange + ); + assertEq( + initialRiskConfig.rateConfig.variableRateSlope1.minDelay, + updatedRiskConfig.rateConfig.variableRateSlope1.minDelay + ); + assertEq( + initialRiskConfig.rateConfig.variableRateSlope1.maxPercentChange, + updatedRiskConfig.rateConfig.variableRateSlope1.maxPercentChange + ); + assertEq( + initialRiskConfig.rateConfig.variableRateSlope2.minDelay, + updatedRiskConfig.rateConfig.variableRateSlope2.minDelay + ); + assertEq( + initialRiskConfig.rateConfig.variableRateSlope2.maxPercentChange, + updatedRiskConfig.rateConfig.variableRateSlope2.maxPercentChange + ); + assertEq( + initialRiskConfig.rateConfig.optimalUsageRatio.minDelay, + updatedRiskConfig.rateConfig.optimalUsageRatio.minDelay + ); + assertEq( + initialRiskConfig.rateConfig.optimalUsageRatio.maxPercentChange, + updatedRiskConfig.rateConfig.optimalUsageRatio.maxPercentChange + ); + assertEq( + initialRiskConfig.priceCapConfig.priceCapLst.maxPercentChange, + updatedRiskConfig.priceCapConfig.priceCapLst.maxPercentChange + ); + assertEq(initialRiskConfig.priceCapConfig.priceCapLst.minDelay, updatedRiskConfig.priceCapConfig.priceCapLst.minDelay); + assertEq( + initialRiskConfig.priceCapConfig.priceCapStable.maxPercentChange, + updatedRiskConfig.priceCapConfig.priceCapStable.maxPercentChange + ); + assertEq(initialRiskConfig.priceCapConfig.priceCapStable.minDelay, updatedRiskConfig.priceCapConfig.priceCapStable.minDelay); + } function _getInterestRatesForAsset( address asset From da9ac080c996d3bc1b69b1977e5386b61f92be1b Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Tue, 25 Mar 2025 19:59:37 +0530 Subject: [PATCH 03/25] fix: use bytes20 for timelock --- src/contracts/RiskSteward.sol | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/contracts/RiskSteward.sol b/src/contracts/RiskSteward.sol index 21bc3e1..d088048 100644 --- a/src/contracts/RiskSteward.sol +++ b/src/contracts/RiskSteward.sol @@ -38,7 +38,7 @@ contract RiskSteward is Ownable, IRiskSteward { Config internal _riskConfig; - mapping(bytes32 id => Debounce) internal _timelocks; + mapping(bytes20 id => Debounce) internal _timelocks; mapping(address => bool) internal _restrictedAddresses; @@ -125,7 +125,7 @@ contract RiskSteward is Ownable, IRiskSteward { /// @inheritdoc IRiskSteward function getEModeTimelock(uint8 eModeCategoryId) external view returns (Debounce memory) { - return _timelocks[bytes32(uint256(eModeCategoryId))]; + return _timelocks[bytes20(uint160(eModeCategoryId))]; } /// @inheritdoc IRiskSteward @@ -351,7 +351,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentEmodeConfig.ltv, newValue: eModeCategoryUpdates[i].ltv, - lastUpdated: _timelocks[bytes32(uint256(eModeId))].eModeLtvLastUpdated, + lastUpdated: _timelocks[bytes20(uint160(eModeId))].eModeLtvLastUpdated, riskConfig: _riskConfig.eModeConfig.ltv, isChangeRelative: false }) @@ -360,7 +360,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentEmodeConfig.liquidationThreshold, newValue: eModeCategoryUpdates[i].liqThreshold, - lastUpdated: _timelocks[bytes32(uint256(eModeId))].eModeLiquidationThresholdLastUpdated, + lastUpdated: _timelocks[bytes20(uint160(eModeId))].eModeLiquidationThresholdLastUpdated, riskConfig: _riskConfig.eModeConfig.liquidationThreshold, isChangeRelative: false }) @@ -369,7 +369,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentEmodeConfig.liquidationBonus - 100_00, // as the definition is 100% + x%, and config engine takes into account x% for simplicity. newValue: eModeCategoryUpdates[i].liqBonus, - lastUpdated: _timelocks[bytes32(uint256(eModeId))].eModeLiquidationBonusLastUpdated, + lastUpdated: _timelocks[bytes20(uint160(eModeId))].eModeLiquidationBonusLastUpdated, riskConfig: _riskConfig.eModeConfig.liquidationBonus, isChangeRelative: false }) @@ -555,15 +555,15 @@ contract RiskSteward is Ownable, IRiskSteward { uint8 eModeId = eModeCategoryUpdates[i].eModeCategory; if (eModeCategoryUpdates[i].ltv != EngineFlags.KEEP_CURRENT) { - _timelocks[bytes32(uint256(eModeId))].eModeLtvLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(uint160(eModeId))].eModeLtvLastUpdated = uint40(block.timestamp); } if (eModeCategoryUpdates[i].liqThreshold != EngineFlags.KEEP_CURRENT) { - _timelocks[bytes32(uint256(eModeId))].eModeLiquidationThresholdLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(uint160(eModeId))].eModeLiquidationThresholdLastUpdated = uint40(block.timestamp); } if (eModeCategoryUpdates[i].liqBonus != EngineFlags.KEEP_CURRENT) { - _timelocks[bytes32(uint256(eModeId))].eModeLiquidationBonusLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(uint160(eModeId))].eModeLiquidationBonusLastUpdated = uint40(block.timestamp); } } From 603319de84fbb3374df8ee479993c0d6a31f9707 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Tue, 25 Mar 2025 20:56:08 +0530 Subject: [PATCH 04/25] feat: add generator for emode updates --- generator/cli.ts | 4 +- generator/common.ts | 9 +- .../__snapshots__/eModeUpdates.spec.ts.snap | 102 ++++++++++++++++++ generator/features/eModeUpdates.spec.ts | 37 +++++++ generator/features/eModeUpdates.ts | 82 ++++++++++++++ generator/features/mocks/configs.ts | 12 ++- generator/features/types.ts | 9 ++ generator/prompts.ts | 15 +-- generator/types.ts | 1 + scripts/RiskStewardsBase.s.sol | 27 ++++- 10 files changed, 280 insertions(+), 18 deletions(-) create mode 100644 generator/features/__snapshots__/eModeUpdates.spec.ts.snap create mode 100644 generator/features/eModeUpdates.spec.ts create mode 100644 generator/features/eModeUpdates.ts diff --git a/generator/cli.ts b/generator/cli.ts index 1bc77bb..fbbf93c 100644 --- a/generator/cli.ts +++ b/generator/cli.ts @@ -13,6 +13,7 @@ import { import {capsUpdates} from './features/capsUpdates'; import {rateUpdatesV3} from './features/rateUpdates'; import {collateralsUpdates} from './features/collateralsUpdates'; +import {eModeUpdates} from './features/eModeUpdates'; import {lstPriceCapsUpdates} from './features/lstPriceCapsUpdates'; import {stablePriceCapsUpdates} from './features/stablePriceCapsUpdates'; import {generateFiles, writeFiles} from './generator'; @@ -42,7 +43,8 @@ const FEATURE_MODULES_V3 = [ capsUpdates, collateralsUpdates, lstPriceCapsUpdates, - stablePriceCapsUpdates + stablePriceCapsUpdates, + eModeUpdates ]; async function generateDeterministicPoolCache(pool: PoolIdentifier): Promise { diff --git a/generator/common.ts b/generator/common.ts index ad3f18d..7e7e18a 100644 --- a/generator/common.ts +++ b/generator/common.ts @@ -41,9 +41,12 @@ export function getAssets(pool: PoolIdentifier): string[] { return Object.keys(assets); } -export function getEModes(pool: PoolIdentifierV3) { - const eModes = addressBook[pool].E_MODES; - return eModes; +export function getEModes(pool: PoolIdentifierV3): {value: string; id: number}[] { + return Object.keys(addressBook[pool].E_MODES).map((key) => ({ + // map the complex type to a string as used in the sol libs + value: addressBook[pool].E_MODES[key].label.toUpperCase().replace(/[^A-Z0-9]+/gi, '_'), + id: key as unknown as number, + })); } export function getVersion(pool: PoolIdentifier) { diff --git a/generator/features/__snapshots__/eModeUpdates.spec.ts.snap b/generator/features/__snapshots__/eModeUpdates.spec.ts.snap new file mode 100644 index 0000000..7b8ac78 --- /dev/null +++ b/generator/features/__snapshots__/eModeUpdates.spec.ts.snap @@ -0,0 +1,102 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`feature: eModeUpdates > should properly generate files 1`] = ` +{ + "jsonConfig": "import {ConfigFile} from '../../generator/types'; +export const config: ConfigFile = { + rootOptions: { + pools: ['AaveV3Ethereum'], + title: 'test', + shortName: 'Test', + date: '20231023', + author: 'test', + discussion: 'test', + }, + poolOptions: { + AaveV3Ethereum: { + configs: { + EMODES_UPDATE: [ + { + eModeCategory: 'AaveV3EthereumEModes.ETH_CORRELATED', + ltv: '', + liqThreshold: '50', + liqBonus: '', + label: '', + }, + ], + }, + cache: {blockNumber: 42}, + }, + }, +}; +", + "payloads": [ + { + "contractName": "AaveV3Ethereum_Test_20231023", + "payload": "// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3EthereumEModes} from 'aave-address-book/AaveV3Ethereum.sol'; +import {RiskStewardsEthereum} from '../../../../scripts/networks/RiskStewardsEthereum.s.sol'; +import {EngineFlags} from 'aave-v3-origin/src/contracts/extensions/v3-config-engine/EngineFlags.sol'; +import {IAaveV3ConfigEngine} from 'aave-v3-origin/src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol'; + +/** + * @title test + * @author test + * - discussion: test + * - deploy-command: make run-script contract=src/contracts/updates/20231023_AaveV3Ethereum_Test/AaveV3Ethereum_Test_20231023.sol:AaveV3Ethereum_Test_20231023 network=mainnet broadcast=false generate_diff=true skip_timelock=false + */ +contract AaveV3Ethereum_Test_20231023 is RiskStewardsEthereum { + function name() public pure override returns (string memory) { + return 'AaveV3Ethereum_Test_20231023'; + } + + function eModeCategoriesUpdates() + public + pure + override + returns (IAaveV3ConfigEngine.EModeCategoryUpdate[] memory) + { + IAaveV3ConfigEngine.EModeCategoryUpdate[] + memory eModeUpdates = new IAaveV3ConfigEngine.EModeCategoryUpdate[](1); + + eModeUpdates[0] = IAaveV3ConfigEngine.EModeCategoryUpdate({ + eModeCategory: AaveV3EthereumEModes.ETH_CORRELATED, + ltv: EngineFlags.KEEP_CURRENT, + liqThreshold: 50_00, + liqBonus: EngineFlags.KEEP_CURRENT, + label: EngineFlags.KEEP_CURRENT_STRING + }); + + return eModeUpdates; + } +} +", + "pool": "AaveV3Ethereum", + }, + ], +} +`; + +exports[`feature: eModeUpdates > should return reasonable code 1`] = ` +{ + "code": { + "fn": [ + "function eModeCategoriesUpdates() public pure override returns (IAaveV3ConfigEngine.EModeCategoryUpdate[] memory) { + IAaveV3ConfigEngine.EModeCategoryUpdate[] memory eModeUpdates = new IAaveV3ConfigEngine.EModeCategoryUpdate[](1); + + eModeUpdates[0] = IAaveV3ConfigEngine.EModeCategoryUpdate({ + eModeCategory: AaveV3EthereumEModes.ETH_CORRELATED, + ltv: EngineFlags.KEEP_CURRENT, + liqThreshold: 50_00, + liqBonus: EngineFlags.KEEP_CURRENT, + label: EngineFlags.KEEP_CURRENT_STRING + }); + + return eModeUpdates; + }", + ], + }, +} +`; diff --git a/generator/features/eModeUpdates.spec.ts b/generator/features/eModeUpdates.spec.ts new file mode 100644 index 0000000..209a8fc --- /dev/null +++ b/generator/features/eModeUpdates.spec.ts @@ -0,0 +1,37 @@ +// sum.test.js +import {expect, describe, it} from 'vitest'; +import {MOCK_OPTIONS, eModeUpdate} from './mocks/configs'; +import {generateFiles} from '../generator'; +import {FEATURE, PoolConfigs} from '../types'; +import {eModeUpdates} from './eModeUpdates'; + +describe('feature: eModeUpdates', () => { + it('should return reasonable code', () => { + const output = eModeUpdates.build({ + options: MOCK_OPTIONS, + pool: 'AaveV3Ethereum', + cfg: eModeUpdate, + cache: {blockNumber: 42}, + }); + expect(output).toMatchSnapshot(); + }); + + it('should properly generate files', async () => { + const poolConfigs: PoolConfigs = { + ['AaveV3Ethereum']: { + artifacts: [ + eModeUpdates.build({ + options: {...MOCK_OPTIONS, pools: ['AaveV3Ethereum']}, + pool: 'AaveV3Ethereum', + cfg: eModeUpdate, + cache: {blockNumber: 42}, + }), + ], + configs: {[FEATURE.EMODES_UPDATE]: eModeUpdate}, + cache: {blockNumber: 42}, + }, + }; + const files = await generateFiles({...MOCK_OPTIONS, pools: ['AaveV3Ethereum']}, poolConfigs); + expect(files).toMatchSnapshot(); + }); +}); diff --git a/generator/features/eModeUpdates.ts b/generator/features/eModeUpdates.ts new file mode 100644 index 0000000..1e7e76d --- /dev/null +++ b/generator/features/eModeUpdates.ts @@ -0,0 +1,82 @@ +import {CodeArtifact, FEATURE, FeatureModule} from '../types'; +import {eModesSelect} from '../prompts'; +import {EModeCategoryUpdate} from './types'; +import {stringOrKeepCurrent, stringPrompt} from '../prompts/stringPrompt'; +import {percentPrompt, translateJsPercentToSol} from '../prompts/percentPrompt'; + +async function fetchEmodeCategoryUpdate( + eModeCategory: string | number, + required?: T, +): Promise { + return { + eModeCategory, + ltv: await percentPrompt({ + message: 'ltv', + required, + }), + liqThreshold: await percentPrompt({ + message: 'liqThreshold', + required, + }), + liqBonus: await percentPrompt({ + message: 'liqBonus', + required, + }), + label: await stringPrompt({ + message: 'label', + required, + }), + }; +} + +type EmodeUpdates = EModeCategoryUpdate[]; + +export const eModeUpdates: FeatureModule = { + value: FEATURE.EMODES_UPDATE, + description: 'eModeCategoriesUpdates (altering eMode category params)', + async cli({pool}) { + console.log(`Fetching information for EMode category updates on ${pool}`); + + const response: EmodeUpdates = []; + const eModeCategories = await eModesSelect({ + message: 'Select the eModes you want to amend', + pool, + }); + + if (eModeCategories) { + for (const eModeCategory of eModeCategories) { + console.log(`collecting info for ${eModeCategory}`); + response.push(await fetchEmodeCategoryUpdate(eModeCategory)); + } + } + return response; + }, + build({pool, cfg}) { + const response: CodeArtifact = { + code: { + fn: [ + `function eModeCategoriesUpdates() public pure override returns (IAaveV3ConfigEngine.EModeCategoryUpdate[] memory) { + IAaveV3ConfigEngine.EModeCategoryUpdate[] memory eModeUpdates = new IAaveV3ConfigEngine.EModeCategoryUpdate[](${ + cfg.length + }); + + ${cfg + .map( + (cfg, ix) => `eModeUpdates[${ix}] = IAaveV3ConfigEngine.EModeCategoryUpdate({ + eModeCategory: ${cfg.eModeCategory}, + ltv: ${translateJsPercentToSol(cfg.ltv)}, + liqThreshold: ${translateJsPercentToSol(cfg.liqThreshold)}, + liqBonus: ${translateJsPercentToSol(cfg.liqBonus)}, + label: ${stringOrKeepCurrent(cfg.label)} + });`, + ) + .join('\n')} + + return eModeUpdates; + }`, + ], + }, + }; + return response; + }, +}; diff --git a/generator/features/mocks/configs.ts b/generator/features/mocks/configs.ts index 2f3879c..d8bd6af 100644 --- a/generator/features/mocks/configs.ts +++ b/generator/features/mocks/configs.ts @@ -1,5 +1,5 @@ import {Options} from '../../types'; -import {CapsUpdate, CollateralUpdate, RateStrategyUpdate, LstPriceCapUpdate, StablePriceCapUpdate} from '../types'; +import {CapsUpdate, CollateralUpdate, RateStrategyUpdate, LstPriceCapUpdate, StablePriceCapUpdate, EModeCategoryUpdate} from '../types'; export const MOCK_OPTIONS: Options = { pools: ['AaveV3Ethereum'], @@ -29,6 +29,16 @@ export const collateralUpdate: CollateralUpdate[] = [ }, ]; +export const eModeUpdate: EModeCategoryUpdate[] = [ + { + eModeCategory: 'AaveV3EthereumEModes.ETH_CORRELATED', + ltv: '', + liqThreshold: '50', + liqBonus: '', + label: '', + }, +]; + export const rateUpdateV3: RateStrategyUpdate[] = [ { asset: 'WETH', diff --git a/generator/features/types.ts b/generator/features/types.ts index 05e184b..440b508 100644 --- a/generator/features/types.ts +++ b/generator/features/types.ts @@ -21,6 +21,15 @@ export interface CollateralUpdatePartial { export interface CollateralUpdate extends CollateralUpdatePartial, AssetSelector {} +export interface EModeCategoryUpdate { + // library accessor or new id + eModeCategory: string | number; + ltv: NumberInputValues; + liqThreshold: NumberInputValues; + liqBonus: NumberInputValues; + label: string; +} + export interface RateStrategyParams { optimalUtilizationRate: string; baseVariableBorrowRate: string; diff --git a/generator/prompts.ts b/generator/prompts.ts index a128002..4953a6d 100644 --- a/generator/prompts.ts +++ b/generator/prompts.ts @@ -34,13 +34,10 @@ export async function eModeSelect({ pool, }: EModeSelectPrompt) { const eModes = getEModes(pool as any); - if (Object.keys(eModes).length != 0) { + if (eModes.length != 0) { const eMode = await select({ message, - choices: [ - ...(disableKeepCurrent ? [] : [{value: ENGINE_FLAGS.KEEP_CURRENT}]), - ...Object.keys(eModes).map((eMode) => ({value: eMode})), - ], + choices: eModes, }); return translateEModeToEModeLib(eMode, pool); } else { @@ -51,14 +48,10 @@ export async function eModeSelect({ export async function eModesSelect({message, pool}: EModeSelectPrompt) { const eModes = getEModes(pool as any); - if (Object.keys(eModes).length != 0) { + if (eModes.length != 0) { const values = await checkbox({ message, - choices: [ - ...Object.keys(eModes) - .filter((e) => e != 'NONE') - .map((eMode) => ({value: eMode})), - ], + choices: eModes, required: true, }); return values.map((mode) => translateEModeToEModeLib(mode, pool)); diff --git a/generator/types.ts b/generator/types.ts index 12dba94..12ed41f 100644 --- a/generator/types.ts +++ b/generator/types.ts @@ -55,6 +55,7 @@ export type CodeArtifact = { export enum FEATURE { CAPS_UPDATE = 'CAPS_UPDATE', + EMODES_UPDATE = 'EMODES_UPDATE', COLLATERALS_UPDATE = 'COLLATERALS_UPDATE', RATE_UPDATE_V3 = 'RATE_UPDATE_V3', LST_PRICE_CAP_UPDATE = 'LST_PRICE_CAP_UPDATE', diff --git a/scripts/RiskStewardsBase.s.sol b/scripts/RiskStewardsBase.s.sol index e955168..3d705a7 100644 --- a/scripts/RiskStewardsBase.s.sol +++ b/scripts/RiskStewardsBase.s.sol @@ -12,7 +12,7 @@ abstract contract RiskStewardsBase is ProtocolV3TestBase { IPool immutable POOL; IRiskSteward immutable STEWARD; - uint8 public constant MAX_TX = 5; + uint8 public constant MAX_TX = 6; constructor(address pool, address steward) { POOL = IPool(pool); @@ -30,6 +30,13 @@ abstract contract RiskStewardsBase is ProtocolV3TestBase { returns (IEngine.RateStrategyUpdate[] memory) {} + function eModeCategoriesUpdates() + public + pure + virtual + returns (IEngine.EModeCategoryUpdate[] memory) + {} + function lstPriceCapsUpdates() public pure @@ -83,6 +90,7 @@ abstract contract RiskStewardsBase is ProtocolV3TestBase { IEngine.CapsUpdate[] memory capUpdates = capsUpdates(); IEngine.CollateralUpdate[] memory collateralUpdates = collateralsUpdates(); + IEngine.EModeCategoryUpdate[] memory eModeUpdates = eModeCategoriesUpdates(); IEngine.RateStrategyUpdate[] memory rateUpdates = rateStrategiesUpdates(); IRiskSteward.PriceCapLstUpdate[] memory lstPriceCapUpdates = lstPriceCapsUpdates(); IRiskSteward.PriceCapStableUpdate[] memory stablePriceCapUpdates = stablePriceCapsUpdates(); @@ -90,7 +98,7 @@ abstract contract RiskStewardsBase is ProtocolV3TestBase { if (skipTimelock) { // warp to the max timelock - uint40[] memory timelocks = new uint40[](12); + uint40[] memory timelocks = new uint40[](15); uint256 index = 0; // Track the current index for adding elements IRiskSteward.Config memory riskConfig = STEWARD.getRiskConfig(); @@ -104,6 +112,11 @@ abstract contract RiskStewardsBase is ProtocolV3TestBase { timelocks[index++] = riskConfig.collateralConfig.liquidationBonus.minDelay; timelocks[index++] = riskConfig.collateralConfig.debtCeiling.minDelay; } + if (eModeUpdates.length != 0) { + timelocks[index++] = riskConfig.eModeConfig.ltv.minDelay; + timelocks[index++] = riskConfig.eModeConfig.liquidationThreshold.minDelay; + timelocks[index++] = riskConfig.eModeConfig.liquidationBonus.minDelay; + } if (rateUpdates.length != 0) { timelocks[index++] = riskConfig.rateConfig.baseVariableBorrowRate.minDelay; timelocks[index++] = riskConfig.rateConfig.optimalUsageRatio.minDelay; @@ -145,6 +158,16 @@ abstract contract RiskStewardsBase is ProtocolV3TestBase { txCount++; } + if (eModeUpdates.length != 0) { + callDatas[txCount] = abi.encodeWithSelector( + IRiskSteward.updateEModeCategories.selector, + eModeUpdates + ); + (bool success, bytes memory resultData) = address(STEWARD).call(callDatas[txCount]); + _verifyCallResult(success, resultData); + txCount++; + } + if (rateUpdates.length != 0) { callDatas[txCount] = abi.encodeWithSelector(IRiskSteward.updateRates.selector, rateUpdates); (bool success, bytes memory resultData) = address(STEWARD).call(callDatas[txCount]); From 1f61c0ac7dc375cb936a113523a0ed3cc2eea138 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Tue, 25 Mar 2025 21:16:02 +0530 Subject: [PATCH 05/25] fix: use pool instead of addresses provider --- scripts/deploy/DeployCapInjector.s.sol | 6 ++--- scripts/deploy/DeployRateInjector.s.sol | 6 ++--- scripts/deploy/DeployStewards.s.sol | 34 ++++++++++++------------- src/contracts/EdgeRiskStewardCaps.sol | 6 ++--- src/contracts/EdgeRiskStewardRates.sol | 6 ++--- src/contracts/RiskSteward.sol | 19 +++++++------- src/interfaces/IRiskSteward.sol | 6 ++--- tests/AaveStewardsInjectorCaps.t.sol | 2 +- tests/AaveStewardsInjectorRates.t.sol | 2 +- tests/EdgeRiskStewardCaps.t.sol | 2 +- tests/EdgeRiskStewardRates.t.sol | 2 +- tests/RiskSteward.t.sol | 4 +-- tests/RiskStewardCapo.t.sol | 2 +- 13 files changed, 48 insertions(+), 49 deletions(-) diff --git a/scripts/deploy/DeployCapInjector.s.sol b/scripts/deploy/DeployCapInjector.s.sol index 94a1b5e..8f347ba 100644 --- a/scripts/deploy/DeployCapInjector.s.sol +++ b/scripts/deploy/DeployCapInjector.s.sol @@ -13,14 +13,14 @@ library DeployStewardContracts { address constant EDGE_RISK_ORACLE = 0x861eeAdB55E41f161F31Acb1BFD4c70E3a964Aed; function _deployRiskStewards( - address poolAddressesProvider, + address pool, address configEngine, address riskCouncil, address governance ) internal returns (address) { address riskSteward = address( new EdgeRiskStewardCaps( - poolAddressesProvider, + pool, configEngine, riskCouncil, governance, @@ -92,7 +92,7 @@ contract DeployArbitrum is ArbitrumScript { .predictAddress(msg.sender, salt); address riskSteward = DeployStewardContracts._deployRiskStewards( - address(AaveV3Arbitrum.POOL_ADDRESSES_PROVIDER), + address(AaveV3Arbitrum.POOL), AaveV3Arbitrum.CONFIG_ENGINE, predictedStewardsInjector, GovernanceV3Arbitrum.EXECUTOR_LVL_1 diff --git a/scripts/deploy/DeployRateInjector.s.sol b/scripts/deploy/DeployRateInjector.s.sol index 9262049..1681364 100644 --- a/scripts/deploy/DeployRateInjector.s.sol +++ b/scripts/deploy/DeployRateInjector.s.sol @@ -13,14 +13,14 @@ library DeployStewardContracts { address constant EDGE_RISK_ORACLE = 0x7ABB46C690C52E919687D19ebF89C81A6136C1F2; function _deployRiskStewards( - address poolDataProvider, + address pool, address configEngine, address riskCouncil, address governance ) internal returns (address) { address riskSteward = address( new EdgeRiskStewardRates( - poolDataProvider, + pool, configEngine, riskCouncil, governance, @@ -90,7 +90,7 @@ contract DeployEthereumLido is EthereumScript { .predictAddress(msg.sender, salt); address riskSteward = DeployStewardContracts._deployRiskStewards( - address(AaveV3EthereumLido.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3EthereumLido.POOL), AaveV3EthereumLido.CONFIG_ENGINE, predictedStewardsInjector, GovernanceV3Ethereum.EXECUTOR_LVL_1 diff --git a/scripts/deploy/DeployStewards.s.sol b/scripts/deploy/DeployStewards.s.sol index 3ac8c1a..3cf3a65 100644 --- a/scripts/deploy/DeployStewards.s.sol +++ b/scripts/deploy/DeployStewards.s.sol @@ -34,14 +34,14 @@ import {RiskSteward, IRiskSteward} from '../../src/contracts/RiskSteward.sol'; library DeployRiskStewards { function _deployRiskStewards( - address addressesProvider, + address pool, address configEngine, address riskCouncil, address governance ) internal returns (address) { address riskSteward = address( new RiskSteward( - addressesProvider, + pool, configEngine, riskCouncil, governance, @@ -88,7 +88,7 @@ contract DeployEthereum is EthereumScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Ethereum.POOL_ADDRESSES_PROVIDER), + address(AaveV3Ethereum.POOL), AaveV3Ethereum.CONFIG_ENGINE, 0x47c71dFEB55Ebaa431Ae3fbF99Ea50e0D3d30fA8, // eth-risk-council GovernanceV3Ethereum.EXECUTOR_LVL_1 @@ -102,7 +102,7 @@ contract DeployEthereumLido is EthereumScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3EthereumLido.POOL_ADDRESSES_PROVIDER), + address(AaveV3EthereumLido.POOL), AaveV3EthereumLido.CONFIG_ENGINE, 0x47c71dFEB55Ebaa431Ae3fbF99Ea50e0D3d30fA8, // eth-risk-council GovernanceV3Ethereum.EXECUTOR_LVL_1 @@ -116,7 +116,7 @@ contract DeployEthereumEtherFi is EthereumScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3EthereumEtherFi.POOL_ADDRESSES_PROVIDER), + address(AaveV3EthereumEtherFi.POOL), AaveV3EthereumEtherFi.CONFIG_ENGINE, 0x47c71dFEB55Ebaa431Ae3fbF99Ea50e0D3d30fA8, // eth-risk-council GovernanceV3Ethereum.EXECUTOR_LVL_1 @@ -130,7 +130,7 @@ contract DeployPolygon is PolygonScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Polygon.POOL_ADDRESSES_PROVIDER), + address(AaveV3Polygon.POOL), AaveV3Polygon.CONFIG_ENGINE, 0x2C40FB1ACe63084fc0bB95F83C31B5854C6C4cB5, // pol-risk-council GovernanceV3Polygon.EXECUTOR_LVL_1 @@ -144,7 +144,7 @@ contract DeployArbitrum is ArbitrumScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Arbitrum.POOL_ADDRESSES_PROVIDER), + address(AaveV3Arbitrum.POOL), AaveV3Arbitrum.CONFIG_ENGINE, 0x3Be327F22eB4BD8042e6944073b8826dCf357Aa2, // arb-risk-council GovernanceV3Arbitrum.EXECUTOR_LVL_1 @@ -158,7 +158,7 @@ contract DeployOptimism is OptimismScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Optimism.POOL_ADDRESSES_PROVIDER), + address(AaveV3Optimism.POOL), AaveV3Optimism.CONFIG_ENGINE, 0xCb86256A994f0c505c5e15c75BF85fdFEa0F2a56, // opt-risk-council GovernanceV3Optimism.EXECUTOR_LVL_1 @@ -172,7 +172,7 @@ contract DeployAvalanche is AvalancheScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Avalanche.POOL_ADDRESSES_PROVIDER), + address(AaveV3Avalanche.POOL), AaveV3Avalanche.CONFIG_ENGINE, 0xCa66149425E7DC8f81276F6D80C4b486B9503D1a, // ava-risk-council GovernanceV3Avalanche.EXECUTOR_LVL_1 @@ -186,7 +186,7 @@ contract DeployScroll is ScrollScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Scroll.POOL_ADDRESSES_PROVIDER), + address(AaveV3Scroll.POOL), AaveV3Scroll.CONFIG_ENGINE, 0x611439a74546888c3535B4dd119A5Cbb9f5332EA, // scroll-risk-council GovernanceV3Scroll.EXECUTOR_LVL_1 @@ -200,7 +200,7 @@ contract DeployGnosis is GnosisScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Gnosis.POOL_ADDRESSES_PROVIDER), + address(AaveV3Gnosis.POOL), AaveV3Gnosis.CONFIG_ENGINE, 0xF221B08dD10e0C68D74F035764931Baa3b030481, // gnosis-risk-council GovernanceV3Gnosis.EXECUTOR_LVL_1 @@ -214,7 +214,7 @@ contract DeployBNB is BNBScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3BNB.POOL_ADDRESSES_PROVIDER), + address(AaveV3BNB.POOL), AaveV3BNB.CONFIG_ENGINE, 0x126dc589cc75f17385dD95516F3F1788d862E7bc, // bnb-risk-council GovernanceV3BNB.EXECUTOR_LVL_1 @@ -228,7 +228,7 @@ contract DeployBase is BaseScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Base.POOL_ADDRESSES_PROVIDER), + address(AaveV3Base.POOL), AaveV3Base.CONFIG_ENGINE, 0xfbeB4AcB31340bA4de9C87B11dfBf7e2bc8C0bF1, // base-risk-council GovernanceV3Base.EXECUTOR_LVL_1 @@ -242,7 +242,7 @@ contract DeployMetis is MetisScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Metis.POOL_ADDRESSES_PROVIDER), + address(AaveV3Metis.POOL), AaveV3Metis.CONFIG_ENGINE, 0x0f547846920C34E70FBE4F3d87E46452a3FeAFfa, // metis-risk-council GovernanceV3Metis.EXECUTOR_LVL_1 @@ -256,7 +256,7 @@ contract DeployLinea is LineaScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Linea.POOL_ADDRESSES_PROVIDER), + address(AaveV3Linea.POOL), AaveV3Linea.CONFIG_ENGINE, 0xF092A5aC5E284E7c433dAFE5b8B138bFcA53a4Ee, // linea-risk-council GovernanceV3Linea.EXECUTOR_LVL_1 @@ -270,7 +270,7 @@ contract DeploySonic is SonicScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Sonic.POOL_ADDRESSES_PROVIDER), + address(AaveV3Sonic.POOL), AaveV3Sonic.CONFIG_ENGINE, 0x1dE39A17a9Fa8c76899fff37488482EEb7835d04, // sonic-risk-council GovernanceV3Sonic.EXECUTOR_LVL_1 @@ -284,7 +284,7 @@ contract DeployCelo is SonicScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Celo.POOL_ADDRESSES_PROVIDER), + address(AaveV3Celo.POOL), AaveV3Celo.CONFIG_ENGINE, 0xd85786B5FC61E2A0c0a3144a33A0fC70646a99f6, // celo-risk-council GovernanceV3Celo.EXECUTOR_LVL_1 diff --git a/src/contracts/EdgeRiskStewardCaps.sol b/src/contracts/EdgeRiskStewardCaps.sol index 4f9156a..d3fc159 100644 --- a/src/contracts/EdgeRiskStewardCaps.sol +++ b/src/contracts/EdgeRiskStewardCaps.sol @@ -11,19 +11,19 @@ import './RiskSteward.sol'; */ contract EdgeRiskStewardCaps is RiskSteward { /** - * @param poolAddressesProvider The pool addresses provider of the pool to be controlled by the steward + * @param pool the aave pool to be controlled by the steward * @param engine the config engine to be used by the steward * @param riskCouncil the safe address of the council being able to interact with the steward * @param owner the owner of the risk steward being able to set configs and mark items as restricted * @param riskConfig the risk configuration to setup for each individual risk param */ constructor( - address poolAddressesProvider, + address pool, address engine, address riskCouncil, address owner, Config memory riskConfig - ) RiskSteward(poolAddressesProvider, engine, riskCouncil, owner, riskConfig) {} + ) RiskSteward(pool, engine, riskCouncil, owner, riskConfig) {} /// @inheritdoc IRiskSteward function updateRates( diff --git a/src/contracts/EdgeRiskStewardRates.sol b/src/contracts/EdgeRiskStewardRates.sol index c80cb0d..edb89a6 100644 --- a/src/contracts/EdgeRiskStewardRates.sol +++ b/src/contracts/EdgeRiskStewardRates.sol @@ -11,19 +11,19 @@ import './RiskSteward.sol'; */ contract EdgeRiskStewardRates is RiskSteward { /** - * @param poolAddressesProvider The pool addresses provider of the pool to be controlled by the steward + * @param pool the aave pool to be controlled by the steward * @param engine the config engine to be used by the steward * @param riskCouncil the safe address of the council being able to interact with the steward * @param owner the owner of the risk steward being able to set configs and mark items as restricted * @param riskConfig the risk configuration to setup for each individual risk param */ constructor( - address poolAddressesProvider, + address pool, address engine, address riskCouncil, address owner, Config memory riskConfig - ) RiskSteward(poolAddressesProvider, engine, riskCouncil, owner, riskConfig) {} + ) RiskSteward(pool, engine, riskCouncil, owner, riskConfig) {} /// @inheritdoc IRiskSteward function updateCaps(IEngine.CapsUpdate[] calldata) external virtual override onlyRiskCouncil { diff --git a/src/contracts/RiskSteward.sol b/src/contracts/RiskSteward.sol index d088048..5957727 100644 --- a/src/contracts/RiskSteward.sol +++ b/src/contracts/RiskSteward.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import {ReserveConfiguration, DataTypes} from 'aave-v3-origin/src/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; -import {IPool, IPoolAddressesProvider} from 'aave-address-book/AaveV3.sol'; +import {IPool} from 'aave-address-book/AaveV3.sol'; import {Address} from 'openzeppelin-contracts/contracts/utils/Address.sol'; import {SafeCast} from 'openzeppelin-contracts/contracts/utils/math/SafeCast.sol'; import {EngineFlags} from 'aave-v3-origin/src/contracts/extensions/v3-config-engine/EngineFlags.sol'; @@ -29,7 +29,7 @@ contract RiskSteward is Ownable, IRiskSteward { IEngine public immutable CONFIG_ENGINE; /// @inheritdoc IRiskSteward - IPoolAddressesProvider public immutable ADDRESSES_PROVIDER; + IPool public immutable POOL; /// @inheritdoc IRiskSteward address public immutable RISK_COUNCIL; @@ -53,20 +53,20 @@ contract RiskSteward is Ownable, IRiskSteward { } /** - * @param poolAddressesProvider The pool addresses provider of the pool to be controlled by the steward + * @param pool The aave pool to be controlled by the steward * @param engine the config engine to be used by the steward * @param riskCouncil the safe address of the council being able to interact with the steward * @param owner the owner of the risk steward being able to set configs and mark items as restricted * @param riskConfig the risk configuration to setup for each individual risk param */ constructor( - address poolAddressesProvider, + address pool, address engine, address riskCouncil, address owner, Config memory riskConfig ) Ownable(owner) { - ADDRESSES_PROVIDER = IPoolAddressesProvider(poolAddressesProvider); + POOL = IPool(pool); CONFIG_ENGINE = IEngine(engine); RISK_COUNCIL = riskCouncil; _riskConfig = riskConfig; @@ -175,7 +175,7 @@ contract RiskSteward is Ownable, IRiskSteward { if (capsUpdate[i].supplyCap == 0 || capsUpdate[i].borrowCap == 0) revert InvalidUpdateToZero(); - (uint256 currentBorrowCap, uint256 currentSupplyCap) = IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getCaps(); + (uint256 currentBorrowCap, uint256 currentSupplyCap) = POOL.getConfiguration(asset).getCaps(); _validateParamUpdate( ParamUpdateValidationInput({ @@ -277,8 +277,7 @@ contract RiskSteward is Ownable, IRiskSteward { collateralUpdates[i].debtCeiling == 0 ) revert InvalidUpdateToZero(); - DataTypes.ReserveConfigurationMap memory configuration = IPool(ADDRESSES_PROVIDER.getPool()) - .getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory configuration = POOL.getConfiguration(asset); ( uint256 currentLtv, uint256 currentLiquidationThreshold, @@ -345,7 +344,7 @@ contract RiskSteward is Ownable, IRiskSteward { eModeCategoryUpdates[i].liqBonus == 0 ) revert InvalidUpdateToZero(); - DataTypes.CollateralConfig memory currentEmodeConfig = IPool(ADDRESSES_PROVIDER.getPool()).getEModeCategoryCollateralConfig(eModeId); + DataTypes.CollateralConfig memory currentEmodeConfig = POOL.getEModeCategoryCollateralConfig(eModeId); _validateParamUpdate( ParamUpdateValidationInput({ @@ -622,7 +621,7 @@ contract RiskSteward is Ownable, IRiskSteward { uint256 variableRateSlope2 ) { - address rateStrategyAddress = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData(asset).interestRateStrategyAddress; + address rateStrategyAddress = POOL.getReserveData(asset).interestRateStrategyAddress; IDefaultInterestRateStrategyV2.InterestRateData memory interestRateData = IDefaultInterestRateStrategyV2(rateStrategyAddress) .getInterestRateDataBps(asset); diff --git a/src/interfaces/IRiskSteward.sol b/src/interfaces/IRiskSteward.sol index af4d061..04d28e9 100644 --- a/src/interfaces/IRiskSteward.sol +++ b/src/interfaces/IRiskSteward.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {IPoolDataProvider, IPoolAddressesProvider} from 'aave-address-book/AaveV3.sol'; +import {IPool} from 'aave-address-book/AaveV3.sol'; import {IAaveV3ConfigEngine as IEngine} from 'aave-v3-origin/src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol'; import {IPriceCapAdapter} from 'aave-capo/interfaces/IPriceCapAdapter.sol'; @@ -208,9 +208,9 @@ interface IRiskSteward { function CONFIG_ENGINE() external view returns (IEngine); /** - * @notice The aave addresses provider of the instance steward controls + * @notice The aave pool of the instance steward controls */ - function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); + function POOL() external view returns (IPool); /** * @notice The safe controlling the steward diff --git a/tests/AaveStewardsInjectorCaps.t.sol b/tests/AaveStewardsInjectorCaps.t.sol index 1b11cfa..6ec912e 100644 --- a/tests/AaveStewardsInjectorCaps.t.sol +++ b/tests/AaveStewardsInjectorCaps.t.sol @@ -50,7 +50,7 @@ contract AaveStewardsInjectorCaps_Test is AaveStewardsInjectorBaseTest { // setup risk steward _riskSteward = new RiskSteward( - address(contracts.poolAddressesProvider), + address(contracts.poolProxy), report.configEngine, address(_stewardInjector), address(this), diff --git a/tests/AaveStewardsInjectorRates.t.sol b/tests/AaveStewardsInjectorRates.t.sol index a836a18..e935e7e 100644 --- a/tests/AaveStewardsInjectorRates.t.sol +++ b/tests/AaveStewardsInjectorRates.t.sol @@ -45,7 +45,7 @@ contract AaveStewardsInjectorRates_Test is AaveStewardsInjectorBaseTest { // setup risk steward _riskSteward = new RiskSteward( - address(contracts.poolAddressesProvider), + address(contracts.poolProxy), report.configEngine, address(_stewardInjector), address(this), diff --git a/tests/EdgeRiskStewardCaps.t.sol b/tests/EdgeRiskStewardCaps.t.sol index 8df5fed..b6a8e9f 100644 --- a/tests/EdgeRiskStewardCaps.t.sol +++ b/tests/EdgeRiskStewardCaps.t.sol @@ -10,7 +10,7 @@ contract EdgeRiskStewardCaps_Test is RiskSteward_Test { super.setUp(); steward = new EdgeRiskStewardCaps( - address(AaveV3Ethereum.POOL_ADDRESSES_PROVIDER), + address(AaveV3Ethereum.POOL), AaveV3Ethereum.CONFIG_ENGINE, riskCouncil, GovernanceV3Ethereum.EXECUTOR_LVL_1, diff --git a/tests/EdgeRiskStewardRates.t.sol b/tests/EdgeRiskStewardRates.t.sol index 235e967..6f231ea 100644 --- a/tests/EdgeRiskStewardRates.t.sol +++ b/tests/EdgeRiskStewardRates.t.sol @@ -10,7 +10,7 @@ contract EdgeRiskStewardRates_Test is RiskSteward_Test { super.setUp(); steward = new EdgeRiskStewardRates( - address(AaveV3Ethereum.POOL_ADDRESSES_PROVIDER), + address(AaveV3Ethereum.POOL), AaveV3Ethereum.CONFIG_ENGINE, riskCouncil, GovernanceV3Ethereum.EXECUTOR_LVL_1, diff --git a/tests/RiskSteward.t.sol b/tests/RiskSteward.t.sol index 14e457e..e449623 100644 --- a/tests/RiskSteward.t.sol +++ b/tests/RiskSteward.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; import {ReserveConfiguration, DataTypes} from 'aave-v3-origin/src/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; -import {IACLManager, IPoolConfigurator, IPoolDataProvider} from 'aave-address-book/AaveV3.sol'; +import {IACLManager, IPoolConfigurator} from 'aave-address-book/AaveV3.sol'; import {IDefaultInterestRateStrategyV2} from 'aave-v3-origin/src/contracts/interfaces/IDefaultInterestRateStrategyV2.sol'; import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; @@ -27,7 +27,7 @@ contract RiskSteward_Test is Test { riskConfig = DeployRiskStewards._getRiskConfig(); steward = new RiskSteward( - address(AaveV3Ethereum.POOL_ADDRESSES_PROVIDER), + address(AaveV3Ethereum.POOL), AaveV3Ethereum.CONFIG_ENGINE, riskCouncil, GovernanceV3Ethereum.EXECUTOR_LVL_1, diff --git a/tests/RiskStewardCapo.t.sol b/tests/RiskStewardCapo.t.sol index 1499dca..47b69a0 100644 --- a/tests/RiskStewardCapo.t.sol +++ b/tests/RiskStewardCapo.t.sol @@ -37,7 +37,7 @@ contract RiskSteward_Capo_Test is Test { riskConfig.priceCapConfig.priceCapStable = defaultRiskParamConfig; steward = new RiskSteward( - address(AaveV3Ethereum.POOL_ADDRESSES_PROVIDER), + address(AaveV3Ethereum.POOL), AaveV3Ethereum.CONFIG_ENGINE, riskCouncil, GovernanceV3Ethereum.EXECUTOR_LVL_1, From 844132308b479b911545b9b2f56dcf26f7d4b7f6 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Fri, 28 Mar 2025 13:20:55 +0530 Subject: [PATCH 06/25] feat: add pendle price cap --- lib/aave-capo | 2 +- scripts/deploy/DeployCapInjector.s.sol | 3 +- scripts/deploy/DeployRateInjector.s.sol | 3 +- scripts/deploy/DeployStewards.s.sol | 3 +- src/contracts/RiskSteward.sol | 53 +++++++++++++++++++++++++ src/interfaces/IRiskSteward.sol | 17 ++++++++ tests/RiskSteward.t.sol | 27 +++++++------ 7 files changed, 91 insertions(+), 17 deletions(-) diff --git a/lib/aave-capo b/lib/aave-capo index f3c3d7b..ba51d1a 160000 --- a/lib/aave-capo +++ b/lib/aave-capo @@ -1 +1 @@ -Subproject commit f3c3d7b0806b4896d5211fa2ea376e1dba806d6f +Subproject commit ba51d1a668035a90ff8b9e90f54d3bdddc0dbdfb diff --git a/scripts/deploy/DeployCapInjector.s.sol b/scripts/deploy/DeployCapInjector.s.sol index 8f347ba..e7f85fb 100644 --- a/scripts/deploy/DeployCapInjector.s.sol +++ b/scripts/deploy/DeployCapInjector.s.sol @@ -75,7 +75,8 @@ library DeployStewardContracts { }), priceCapConfig: IRiskSteward.PriceCapConfig({ priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 5_00}), - priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}) + priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), + priceCapPendle: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00}) }) }); } diff --git a/scripts/deploy/DeployRateInjector.s.sol b/scripts/deploy/DeployRateInjector.s.sol index 1681364..7467ec8 100644 --- a/scripts/deploy/DeployRateInjector.s.sol +++ b/scripts/deploy/DeployRateInjector.s.sol @@ -73,7 +73,8 @@ library DeployStewardContracts { }), priceCapConfig: IRiskSteward.PriceCapConfig({ priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 5_00}), - priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}) + priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}), + priceCapPendle: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 20_00}) }) }); } diff --git a/scripts/deploy/DeployStewards.s.sol b/scripts/deploy/DeployStewards.s.sol index 3cf3a65..a956ff3 100644 --- a/scripts/deploy/DeployStewards.s.sol +++ b/scripts/deploy/DeployStewards.s.sol @@ -77,7 +77,8 @@ library DeployRiskStewards { }), priceCapConfig: IRiskSteward.PriceCapConfig({ priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 5_00}), - priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}) + priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), + priceCapPendle: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00}) }) }); } diff --git a/src/contracts/RiskSteward.sol b/src/contracts/RiskSteward.sol index 5957727..9e3eb0f 100644 --- a/src/contracts/RiskSteward.sol +++ b/src/contracts/RiskSteward.sol @@ -12,6 +12,7 @@ import {IRiskSteward} from '../interfaces/IRiskSteward.sol'; import {IDefaultInterestRateStrategyV2} from 'aave-v3-origin/src/contracts/interfaces/IDefaultInterestRateStrategyV2.sol'; import {IPriceCapAdapter} from 'aave-capo/interfaces/IPriceCapAdapter.sol'; import {IPriceCapAdapterStable} from 'aave-capo/interfaces/IPriceCapAdapterStable.sol'; +import {IPendlePriceCapAdapter} from 'aave-capo/interfaces/IPendlePriceCapAdapter.sol'; /** * @title RiskSteward @@ -118,6 +119,14 @@ contract RiskSteward is Ownable, IRiskSteward { _updateStablePriceCaps(priceCapUpdates); } + /// @inheritdoc IRiskSteward + function updatePendlePriceCaps( + PriceCapPendleUpdate[] calldata priceCapUpdates + ) external virtual onlyRiskCouncil { + _validatePendlePriceCapUpdate(priceCapUpdates); + _updatePendlePriceCaps(priceCapUpdates); + } + /// @inheritdoc IRiskSteward function getTimelock(address asset) external view returns (Debounce memory) { return _timelocks[bytes20(asset)]; @@ -444,6 +453,36 @@ contract RiskSteward is Ownable, IRiskSteward { } } + /** + * @notice method to validate the oracle pendle price caps update + * @param priceCapsUpdate list containing the new price cap values for the oracles + */ + function _validatePendlePriceCapUpdate( + PriceCapPendleUpdate[] calldata priceCapsUpdate + ) internal view { + if (priceCapsUpdate.length == 0) revert NoZeroUpdates(); + + for (uint256 i = 0; i < priceCapsUpdate.length; i++) { + address oracle = priceCapsUpdate[i].oracle; + + if (_restrictedAddresses[oracle]) revert OracleIsRestricted(); + if (priceCapsUpdate[i].discountRate == 0) revert InvalidUpdateToZero(); + + // get current rate + uint256 currentDiscount = IPendlePriceCapAdapter(oracle).discountRatePerYear(); + + _validateParamUpdate( + ParamUpdateValidationInput({ + currentValue: currentDiscount, + newValue: priceCapsUpdate[i].discountRate, + lastUpdated: _timelocks[bytes20(oracle)].priceCapLastUpdated, + riskConfig: _riskConfig.priceCapConfig.priceCapPendle, + isChangeRelative: true + }) + ); + } + } + /** * @notice method to validate the risk param update is within the allowed bound and the debounce is respected * @param validationParam struct containing values used for validation of the risk param update @@ -601,6 +640,20 @@ contract RiskSteward is Ownable, IRiskSteward { } } + /** + * @notice method to update the oracle pendle price caps update + * @param priceCapsUpdate list containing the new price cap values for the oracles + */ + function _updatePendlePriceCaps(PriceCapPendleUpdate[] calldata priceCapsUpdate) internal { + for (uint256 i = 0; i < priceCapsUpdate.length; i++) { + address oracle = priceCapsUpdate[i].oracle; + + _timelocks[bytes20(oracle)].priceCapLastUpdated = uint40(block.timestamp); + + IPendlePriceCapAdapter(oracle).setDiscountRatePerYear(priceCapsUpdate[i].discountRate.toUint64()); + } + } + /** * @notice method to fetch the current interest rate params of the asset * @param asset the address of the underlying asset diff --git a/src/interfaces/IRiskSteward.sol b/src/interfaces/IRiskSteward.sol index 04d28e9..1a371a7 100644 --- a/src/interfaces/IRiskSteward.sol +++ b/src/interfaces/IRiskSteward.sol @@ -184,6 +184,7 @@ interface IRiskSteward { struct PriceCapConfig { RiskParamConfig priceCapLst; RiskParamConfig priceCapStable; + RiskParamConfig priceCapPendle; } /** @@ -202,6 +203,14 @@ interface IRiskSteward { uint256 priceCap; } + /** + * @notice Struct used to update the pendle cap params + */ + struct PriceCapPendleUpdate { + address oracle; + uint256 discountRate; + } + /** * @notice The config engine used to perform the cap update via delegatecall */ @@ -265,6 +274,14 @@ interface IRiskSteward { */ function updateStablePriceCaps(PriceCapStableUpdate[] calldata priceCapUpdates) external; + /** + * @notice Allows updating pendle price cap params (i.e discount rate) across multiple oracles + * @dev A price cap update is only possible after minDelay has passed after last update + * @dev A price cap increase / decrease is only allowed by a magnitude of maxPercentChange + * @param priceCapUpdates struct containing new price cap params to be updated + */ + function updatePendlePriceCaps(PriceCapPendleUpdate[] calldata priceCapUpdates) external; + /** * @notice method to check if an asset/oracle is restricted to be used by the risk stewards * @param contractAddress address of the underlying asset or oracle diff --git a/tests/RiskSteward.t.sol b/tests/RiskSteward.t.sol index e449623..a9b1de9 100644 --- a/tests/RiskSteward.t.sol +++ b/tests/RiskSteward.t.sol @@ -12,7 +12,7 @@ import {IAaveV3ConfigEngine as IEngine} from 'aave-v3-origin/src/contracts/exten import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; import {ConfigEngineDeployer} from './utils/ConfigEngineDeployer.sol'; import {Ownable} from 'openzeppelin-contracts/contracts/access/Ownable.sol'; -import {DeployRiskStewards} from '../scripts/deploy/DeployStewards.s.sol'; +// import {DeployRiskStewards} from '../scripts/deploy/DeployStewards.s.sol'; contract RiskSteward_Test is Test { using ReserveConfiguration for DataTypes.ReserveConfigurationMap; @@ -22,20 +22,20 @@ contract RiskSteward_Test is Test { IRiskSteward.Config public riskConfig; function setUp() public virtual { - vm.createSelectFork(vm.rpcUrl('mainnet'), 21974363); + // vm.createSelectFork(vm.rpcUrl('mainnet'), 21974363); - riskConfig = DeployRiskStewards._getRiskConfig(); + // riskConfig = DeployRiskStewards._getRiskConfig(); - steward = new RiskSteward( - address(AaveV3Ethereum.POOL), - AaveV3Ethereum.CONFIG_ENGINE, - riskCouncil, - GovernanceV3Ethereum.EXECUTOR_LVL_1, - riskConfig - ); + // steward = new RiskSteward( + // address(AaveV3Ethereum.POOL), + // AaveV3Ethereum.CONFIG_ENGINE, + // riskCouncil, + // GovernanceV3Ethereum.EXECUTOR_LVL_1, + // riskConfig + // ); - vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); - AaveV3Ethereum.ACL_MANAGER.addRiskAdmin(address(steward)); + // vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); + // AaveV3Ethereum.ACL_MANAGER.addRiskAdmin(address(steward)); } /* ----------------------------- Caps Tests ----------------------------- */ @@ -1260,7 +1260,8 @@ contract RiskSteward_Test is Test { }), priceCapConfig: IRiskSteward.PriceCapConfig({ priceCapLst: newRiskParamConfig, - priceCapStable: newRiskParamConfig + priceCapStable: newRiskParamConfig, + priceCapPendle: newRiskParamConfig }) }); From 4066cbcabaab99aac92a214fc710b0ed4250c080 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Fri, 28 Mar 2025 15:31:53 +0530 Subject: [PATCH 07/25] fix: test --- tests/RiskSteward.t.sol | 24 ++++++++++++------------ tests/RiskStewardCapo.t.sol | 1 + 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/tests/RiskSteward.t.sol b/tests/RiskSteward.t.sol index a9b1de9..eba13aa 100644 --- a/tests/RiskSteward.t.sol +++ b/tests/RiskSteward.t.sol @@ -12,7 +12,7 @@ import {IAaveV3ConfigEngine as IEngine} from 'aave-v3-origin/src/contracts/exten import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; import {ConfigEngineDeployer} from './utils/ConfigEngineDeployer.sol'; import {Ownable} from 'openzeppelin-contracts/contracts/access/Ownable.sol'; -// import {DeployRiskStewards} from '../scripts/deploy/DeployStewards.s.sol'; +import {DeployRiskStewards} from '../scripts/deploy/DeployStewards.s.sol'; contract RiskSteward_Test is Test { using ReserveConfiguration for DataTypes.ReserveConfigurationMap; @@ -22,20 +22,20 @@ contract RiskSteward_Test is Test { IRiskSteward.Config public riskConfig; function setUp() public virtual { - // vm.createSelectFork(vm.rpcUrl('mainnet'), 21974363); + vm.createSelectFork(vm.rpcUrl('mainnet'), 21974363); - // riskConfig = DeployRiskStewards._getRiskConfig(); + riskConfig = DeployRiskStewards._getRiskConfig(); - // steward = new RiskSteward( - // address(AaveV3Ethereum.POOL), - // AaveV3Ethereum.CONFIG_ENGINE, - // riskCouncil, - // GovernanceV3Ethereum.EXECUTOR_LVL_1, - // riskConfig - // ); + steward = new RiskSteward( + address(AaveV3Ethereum.POOL), + AaveV3Ethereum.CONFIG_ENGINE, + riskCouncil, + GovernanceV3Ethereum.EXECUTOR_LVL_1, + riskConfig + ); - // vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); - // AaveV3Ethereum.ACL_MANAGER.addRiskAdmin(address(steward)); + vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); + AaveV3Ethereum.ACL_MANAGER.addRiskAdmin(address(steward)); } /* ----------------------------- Caps Tests ----------------------------- */ diff --git a/tests/RiskStewardCapo.t.sol b/tests/RiskStewardCapo.t.sol index 47b69a0..782aa67 100644 --- a/tests/RiskStewardCapo.t.sol +++ b/tests/RiskStewardCapo.t.sol @@ -35,6 +35,7 @@ contract RiskSteward_Capo_Test is Test { IRiskSteward.Config memory riskConfig; riskConfig.priceCapConfig.priceCapLst = defaultRiskParamConfig; riskConfig.priceCapConfig.priceCapStable = defaultRiskParamConfig; + riskConfig.priceCapConfig.priceCapPendle = defaultRiskParamConfig; steward = new RiskSteward( address(AaveV3Ethereum.POOL), From 5737c57ae61ba02fbf3da71dd6949da6945ddeed Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Fri, 28 Mar 2025 16:28:20 +0530 Subject: [PATCH 08/25] test: pendle price cap --- tests/RiskStewardCapo.t.sol | 167 +++++++++++++++++++++++++++++++++++- 1 file changed, 166 insertions(+), 1 deletion(-) diff --git a/tests/RiskStewardCapo.t.sol b/tests/RiskStewardCapo.t.sol index 782aa67..6409072 100644 --- a/tests/RiskStewardCapo.t.sol +++ b/tests/RiskStewardCapo.t.sol @@ -12,6 +12,7 @@ import {ConfigEngineDeployer} from './utils/ConfigEngineDeployer.sol'; import {IPriceCapAdapter} from 'aave-capo/interfaces/IPriceCapAdapter.sol'; import {IPriceCapAdapterStable, IChainlinkAggregator} from 'aave-capo/interfaces/IPriceCapAdapterStable.sol'; import {PriceCapAdapterStable} from 'aave-capo/contracts/PriceCapAdapterStable.sol'; +import {PendlePriceCapAdapter, IPendlePriceCapAdapter} from 'aave-capo/contracts/PendlePriceCapAdapter.sol'; import {SafeCast} from 'openzeppelin-contracts/contracts/utils/math/SafeCast.sol'; contract RiskSteward_Capo_Test is Test { @@ -19,6 +20,7 @@ contract RiskSteward_Capo_Test is Test { using SafeCast for int256; address public constant riskCouncil = address(42); + PendlePriceCapAdapter public pendleAdapter; RiskSteward public steward; uint104 currentRatio; uint48 delay; @@ -26,7 +28,7 @@ contract RiskSteward_Capo_Test is Test { event AddressRestricted(address indexed contractAddress, bool indexed isRestricted); function setUp() public { - vm.createSelectFork(vm.rpcUrl('mainnet'), 20934847); + vm.createSelectFork(vm.rpcUrl('mainnet'), 22144636); IRiskSteward.RiskParamConfig memory defaultRiskParamConfig = IRiskSteward.RiskParamConfig({ minDelay: 5 days, @@ -63,6 +65,15 @@ contract RiskSteward_Capo_Test is Test { }) ); vm.etch(AaveV3EthereumAssets.USDT_ORACLE, address(mockAdapter).code); + + pendleAdapter = new PendlePriceCapAdapter(IPendlePriceCapAdapter.PendlePriceCapAdapterParams({ + assetToUsdAggregator: 0x42bc86f2f08419280a99d8fbEa4672e7c30a86ec, // sUSDe capo + pendlePrincipalToken: 0xb7de5dFCb74d25c2f21841fbd6230355C50d9308, // sUSDe PT token + maxDiscountRatePerYear: 1e18, // 100% + discountRatePerYear: 0.1e18, // 10% + aclManager: address(AaveV3Ethereum.ACL_MANAGER), + description: 'sUSDe PT Adapter' + })); } /* ----------------------------- LST Price Cap Tests ----------------------------- */ @@ -541,4 +552,158 @@ contract RiskSteward_Capo_Test is Test { assertEq(priceCapBefore, priceCapAfter); } + + /* ----------------------------- Pendle PT Price Cap Tests ----------------------------- */ + + function test_updatePendlePriceCap() public { + uint256 currentDiscount = pendleAdapter.discountRatePerYear(); + + IRiskSteward.PriceCapPendleUpdate[] + memory priceCapUpdates = new IRiskSteward.PriceCapPendleUpdate[](1); + + priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + oracle: address(pendleAdapter), + discountRate: ((currentDiscount * 110) / 100) // +10% relative change + }); + + vm.startPrank(riskCouncil); + steward.updatePendlePriceCaps(priceCapUpdates); + + RiskSteward.Debounce memory lastUpdated = steward.getTimelock(address(pendleAdapter)); + + uint256 discountAfter = pendleAdapter.discountRatePerYear(); + + assertEq(discountAfter, priceCapUpdates[0].discountRate); + assertEq(lastUpdated.priceCapLastUpdated, block.timestamp); + + // after min time passed test collateral update decrease + vm.warp(block.timestamp + 5 days + 1); + currentDiscount = pendleAdapter.discountRatePerYear(); + + priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + oracle: address(pendleAdapter), + discountRate: ((currentDiscount * 90) / 100) // -10% relative change + }); + + steward.updatePendlePriceCaps(priceCapUpdates); + + lastUpdated = steward.getTimelock(address(pendleAdapter)); + + discountAfter = pendleAdapter.discountRatePerYear(); + + assertEq(discountAfter, priceCapUpdates[0].discountRate); + assertEq(lastUpdated.priceCapLastUpdated, block.timestamp); + } + + function test_updatePendlePriceCap_debounceNotRespected() public { + uint256 currentDiscount = pendleAdapter.discountRatePerYear(); + + IRiskSteward.PriceCapPendleUpdate[] + memory priceCapUpdates = new IRiskSteward.PriceCapPendleUpdate[](1); + + priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + oracle: address(pendleAdapter), + discountRate: ((currentDiscount * 110) / 100) // +10% relative change + }); + + vm.startPrank(riskCouncil); + steward.updatePendlePriceCaps(priceCapUpdates); + + priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + oracle: address(pendleAdapter), + discountRate: ((currentDiscount * 105) / 100) // +10% relative change + }); + + // expect revert as minimum time has not passed for next update + vm.expectRevert(IRiskSteward.DebounceNotRespected.selector); + steward.updatePendlePriceCaps(priceCapUpdates); + } + + function test_updatePendlePriceCap_outOfRange() public { + uint256 currentDiscount = pendleAdapter.discountRatePerYear(); + IRiskSteward.PriceCapPendleUpdate[] + memory priceCapUpdates = new IRiskSteward.PriceCapPendleUpdate[](1); + + priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + oracle: address(pendleAdapter), + discountRate: ((currentDiscount * 111) / 100) // +11% relative increase + }); + vm.startPrank(riskCouncil); + + // expect revert as price cap (discountRate) is out of range + vm.expectRevert(IRiskSteward.UpdateNotInRange.selector); + steward.updatePendlePriceCaps(priceCapUpdates); + + priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + oracle: address(pendleAdapter), + discountRate: ((currentDiscount * 89) / 100) // -11% relative decrease + }); + vm.expectRevert(IRiskSteward.UpdateNotInRange.selector); + steward.updatePendlePriceCaps(priceCapUpdates); + } + + function test_updatePendlePriceCap_keepCurrent_revert() public { + IRiskSteward.PriceCapPendleUpdate[] + memory priceCapUpdates = new IRiskSteward.PriceCapPendleUpdate[](1); + + priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + oracle: address(pendleAdapter), + discountRate: EngineFlags.KEEP_CURRENT + }); + vm.prank(riskCouncil); + + // expect revert as price cap is out of range + vm.expectRevert(); + steward.updatePendlePriceCaps(priceCapUpdates); + } + + function test_updatePendlePriceCap_toValueZeroNotAllowed() public { + IRiskSteward.PriceCapPendleUpdate[] + memory priceCapUpdates = new IRiskSteward.PriceCapPendleUpdate[](1); + + priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + oracle: address(pendleAdapter), + discountRate: 0 + }); + vm.prank(riskCouncil); + + // expect revert as price cap is out of range + vm.expectRevert(IRiskSteward.InvalidUpdateToZero.selector); + steward.updatePendlePriceCaps(priceCapUpdates); + } + + function test_updatePendlePriceCap_oracleRestricted() public { + vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); + steward.setAddressRestricted(address(pendleAdapter), true); + + uint256 currentDiscount = pendleAdapter.discountRatePerYear(); + IRiskSteward.PriceCapPendleUpdate[] + memory priceCapUpdates = new IRiskSteward.PriceCapPendleUpdate[](1); + + priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + oracle: address(pendleAdapter), + discountRate: ((currentDiscount * 110) / 100) // +10% relative change + }); + vm.prank(riskCouncil); + // expect revert as oracle is restricted + + vm.expectRevert(IRiskSteward.OracleIsRestricted.selector); + steward.updatePendlePriceCaps(priceCapUpdates); + } + + function test_updatePendlePriceCap_sameUpdates() public { + uint256 initialDiscount = pendleAdapter.discountRatePerYear(); + IRiskSteward.PriceCapPendleUpdate[] + memory priceCapUpdates = new IRiskSteward.PriceCapPendleUpdate[](1); + + priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + oracle: address(pendleAdapter), + discountRate: initialDiscount + }); + vm.prank(riskCouncil); + steward.updatePendlePriceCaps(priceCapUpdates); + + uint256 afterDiscount = pendleAdapter.discountRatePerYear(); + assertEq(initialDiscount, afterDiscount); + } } From b2cfdef37a86c983ee402060897068a6023b83ed Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Fri, 28 Mar 2025 16:30:35 +0530 Subject: [PATCH 09/25] fix: edge risk stewards --- src/contracts/EdgeRiskStewardCaps.sol | 7 +++++++ src/contracts/EdgeRiskStewardRates.sol | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/contracts/EdgeRiskStewardCaps.sol b/src/contracts/EdgeRiskStewardCaps.sol index d3fc159..9589c8d 100644 --- a/src/contracts/EdgeRiskStewardCaps.sol +++ b/src/contracts/EdgeRiskStewardCaps.sol @@ -59,4 +59,11 @@ contract EdgeRiskStewardCaps is RiskSteward { ) external virtual override onlyRiskCouncil { revert UpdateNotAllowed(); } + + /// @inheritdoc IRiskSteward + function updatePendlePriceCaps( + PriceCapPendleUpdate[] calldata + ) external virtual override onlyRiskCouncil { + revert UpdateNotAllowed(); + } } diff --git a/src/contracts/EdgeRiskStewardRates.sol b/src/contracts/EdgeRiskStewardRates.sol index edb89a6..5cc9406 100644 --- a/src/contracts/EdgeRiskStewardRates.sol +++ b/src/contracts/EdgeRiskStewardRates.sol @@ -57,4 +57,11 @@ contract EdgeRiskStewardRates is RiskSteward { ) external virtual override onlyRiskCouncil { revert UpdateNotAllowed(); } + + /// @inheritdoc IRiskSteward + function updatePendlePriceCaps( + PriceCapPendleUpdate[] calldata + ) external virtual override onlyRiskCouncil { + revert UpdateNotAllowed(); + } } From 1e1875816aeced63572ed81659d428eb0c9adf7b Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Fri, 28 Mar 2025 16:35:11 +0530 Subject: [PATCH 10/25] Update src/contracts/RiskSteward.sol --- src/contracts/RiskSteward.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contracts/RiskSteward.sol b/src/contracts/RiskSteward.sol index 9e3eb0f..65fc4af 100644 --- a/src/contracts/RiskSteward.sol +++ b/src/contracts/RiskSteward.sol @@ -454,7 +454,7 @@ contract RiskSteward is Ownable, IRiskSteward { } /** - * @notice method to validate the oracle pendle price caps update + * @notice method to validate the pendle oracle price caps update * @param priceCapsUpdate list containing the new price cap values for the oracles */ function _validatePendlePriceCapUpdate( From 18d9562984d38f62ae98b3eeef45931edc9dafa3 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Fri, 28 Mar 2025 16:47:37 +0530 Subject: [PATCH 11/25] Update src/contracts/RiskSteward.sol --- src/contracts/RiskSteward.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contracts/RiskSteward.sol b/src/contracts/RiskSteward.sol index 65fc4af..a8343d0 100644 --- a/src/contracts/RiskSteward.sol +++ b/src/contracts/RiskSteward.sol @@ -641,7 +641,7 @@ contract RiskSteward is Ownable, IRiskSteward { } /** - * @notice method to update the oracle pendle price caps update + * @notice method to update the pendle oracle price caps update * @param priceCapsUpdate list containing the new price cap values for the oracles */ function _updatePendlePriceCaps(PriceCapPendleUpdate[] calldata priceCapsUpdate) internal { From bad31366e0a139d299d9df082faee4f2a6f73aa9 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Fri, 28 Mar 2025 20:06:22 +0530 Subject: [PATCH 12/25] chore: fix ci --- .gitignore | 2 - package-lock.json | 7500 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 +- 3 files changed, 7502 insertions(+), 3 deletions(-) create mode 100644 package-lock.json diff --git a/.gitignore b/.gitignore index 26e143a..cf674aa 100644 --- a/.gitignore +++ b/.gitignore @@ -11,8 +11,6 @@ zkout/ .idea .vscode -# well, looks strange to ignore package-lock, but we have only pretter and it's temproray -package-lock.json node_modules # ignore foundry deploy artifacts diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..850a3d9 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,7500 @@ +{ + "name": "aave-v3-risk-stewards", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "aave-v3-risk-stewards", + "version": "1.0.0", + "license": "BUSL-1.1", + "devDependencies": { + "@bgd-labs/aave-address-book": "^4.16.1", + "@bgd-labs/aave-cli": "^1.1.12", + "@bgd-labs/js-utils": "^1.4.7", + "@ethersproject/hardware-wallets": "^5.7.0", + "@inquirer/prompts": "^3.3.0", + "@inquirer/testing": "^2.1.13", + "@safe-global/safe-core-sdk": "^3.3.3", + "@safe-global/safe-ethers-lib": "^1.9.3", + "@safe-global/safe-service-client": "^2.0.1", + "commander": "^12.1.0", + "dotenv": "^16.0.3", + "ethers": "5.7.2", + "husky": "^8.0.3", + "prettier": "2.8.7", + "prettier-plugin-solidity": "1.1.3", + "ts-node": "^10.9.1", + "tsx": "^4.16.3", + "typescript": "^5.0.4", + "viem": "^2.23.6", + "vitest": "^2.1.8" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.0.tgz", + "integrity": "sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==", + "dev": true + }, + "node_modules/@assemblyscript/loader": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.9.4.tgz", + "integrity": "sha512-HazVq9zwTVwGmqdwYzu7WyQ6FQVZ7SwET0KKQuKm55jD0IfUpZgN0OPIiZG3zV1iSrVYcN0bdwLRXI/VNCYsUA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@bgd-labs/aave-address-book": { + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/@bgd-labs/aave-address-book/-/aave-address-book-4.16.1.tgz", + "integrity": "sha512-h16HOtGhyI+7yF7BfpBwJpAwlUskH+jyJSvXxFrPfSiDO7K5CqZgmHzHlkM/SboTdIWLJYHktDpMqZ1Y9MSELw==", + "dev": true + }, + "node_modules/@bgd-labs/aave-cli": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@bgd-labs/aave-cli/-/aave-cli-1.1.12.tgz", + "integrity": "sha512-PuxWcdmNmNjVHP9hzZpJ6LYyM6MViJCQQ7U4yEPjiAGQ0mQ9aJIfAq5EpNds6r4OmmxufZ+Ely6f8QkIrDXDdA==", + "dev": true, + "dependencies": { + "@bgd-labs/aave-address-book": "^4.5.1", + "@bgd-labs/aave-v3-governance-cache": "^1.0.8", + "@bgd-labs/js-utils": "^1.4.6", + "@bgd-labs/rpc-env": "^2.1.1", + "@commander-js/extra-typings": "^12.1.0", + "@inquirer/prompts": "^7.1.0", + "blockstore-core": "^5.0.2", + "chalk": "^4.1.2", + "commander": "^12.1.0", + "deepmerge": "^4.3.1", + "dotenv": "^16.4.1", + "find-object-paths": "^1.1.0", + "gray-matter": "^4.0.3", + "ipfs-unixfs-importer": "^15.3.1", + "json-bigint": "^1.0.0", + "viem": "^2.21.48", + "zod": "^3.23.8" + }, + "bin": { + "aave-cli": "dist/cli.js" + } + }, + "node_modules/@bgd-labs/aave-cli/node_modules/@inquirer/checkbox": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.0.2.tgz", + "integrity": "sha512-+gznPl8ip8P8HYHYecDtUtdsh1t2jvb+sWCD72GAiZ9m45RqwrLmReDaqdC0umQfamtFXVRoMVJ2/qINKGm9Tg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@bgd-labs/aave-cli/node_modules/@inquirer/confirm": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.0.2.tgz", + "integrity": "sha512-KJLUHOaKnNCYzwVbryj3TNBxyZIrr56fR5N45v6K9IPrbT6B7DcudBMfylkV1A8PUdJE15mybkEQyp2/ZUpxUA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@bgd-labs/aave-cli/node_modules/@inquirer/core": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.0.tgz", + "integrity": "sha512-I+ETk2AL+yAVbvuKx5AJpQmoaWhpiTFOg/UJb7ZkMAK4blmtG8ATh5ct+T/8xNld0CZG/2UhtkdMwpgvld92XQ==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@bgd-labs/aave-cli/node_modules/@inquirer/editor": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.1.0.tgz", + "integrity": "sha512-K1gGWsxEqO23tVdp5MT3H799OZ4ER1za7Dlc8F4um0W7lwSv0KGR/YyrUEyimj0g7dXZd8XknM/5QA2/Uy+TbA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1", + "external-editor": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@bgd-labs/aave-cli/node_modules/@inquirer/expand": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.2.tgz", + "integrity": "sha512-WdgCX1cUtinz+syKyZdJomovULYlKUWZbVYZzhf+ZeeYf4htAQ3jLymoNs3koIAKfZZl3HUBb819ClCBfyznaw==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@bgd-labs/aave-cli/node_modules/@inquirer/input": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.0.2.tgz", + "integrity": "sha512-yCLCraigU085EcdpIVEDgyfGv4vBiE4I+k1qRkc9C5dMjWF42ADMGy1RFU94+eZlz4YlkmFsiyHZy0W1wdhaNg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@bgd-labs/aave-cli/node_modules/@inquirer/password": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.2.tgz", + "integrity": "sha512-tQXGSu7IO07gsYlGy3VgXRVsbOWqFBMbqAUrJSc1PDTQQ5Qdm+QVwkP0OC0jnUZ62D19iPgXOMO+tnWG+HhjNQ==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1", + "ansi-escapes": "^4.3.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@bgd-labs/aave-cli/node_modules/@inquirer/prompts": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.1.0.tgz", + "integrity": "sha512-5U/XiVRH2pp1X6gpNAjWOglMf38/Ys522ncEHIKT1voRUvSj/DQnR22OVxHnwu5S+rCFaUiPQ57JOtMFQayqYA==", + "dev": true, + "dependencies": { + "@inquirer/checkbox": "^4.0.2", + "@inquirer/confirm": "^5.0.2", + "@inquirer/editor": "^4.1.0", + "@inquirer/expand": "^4.0.2", + "@inquirer/input": "^4.0.2", + "@inquirer/number": "^3.0.2", + "@inquirer/password": "^4.0.2", + "@inquirer/rawlist": "^4.0.2", + "@inquirer/search": "^3.0.2", + "@inquirer/select": "^4.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@bgd-labs/aave-cli/node_modules/@inquirer/rawlist": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.0.2.tgz", + "integrity": "sha512-3XGcskMoVF8H0Dl1S5TSZ3rMPPBWXRcM0VeNVsS4ByWeWjSeb0lPqfnBg6N7T0608I1B2bSVnbi2cwCrmOD1Yw==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@bgd-labs/aave-cli/node_modules/@inquirer/select": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.0.2.tgz", + "integrity": "sha512-uSWUzaSYAEj0hlzxa1mUB6VqrKaYx0QxGBLZzU4xWFxaSyGaXxsSE4OSOwdU24j0xl8OajgayqFXW0l2bkl2kg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@bgd-labs/aave-cli/node_modules/@inquirer/type": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.1.tgz", + "integrity": "sha512-+ksJMIy92sOAiAccGpcKZUc3bYO07cADnscIxHBknEm3uNts3movSmBofc1908BNy5edKscxYeAdaX1NXkHS6A==", + "dev": true, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@bgd-labs/aave-cli/node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@bgd-labs/aave-v3-governance-cache": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@bgd-labs/aave-v3-governance-cache/-/aave-v3-governance-cache-1.0.8.tgz", + "integrity": "sha512-niaJafgxLQcuzZ13Wo1rO5tJ8f5pE5AdWs+5/PoHMrk5Z+bm5kE59oHbIO2xpg1pCQ7IZmsxXEIIlC2c0+v/Jg==", + "dev": true, + "peerDependencies": { + "@bgd-labs/aave-address-book": "^4.0.1-02c70ec5f8a433b38372b81d27ed44b79aa52f65.0", + "viem": "^2.9.20" + } + }, + "node_modules/@bgd-labs/js-utils": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@bgd-labs/js-utils/-/js-utils-1.4.7.tgz", + "integrity": "sha512-rv8VZkNQlt71LPqveo1o/LMilq6XRS3gTJeDaoDCUtzFpv16S9PqZe92uoYLatUhhSvBEXKMmjnOoW/WbMsdVQ==", + "dev": true, + "dependencies": { + "@bgd-labs/rpc-env": "^2.3.0", + "@supercharge/promise-pool": "^3.1.1", + "bs58": "^5.0.0", + "gray-matter": "^4.0.3", + "tsx": "^4.7.1" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "viem": "^2.0.3" + } + }, + "node_modules/@bgd-labs/rpc-env": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@bgd-labs/rpc-env/-/rpc-env-2.3.1.tgz", + "integrity": "sha512-jWygItqoHd+KC6f/O8NSN2/q0GFzvxDlEYJRLI693QkptfWu1TJkse2JCz8+f6IYGl0JksW9X0O8VY/5iBWZcQ==", + "dev": true, + "bin": { + "rpc-env": "dist/cli.js" + } + }, + "node_modules/@chainsafe/is-ip": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@chainsafe/is-ip/-/is-ip-2.0.2.tgz", + "integrity": "sha512-ndGqEMG1W5WkGagaqOZHpPU172AGdxr+LD15sv3WIUvT5oCFUrG1Y0CW/v2Egwj4JXEvSibaIIIqImsm98y1nA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@chainsafe/netmask": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@chainsafe/netmask/-/netmask-2.0.0.tgz", + "integrity": "sha512-I3Z+6SWUoaljh3TBzCnCxjlUyN8tA+NAk5L6m9IxvCf1BENQTePzPMis97CoN/iMW1St3WN+AWCCRp+TTBRiDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@chainsafe/is-ip": "^2.0.1" + } + }, + "node_modules/@commander-js/extra-typings": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@commander-js/extra-typings/-/extra-typings-12.1.0.tgz", + "integrity": "sha512-wf/lwQvWAA0goIghcb91dQYpkLBcyhOhQNqG/VgWhnKzgt+UOMvra7EX/2fv70arm5RW+PUHoQHHDa6/p77Eqg==", + "dev": true, + "peerDependencies": { + "commander": "~12.1.0" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.0.tgz", + "integrity": "sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.0.tgz", + "integrity": "sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "dev": true, + "license": "MPL-2.0", + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethersproject/abi": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0" + } + }, + "node_modules/@ethersproject/basex": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", + "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.7.0" + } + }, + "node_modules/@ethersproject/contracts": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", + "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0" + } + }, + "node_modules/@ethersproject/hardware-wallets": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hardware-wallets/-/hardware-wallets-5.7.0.tgz", + "integrity": "sha512-DjMMXIisRc8xFvEoLoYz1w7JDOYmaz/a0X9sp7Zu668RR8U1zCAyj5ow25HLRW+TCzEC5XiFetTXqS5kXonFCQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ledgerhq/hw-app-eth": "5.27.2", + "@ledgerhq/hw-transport": "5.26.0", + "@ledgerhq/hw-transport-u2f": "5.26.0", + "ethers": "^5.7.0" + }, + "optionalDependencies": { + "@ledgerhq/hw-transport-node-hid": "5.26.0" + } + }, + "node_modules/@ethersproject/hardware-wallets/node_modules/@ledgerhq/hw-transport": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-5.26.0.tgz", + "integrity": "sha512-NFeJOJmyEfAX8uuIBTpocWHcz630sqPcXbu864Q+OCBm4EK5UOKV1h/pX7e0xgNIKY8zhJ/O4p4cIZp9tnXLHQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@ledgerhq/devices": "^5.26.0", + "@ledgerhq/errors": "^5.26.0", + "events": "^3.2.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/hdnode": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", + "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", + "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/providers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/@ethersproject/providers/node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@ethersproject/random": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/sha2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", + "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/solidity": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" + } + }, + "node_modules/@ethersproject/units": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/wallet": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", + "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/wordlists": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", + "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-1.5.2.tgz", + "integrity": "sha512-CifrkgQjDkUkWexmgYYNyB5603HhTHI91vLFeQXh6qrTKiCMVASol01Rs1cv6LP/A2WccZSRlJKZhbaBIs/9ZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^6.0.0", + "@inquirer/type": "^1.1.6", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "figures": "^3.2.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/@inquirer/confirm": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-2.0.17.tgz", + "integrity": "sha512-EqzhGryzmGpy2aJf6LxJVhndxYmFs+m8cxXzf8nejb1DE3sabf6mUgBcp4J0jAUEiAcYzqmkqRr7LPFh/WdnXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^6.0.0", + "@inquirer/type": "^1.1.6", + "chalk": "^4.1.2" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/@inquirer/core": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-6.0.0.tgz", + "integrity": "sha512-fKi63Khkisgda3ohnskNf5uZJj+zXOaBvOllHsOkdsXRA/ubQLJQrZchFFi57NKbZzkTunXiBMdvWOv71alonw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/type": "^1.1.6", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.10.7", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "figures": "^3.2.0", + "mute-stream": "^1.0.0", + "run-async": "^3.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/@inquirer/core/node_modules/@types/node": { + "version": "20.14.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", + "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@inquirer/core/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@inquirer/editor": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-1.2.15.tgz", + "integrity": "sha512-gQ77Ls09x5vKLVNMH9q/7xvYPT6sIs5f7URksw+a2iJZ0j48tVS6crLqm2ugG33tgXHIwiEqkytY60Zyh5GkJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^6.0.0", + "@inquirer/type": "^1.1.6", + "chalk": "^4.1.2", + "external-editor": "^3.1.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/@inquirer/expand": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-1.1.16.tgz", + "integrity": "sha512-TGLU9egcuo+s7PxphKUCnJnpCIVY32/EwPCLLuu+gTvYiD8hZgx8Z2niNQD36sa6xcfpdLY6xXDBiL/+g1r2XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^6.0.0", + "@inquirer/type": "^1.1.6", + "chalk": "^4.1.2", + "figures": "^3.2.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.8.tgz", + "integrity": "sha512-tKd+jsmhq21AP1LhexC0pPwsCxEhGgAkg28byjJAd+xhmIs8LUX8JbUc3vBf3PhLxWiB5EvyBE5X7JSPAqMAqg==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "1.2.16", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-1.2.16.tgz", + "integrity": "sha512-Ou0LaSWvj1ni+egnyQ+NBtfM1885UwhRCMtsRt2bBO47DoC1dwtCa+ZUNgrxlnCHHF0IXsbQHYtIIjFGAavI4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^6.0.0", + "@inquirer/type": "^1.1.6", + "chalk": "^4.1.2" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.2.tgz", + "integrity": "sha512-MKQhYofdUNk7eqJtz52KvM1dH6R93OMrqHduXCvuefKrsiMjHiMwjc3NZw5Imm2nqY7gWd9xdhYrtcHMJQZUxA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/number/node_modules/@inquirer/core": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.0.tgz", + "integrity": "sha512-I+ETk2AL+yAVbvuKx5AJpQmoaWhpiTFOg/UJb7ZkMAK4blmtG8ATh5ct+T/8xNld0CZG/2UhtkdMwpgvld92XQ==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/number/node_modules/@inquirer/type": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.1.tgz", + "integrity": "sha512-+ksJMIy92sOAiAccGpcKZUc3bYO07cADnscIxHBknEm3uNts3movSmBofc1908BNy5edKscxYeAdaX1NXkHS6A==", + "dev": true, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/number/node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@inquirer/password": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-1.1.16.tgz", + "integrity": "sha512-aZYZVHLUXZ2gbBot+i+zOJrks1WaiI95lvZCn1sKfcw6MtSSlYC8uDX8sTzQvAsQ8epHoP84UNvAIT0KVGOGqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^6.0.0", + "@inquirer/type": "^1.1.6", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/@inquirer/prompts": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-3.3.2.tgz", + "integrity": "sha512-k52mOMRvTUejrqyF1h8Z07chC+sbaoaUYzzr1KrJXyj7yaX7Nrh0a9vktv8TuocRwIJOQMaj5oZEmkspEcJFYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^1.5.2", + "@inquirer/confirm": "^2.0.17", + "@inquirer/core": "^6.0.0", + "@inquirer/editor": "^1.2.15", + "@inquirer/expand": "^1.1.16", + "@inquirer/input": "^1.2.16", + "@inquirer/password": "^1.1.16", + "@inquirer/rawlist": "^1.2.16", + "@inquirer/select": "^1.3.3" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/@inquirer/rawlist": { + "version": "1.2.16", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-1.2.16.tgz", + "integrity": "sha512-pZ6TRg2qMwZAOZAV6TvghCtkr53dGnK29GMNQ3vMZXSNguvGqtOVc4j/h1T8kqGJFagjyfBZhUPGwNS55O5qPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^6.0.0", + "@inquirer/type": "^1.1.6", + "chalk": "^4.1.2" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/@inquirer/search": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.2.tgz", + "integrity": "sha512-Zv4FC7w4dJ13BOJfKRQCICQfShinGjb1bCEIHxTSnjj2telu3+3RHwHubPG9HyD4aix5s+lyAMEK/wSFD75HLA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/search/node_modules/@inquirer/core": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.0.tgz", + "integrity": "sha512-I+ETk2AL+yAVbvuKx5AJpQmoaWhpiTFOg/UJb7ZkMAK4blmtG8ATh5ct+T/8xNld0CZG/2UhtkdMwpgvld92XQ==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/search/node_modules/@inquirer/type": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.1.tgz", + "integrity": "sha512-+ksJMIy92sOAiAccGpcKZUc3bYO07cADnscIxHBknEm3uNts3movSmBofc1908BNy5edKscxYeAdaX1NXkHS6A==", + "dev": true, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/search/node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@inquirer/select": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-1.3.3.tgz", + "integrity": "sha512-RzlRISXWqIKEf83FDC9ZtJ3JvuK1l7aGpretf41BCWYrvla2wU8W8MTRNMiPrPJ+1SIqrRC1nZdZ60hD9hRXLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^6.0.0", + "@inquirer/type": "^1.1.6", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "figures": "^3.2.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/@inquirer/testing": { + "version": "2.1.31", + "resolved": "https://registry.npmjs.org/@inquirer/testing/-/testing-2.1.31.tgz", + "integrity": "sha512-Dab4avme+Q6lFGtbJkOW5e5SZpehrG6kCpTMzx7RcGDzpCIbGsjok+jVzhW5hd790i+EizMPS+7c+PaxQPTSgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/type": "^1.5.2", + "@types/mute-stream": "^0.0.4", + "@types/node": "^22.1.0", + "ansi-escapes": "^4.3.2", + "mute-stream": "^1.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/testing/node_modules/@types/node": { + "version": "22.5.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.1.tgz", + "integrity": "sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@inquirer/testing/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@inquirer/type": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.2.tgz", + "integrity": "sha512-w9qFkumYDCNyDZmNQjf/n6qQuvQ4dMC3BJesY4oF+yr0CxR5vxujflAVeIcS6U336uzi9GM0kAfZlLrZ9UTkpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ipld/dag-pb": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@ipld/dag-pb/-/dag-pb-4.1.3.tgz", + "integrity": "sha512-ueULCaaSCcD+dQga6nKiRr+RSeVgdiYiEPKVUu5iQMNYDN+9osd0KpR3UDd9uQQ+6RWuv9L34SchfEwj7YIbOA==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^13.1.0" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@ledgerhq/cryptoassets": { + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/cryptoassets/-/cryptoassets-5.53.0.tgz", + "integrity": "sha512-M3ibc3LRuHid5UtL7FI3IC6nMEppvly98QHFoSa7lJU0HDzQxY6zHec/SPM4uuJUC8sXoGVAiRJDkgny54damw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "invariant": "2" + } + }, + "node_modules/@ledgerhq/devices": { + "version": "5.51.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-5.51.1.tgz", + "integrity": "sha512-4w+P0VkbjzEXC7kv8T1GJ/9AVaP9I6uasMZ/JcdwZBS3qwvKo5A5z9uGhP5c7TvItzcmPb44b5Mw2kT+WjUuAA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@ledgerhq/errors": "^5.50.0", + "@ledgerhq/logs": "^5.50.0", + "rxjs": "6", + "semver": "^7.3.5" + } + }, + "node_modules/@ledgerhq/errors": { + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-5.50.0.tgz", + "integrity": "sha512-gu6aJ/BHuRlpU7kgVpy2vcYk6atjB4iauP2ymF7Gk0ez0Y/6VSMVSJvubeEQN+IV60+OBK0JgeIZG7OiHaw8ow==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@ledgerhq/hw-app-eth": { + "version": "5.27.2", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-app-eth/-/hw-app-eth-5.27.2.tgz", + "integrity": "sha512-llNdrE894cCN8j6yxJEUniciyLVcLmu5N0UmIJLOObztG+5rOF4bX54h4SreTWK+E10Z0CzHSeyE5Lz/tVcqqQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@ledgerhq/cryptoassets": "^5.27.2", + "@ledgerhq/errors": "^5.26.0", + "@ledgerhq/hw-transport": "^5.26.0", + "bignumber.js": "^9.0.1", + "rlp": "^2.2.6" + } + }, + "node_modules/@ledgerhq/hw-transport": { + "version": "5.51.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-5.51.1.tgz", + "integrity": "sha512-6wDYdbWrw9VwHIcoDnqWBaDFyviyjZWv6H9vz9Vyhe4Qd7TIFmbTl/eWs6hZvtZBza9K8y7zD8ChHwRI4s9tSw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@ledgerhq/devices": "^5.51.1", + "@ledgerhq/errors": "^5.50.0", + "events": "^3.3.0" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-5.26.0.tgz", + "integrity": "sha512-qhaefZVZatJ6UuK8Wb6WSFNOLWc2mxcv/xgsfKi5HJCIr4bPF/ecIeN+7fRcEaycxj4XykY6Z4A7zDVulfFH4w==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@ledgerhq/devices": "^5.26.0", + "@ledgerhq/errors": "^5.26.0", + "@ledgerhq/hw-transport": "^5.26.0", + "@ledgerhq/hw-transport-node-hid-noevents": "^5.26.0", + "@ledgerhq/logs": "^5.26.0", + "lodash": "^4.17.20", + "node-hid": "1.3.0", + "usb": "^1.6.3" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid-noevents": { + "version": "5.51.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-5.51.1.tgz", + "integrity": "sha512-9wFf1L8ZQplF7XOY2sQGEeOhpmBRzrn+4X43kghZ7FBDoltrcK+s/D7S+7ffg3j2OySyP6vIIIgloXylao5Scg==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@ledgerhq/devices": "^5.51.1", + "@ledgerhq/errors": "^5.50.0", + "@ledgerhq/hw-transport": "^5.51.1", + "@ledgerhq/logs": "^5.50.0", + "node-hid": "2.1.1" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/node-hid": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-2.1.1.tgz", + "integrity": "sha512-Skzhqow7hyLZU93eIPthM9yjot9lszg9xrKxESleEs05V2NcbUptZc5HFqzjOkSmL0sFlZFr3kmvaYebx06wrw==", + "dev": true, + "hasInstallScript": true, + "license": "(MIT OR X11)", + "optional": true, + "dependencies": { + "bindings": "^1.5.0", + "node-addon-api": "^3.0.2", + "prebuild-install": "^6.0.0" + }, + "bin": { + "hid-showdevices": "src/show-devices.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/prebuild-install": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", + "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.21.0", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@ledgerhq/hw-transport-u2f": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-u2f/-/hw-transport-u2f-5.26.0.tgz", + "integrity": "sha512-QTxP1Rsh+WZ184LUOelYVLeaQl3++V3I2jFik+l9JZtakwEHjD0XqOT750xpYNL/vfHsy31Wlz+oicdxGzFk+w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@ledgerhq/errors": "^5.26.0", + "@ledgerhq/hw-transport": "^5.26.0", + "@ledgerhq/logs": "^5.26.0", + "u2f-api": "0.2.7" + } + }, + "node_modules/@ledgerhq/logs": { + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-5.50.0.tgz", + "integrity": "sha512-swKHYCOZUGyVt4ge0u8a7AwNcA//h4nx5wIi0sruGye1IJ5Cva0GyK9L2/WdX+kWVTKp92ZiEo1df31lrWGPgA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@libp2p/interface": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@libp2p/interface/-/interface-2.2.1.tgz", + "integrity": "sha512-5dvsnf9+S5DoXCk5H3HNpe8lKzuXTi0k2On8Cdqr6YrkmrhCimow63AxtaUOVkH7GVBTTi8Q1jSx3aleX7KcEA==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "@multiformats/multiaddr": "^12.2.3", + "it-pushable": "^3.2.3", + "it-stream-types": "^2.0.1", + "multiformats": "^13.1.0", + "progress-events": "^1.0.0", + "uint8arraylist": "^2.4.8" + } + }, + "node_modules/@libp2p/logger": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@libp2p/logger/-/logger-5.1.4.tgz", + "integrity": "sha512-pVQ2odi6rcOR412wM0dg7eZ1+wPHPo5D7W8vIn3YyB2FLodQD7CZXXfg7Z9Yaqlc4BVbkNXDWL/jlUss9wL2Ow==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "@libp2p/interface": "^2.2.1", + "@multiformats/multiaddr": "^12.2.3", + "interface-datastore": "^8.3.0", + "multiformats": "^13.1.0", + "weald": "^1.0.2" + } + }, + "node_modules/@multiformats/dns": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@multiformats/dns/-/dns-1.0.6.tgz", + "integrity": "sha512-nt/5UqjMPtyvkG9BQYdJ4GfLK3nMqGpFZOzf4hAmIa0sJh2LlS9YKXZ4FgwBDsaHvzZqR/rUFIywIc7pkHNNuw==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "@types/dns-packet": "^5.6.5", + "buffer": "^6.0.3", + "dns-packet": "^5.6.1", + "hashlru": "^2.3.0", + "p-queue": "^8.0.1", + "progress-events": "^1.0.0", + "uint8arrays": "^5.0.2" + } + }, + "node_modules/@multiformats/multiaddr": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@multiformats/multiaddr/-/multiaddr-12.3.1.tgz", + "integrity": "sha512-yoGODQY4nIj41ENJClucS8FtBoe8w682bzbKldEQr9lSlfdHqAsRC+vpJAOBpiMwPps1tHua4kxrDmvprdhoDQ==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "@chainsafe/is-ip": "^2.0.1", + "@chainsafe/netmask": "^2.0.0", + "@multiformats/dns": "^1.0.3", + "multiformats": "^13.0.0", + "uint8-varint": "^2.0.1", + "uint8arrays": "^5.0.0" + } + }, + "node_modules/@multiformats/murmur3": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@multiformats/murmur3/-/murmur3-2.1.8.tgz", + "integrity": "sha512-6vId1C46ra3R1sbJUOFCZnsUIveR9oF20yhPmAFxPm0JfrX3/ZRCgP3YDrBzlGoEppOXnA9czHeYc0T9mB6hbA==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^13.0.0", + "murmurhash3js-revisited": "^3.0.0" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@noble/curves": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.1.tgz", + "integrity": "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==", + "dev": true, + "dependencies": { + "@noble/hashes": "1.7.1" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves/node_modules/@noble/hashes": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz", + "integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==", + "dev": true, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.37.0.tgz", + "integrity": "sha512-l7StVw6WAa8l3vA1ov80jyetOAEo1FtHvZDbzXDO/02Sq/QVvqlHkYoFwDJPIMj0GKiistsBudfx5tGFnwYWDQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.37.0.tgz", + "integrity": "sha512-6U3SlVyMxezt8Y+/iEBcbp945uZjJwjZimu76xoG7tO1av9VO691z8PkhzQ85ith2I8R2RddEPeSfcbyPfD4hA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.37.0.tgz", + "integrity": "sha512-+iTQ5YHuGmPt10NTzEyMPbayiNTcOZDWsbxZYR1ZnmLnZxG17ivrPSWFO9j6GalY0+gV3Jtwrrs12DBscxnlYA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.37.0.tgz", + "integrity": "sha512-m8W2UbxLDcmRKVjgl5J/k4B8d7qX2EcJve3Sut7YGrQoPtCIQGPH5AMzuFvYRWZi0FVS0zEY4c8uttPfX6bwYQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.37.0.tgz", + "integrity": "sha512-FOMXGmH15OmtQWEt174v9P1JqqhlgYge/bUjIbiVD1nI1NeJ30HYT9SJlZMqdo1uQFyt9cz748F1BHghWaDnVA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.37.0.tgz", + "integrity": "sha512-SZMxNttjPKvV14Hjck5t70xS3l63sbVwl98g3FlVVx2YIDmfUIy29jQrsw06ewEYQ8lQSuY9mpAPlmgRD2iSsA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.37.0.tgz", + "integrity": "sha512-hhAALKJPidCwZcj+g+iN+38SIOkhK2a9bqtJR+EtyxrKKSt1ynCBeqrQy31z0oWU6thRZzdx53hVgEbRkuI19w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.37.0.tgz", + "integrity": "sha512-jUb/kmn/Gd8epbHKEqkRAxq5c2EwRt0DqhSGWjPFxLeFvldFdHQs/n8lQ9x85oAeVb6bHcS8irhTJX2FCOd8Ag==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.37.0.tgz", + "integrity": "sha512-oNrJxcQT9IcbcmKlkF+Yz2tmOxZgG9D9GRq+1OE6XCQwCVwxixYAa38Z8qqPzQvzt1FCfmrHX03E0pWoXm1DqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.37.0.tgz", + "integrity": "sha512-pfxLBMls+28Ey2enpX3JvjEjaJMBX5XlPCZNGxj4kdJyHduPBXtxYeb8alo0a7bqOoWZW2uKynhHxF/MWoHaGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.37.0.tgz", + "integrity": "sha512-yCE0NnutTC/7IGUq/PUHmoeZbIwq3KRh02e9SfFh7Vmc1Z7atuJRYWhRME5fKgT8aS20mwi1RyChA23qSyRGpA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.37.0.tgz", + "integrity": "sha512-NxcICptHk06E2Lh3a4Pu+2PEdZ6ahNHuK7o6Np9zcWkrBMuv21j10SQDJW3C9Yf/A/P7cutWoC/DptNLVsZ0VQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.37.0.tgz", + "integrity": "sha512-PpWwHMPCVpFZLTfLq7EWJWvrmEuLdGn1GMYcm5MV7PaRgwCEYJAwiN94uBuZev0/J/hFIIJCsYw4nLmXA9J7Pw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.37.0.tgz", + "integrity": "sha512-DTNwl6a3CfhGTAOYZ4KtYbdS8b+275LSLqJVJIrPa5/JuIufWWZ/QFvkxp52gpmguN95eujrM68ZG+zVxa8zHA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.37.0.tgz", + "integrity": "sha512-hZDDU5fgWvDdHFuExN1gBOhCuzo/8TMpidfOR+1cPZJflcEzXdCy1LjnklQdW8/Et9sryOPJAKAQRw8Jq7Tg+A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.37.0.tgz", + "integrity": "sha512-pKivGpgJM5g8dwj0ywBwe/HeVAUSuVVJhUTa/URXjxvoyTT/AxsLTAbkHkDHG7qQxLoW2s3apEIl26uUe08LVQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.37.0.tgz", + "integrity": "sha512-E2lPrLKE8sQbY/2bEkVTGDEk4/49UYRVWgj90MY8yPjpnGBQ+Xi1Qnr7b7UIWw1NOggdFQFOLZ8+5CzCiz143w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.37.0.tgz", + "integrity": "sha512-Jm7biMazjNzTU4PrQtr7VS8ibeys9Pn29/1bm4ph7CP2kf21950LgN+BaE2mJ1QujnvOc6p54eWWiVvn05SOBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.37.0.tgz", + "integrity": "sha512-e3/1SFm1OjefWICB2Ucstg2dxYDkDTZGDYgwufcbsxTHyqQps1UQf33dFEChBNmeSsTOyrjw2JJq0zbG5GF6RA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.37.0.tgz", + "integrity": "sha512-LWbXUBwn/bcLx2sSsqy7pK5o+Nr+VCoRoAohfJ5C/aBio9nfJmGQqHAhU6pwxV/RmyTk5AqdySma7uwWGlmeuA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@safe-global/safe-core-sdk": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@safe-global/safe-core-sdk/-/safe-core-sdk-3.3.5.tgz", + "integrity": "sha512-ul+WmpxZOXgDIXrZ6MIHptThYbm0CVV3/rypMQEn4tZLkudh/yXK7EuWBFnx9prR3MePuku51Zcz9fu1vi7sfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethersproject/solidity": "^5.7.0", + "@safe-global/safe-core-sdk-types": "^1.9.2", + "@safe-global/safe-core-sdk-utils": "^1.7.4", + "@safe-global/safe-deployments": "^1.25.0", + "ethereumjs-util": "^7.1.5", + "semver": "^7.3.8", + "web3-utils": "^1.8.1", + "zksync-web3": "^0.14.3" + } + }, + "node_modules/@safe-global/safe-core-sdk-types": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@safe-global/safe-core-sdk-types/-/safe-core-sdk-types-1.10.1.tgz", + "integrity": "sha512-BKvuYTLOlY16Rq6qCXglmnL6KxInDuXMFqZMaCzwDKiEh+uoHu3xCumG5tVtWOkCgBF4XEZXMqwZUiLcon7IsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/contracts": "^5.7.0", + "@safe-global/safe-deployments": "^1.20.2", + "web3-core": "^1.8.1", + "web3-utils": "^1.8.1" + } + }, + "node_modules/@safe-global/safe-core-sdk-utils": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@safe-global/safe-core-sdk-utils/-/safe-core-sdk-utils-1.7.4.tgz", + "integrity": "sha512-ITocwSWlFUA1K9VMP/eJiMfgbP/I9qDxAaFz7ukj5N5NZD3ihVQZkmqML6hjse5UhrfjCnfIEcLkNZhtB2XC2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@safe-global/safe-core-sdk-types": "^1.9.2", + "semver": "^7.3.8", + "web3-utils": "^1.8.1" + } + }, + "node_modules/@safe-global/safe-deployments": { + "version": "1.37.3", + "resolved": "https://registry.npmjs.org/@safe-global/safe-deployments/-/safe-deployments-1.37.3.tgz", + "integrity": "sha512-EtbiOJVGe697+GcbHtfo75NYpp+hTlIIBqL2ETPLGoQBHoxo9HWbGX/6ZkVxsZv/NN4nKawyMi+MvpUkH9VXGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.6.2" + } + }, + "node_modules/@safe-global/safe-ethers-lib": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@safe-global/safe-ethers-lib/-/safe-ethers-lib-1.9.4.tgz", + "integrity": "sha512-WhzcmNun0s0VxeVQKRqaapV0vEpdm76zZBR2Du+S+58u1r57OjZkOSL2Gru0tdwkt3FIZZtE3OhDu09M70pVkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@safe-global/safe-core-sdk-types": "^1.9.2", + "@safe-global/safe-core-sdk-utils": "^1.7.4", + "ethers": "5.7.2" + } + }, + "node_modules/@safe-global/safe-service-client": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@safe-global/safe-service-client/-/safe-service-client-2.0.3.tgz", + "integrity": "sha512-t5eOopQUbP5HxixG0/TUGxzzNetLrNCxnLtt2RTzDVdlvgf/QGHywUqlJ5/eF8YBeZO/TNz6uAoLUMJ0u69IAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@safe-global/safe-core-sdk-types": "^1.9.2", + "node-fetch": "^2.6.6" + } + }, + "node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "dev": true, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@solidity-parser/parser": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.0.tgz", + "integrity": "sha512-ESipEcHyRHg4Np4SqBCfcXwyxxna1DgFVz69bgpLV8vzl/NP1DtcKsJ4dJZXWQhY/Z4J2LeKBiOkOVZn9ct33Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "node_modules/@supercharge/promise-pool": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@supercharge/promise-pool/-/promise-pool-3.2.0.tgz", + "integrity": "sha512-pj0cAALblTZBPtMltWOlZTQSLT07jIaFNeM8TWoJD1cQMgDB9mcMlVMoetiB35OzNJpqQ2b+QEtwiR9f20mADg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/bn.js": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", + "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/dns-packet": { + "version": "5.6.5", + "resolved": "https://registry.npmjs.org/@types/dns-packet/-/dns-packet-5.6.5.tgz", + "integrity": "sha512-qXOC7XLOEe43ehtWJCMnQXvgcIpv6rPmQ1jXT98Ad8A3TB1Ue50jsCbSSSyuazScEuZ/Q026vHbrOTVkmwA+7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "dev": true + }, + "node_modules/@types/mute-stream": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@types/mute-stream/-/mute-stream-0.0.4.tgz", + "integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", + "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.13.0" + } + }, + "node_modules/@types/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/secp256k1": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", + "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/wrap-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", + "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitest/expect": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz", + "integrity": "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==", + "dev": true, + "dependencies": { + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.9.tgz", + "integrity": "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==", + "dev": true, + "dependencies": { + "@vitest/spy": "2.1.9", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", + "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", + "dev": true, + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.9.tgz", + "integrity": "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==", + "dev": true, + "dependencies": { + "@vitest/utils": "2.1.9", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", + "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", + "dev": true, + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.9.tgz", + "integrity": "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==", + "dev": true, + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz", + "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==", + "dev": true, + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/abitype": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.8.tgz", + "integrity": "sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "typescript": ">=5.0.4", + "zod": "^3 >=3.22.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/abortcontroller-polyfill": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz", + "integrity": "sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/antlr4ts": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", + "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/are-we-there-yet/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/base-x": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", + "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/blockstore-core": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/blockstore-core/-/blockstore-core-5.0.2.tgz", + "integrity": "sha512-y7/BHdYLO3YCpJMg6Ue7b4Oz4FT1HWSZoHHdlsaJTsvoE8XieXb6kUCB9UkkUBDw2x4neRDwlgYBpyK77+Ro2Q==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "@libp2p/logger": "^5.0.1", + "interface-blockstore": "^5.0.0", + "interface-store": "^6.0.0", + "it-drain": "^3.0.7", + "it-filter": "^3.1.1", + "it-merge": "^3.0.5", + "it-pushable": "^3.2.3", + "multiformats": "^13.2.3" + } + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/bs58": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "base-x": "^4.0.0" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/bs58check/node_modules/base-x": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", + "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/bs58check/node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bufferutil": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chai": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz", + "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", + "dev": true, + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true, + "license": "MIT" + }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "engines": { + "node": ">= 16" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "node_modules/d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "dev": true, + "license": "ISC", + "dependencies": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", + "dev": true + }, + "node_modules/es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "dev": true, + "hasInstallScript": true, + "license": "ISC", + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "license": "MIT", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/es6-symbol": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/esbuild": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.0.tgz", + "integrity": "sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.23.0", + "@esbuild/android-arm": "0.23.0", + "@esbuild/android-arm64": "0.23.0", + "@esbuild/android-x64": "0.23.0", + "@esbuild/darwin-arm64": "0.23.0", + "@esbuild/darwin-x64": "0.23.0", + "@esbuild/freebsd-arm64": "0.23.0", + "@esbuild/freebsd-x64": "0.23.0", + "@esbuild/linux-arm": "0.23.0", + "@esbuild/linux-arm64": "0.23.0", + "@esbuild/linux-ia32": "0.23.0", + "@esbuild/linux-loong64": "0.23.0", + "@esbuild/linux-mips64el": "0.23.0", + "@esbuild/linux-ppc64": "0.23.0", + "@esbuild/linux-riscv64": "0.23.0", + "@esbuild/linux-s390x": "0.23.0", + "@esbuild/linux-x64": "0.23.0", + "@esbuild/netbsd-x64": "0.23.0", + "@esbuild/openbsd-arm64": "0.23.0", + "@esbuild/openbsd-x64": "0.23.0", + "@esbuild/sunos-x64": "0.23.0", + "@esbuild/win32-arm64": "0.23.0", + "@esbuild/win32-ia32": "0.23.0", + "@esbuild/win32-x64": "0.23.0" + } + }, + "node_modules/esbuild/node_modules/@esbuild/aix-ppc64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.0.tgz", + "integrity": "sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/android-arm": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.0.tgz", + "integrity": "sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/android-arm64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.0.tgz", + "integrity": "sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/android-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.0.tgz", + "integrity": "sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/darwin-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.0.tgz", + "integrity": "sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/freebsd-arm64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.0.tgz", + "integrity": "sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/freebsd-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.0.tgz", + "integrity": "sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-arm": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.0.tgz", + "integrity": "sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-arm64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.0.tgz", + "integrity": "sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-ia32": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.0.tgz", + "integrity": "sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-loong64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.0.tgz", + "integrity": "sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-mips64el": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.0.tgz", + "integrity": "sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-ppc64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.0.tgz", + "integrity": "sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-riscv64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.0.tgz", + "integrity": "sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-s390x": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.0.tgz", + "integrity": "sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.0.tgz", + "integrity": "sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/netbsd-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.0.tgz", + "integrity": "sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/openbsd-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.0.tgz", + "integrity": "sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/sunos-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.0.tgz", + "integrity": "sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/win32-arm64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.0.tgz", + "integrity": "sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/win32-ia32": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.0.tgz", + "integrity": "sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/win32-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.0.tgz", + "integrity": "sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/ethereum-bloom-filters": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.2.0.tgz", + "integrity": "sha512-28hyiE7HVsWubqhpVLVmZXFd4ITeHi+BUu05o9isf0GUpMtzBUi+8/gFrGaGYzvGAJQmJ3JKj77Mk9G98T84rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "^1.4.0" + } + }, + "node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/ethereum-cryptography/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethereumjs-util": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ethereumjs-util/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, + "node_modules/ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true, + "license": "MIT" + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", + "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, + "license": "(MIT OR WTFPL)", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/expect-type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.0.tgz", + "integrity": "sha512-80F22aiJ3GLyVnS/B3HzgR6RelZVumzj9jkL0Rhz4h0xYbNW9PjlQz5h3J/SShErbXBc295vseR4/MIbVmUbeA==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "license": "ISC", + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/find-object-paths": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-object-paths/-/find-object-paths-1.1.0.tgz", + "integrity": "sha512-UJvfPQibLUOrXl76PJ49cYbXJPsU1lYX6Pw7mHVW+ahaGx6kVHiozNIQriDc/EOlSvkDa6L9GyTFXPYQsa6sGA==", + "dev": true, + "license": "GPL-3.0-or-later" + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/gauge/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.6.tgz", + "integrity": "sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/hamt-sharding": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/hamt-sharding/-/hamt-sharding-3.0.6.tgz", + "integrity": "sha512-nZeamxfymIWLpVcAN0CRrb7uVq3hCOGj9IcL6NMA6VVCVWqj+h9Jo/SmaWuS92AEDf1thmHsM5D5c70hM3j2Tg==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "sparse-array": "^1.3.1", + "uint8arrays": "^5.0.1" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hashlru": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/hashlru/-/hashlru-2.3.0.tgz", + "integrity": "sha512-0cMsjjIC8I+D3M44pOQdsy0OHXGLVz6Z0beRuufhKa0KfaD2wGwAev6jILzXsd3/vpnNQJmWyZtIILqM1N+n5A==", + "dev": true, + "license": "MIT" + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/http-https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", + "integrity": "sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==", + "dev": true, + "license": "ISC" + }, + "node_modules/husky": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", + "dev": true, + "license": "MIT", + "bin": { + "husky": "lib/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/interface-blockstore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/interface-blockstore/-/interface-blockstore-5.3.1.tgz", + "integrity": "sha512-nhgrQnz6yUQEqxTFLhlOBurQOy5lWlwCpgFmZ3GTObTVTQS9RZjK/JTozY6ty9uz2lZs7VFJSqwjWAltorJ4Vw==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "interface-store": "^6.0.0", + "multiformats": "^13.2.3" + } + }, + "node_modules/interface-datastore": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/interface-datastore/-/interface-datastore-8.3.1.tgz", + "integrity": "sha512-3r0ETmHIi6HmvM5sc09QQiCD3gUfwtEM/AAChOyAd/UAKT69uk8LXfTSUBufbUIO/dU65Vj8nb9O6QjwW8vDSQ==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "interface-store": "^6.0.0", + "uint8arrays": "^5.1.0" + } + }, + "node_modules/interface-store": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/interface-store/-/interface-store-6.0.2.tgz", + "integrity": "sha512-KSFCXtBlNoG0hzwNa0RmhHtrdhzexp+S+UY2s0rWTBJyfdEIgn6i6Zl9otVqrcFYbYrneBT7hbmHQ8gE0C3umA==", + "dev": true, + "license": "Apache-2.0 OR MIT" + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ipfs-unixfs": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/ipfs-unixfs/-/ipfs-unixfs-11.2.0.tgz", + "integrity": "sha512-J8FN1qM5nfrDo8sQKQwfj0+brTg1uBfZK2vY9hxci33lcl3BFrsELS9+1+4q/8tO1ASKfxZO8W3Pi2O4sVX2Lg==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "protons-runtime": "^5.5.0", + "uint8arraylist": "^2.4.8" + } + }, + "node_modules/ipfs-unixfs-importer": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/ipfs-unixfs-importer/-/ipfs-unixfs-importer-15.3.1.tgz", + "integrity": "sha512-wHCTBqNsZXLJZ9/GSr7Msb3FDXD5yXF20Y9sKyUbbqNjbvaXs3n3h1+NM/5+WrgESHfwRcJIlJtaOKafL8Ymdg==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "@ipld/dag-pb": "^4.1.2", + "@multiformats/murmur3": "^2.1.8", + "hamt-sharding": "^3.0.6", + "interface-blockstore": "^5.3.0", + "interface-store": "^6.0.0", + "ipfs-unixfs": "^11.0.0", + "it-all": "^3.0.6", + "it-batch": "^3.0.6", + "it-first": "^3.0.6", + "it-parallel-batch": "^3.0.6", + "multiformats": "^13.2.3", + "progress-events": "^1.0.1", + "rabin-wasm": "^0.1.5", + "uint8arraylist": "^2.4.8", + "uint8arrays": "^5.1.0" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true, + "license": "MIT" + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/isows": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.6.tgz", + "integrity": "sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/it-all": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/it-all/-/it-all-3.0.6.tgz", + "integrity": "sha512-HXZWbxCgQZJfrv5rXvaVeaayXED8nTKx9tj9fpBhmcUJcedVZshMMMqTj0RG2+scGypb9Ut1zd1ifbf3lA8L+Q==", + "dev": true, + "license": "Apache-2.0 OR MIT" + }, + "node_modules/it-batch": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/it-batch/-/it-batch-3.0.6.tgz", + "integrity": "sha512-pQAAlSvJ4aV6xM/6LRvkPdKSKXxS4my2fGzNUxJyAQ8ccFdxPmK1bUuF5OoeUDkcdrbs8jtsmc4DypCMrGY6sg==", + "dev": true, + "license": "Apache-2.0 OR MIT" + }, + "node_modules/it-drain": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/it-drain/-/it-drain-3.0.7.tgz", + "integrity": "sha512-vy6S1JKjjHSIFHgBpLpD1zhkCRl3z1zYWUxE14+kAYf+BL9ssWSFImJfhl361IIcwr0ofw8etzg11VqqB+ntUA==", + "dev": true, + "license": "Apache-2.0 OR MIT" + }, + "node_modules/it-filter": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/it-filter/-/it-filter-3.1.1.tgz", + "integrity": "sha512-TOXmVuaSkxlLp2hXKoMTra0WMZMKVFxE3vSsbIA+PbADNCBAHhjJ/lM31vBOUTddHMO34Ku++vU8T9PLlBxQtg==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "it-peekable": "^3.0.0" + } + }, + "node_modules/it-first": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/it-first/-/it-first-3.0.6.tgz", + "integrity": "sha512-ExIewyK9kXKNAplg2GMeWfgjUcfC1FnUXz/RPfAvIXby+w7U4b3//5Lic0NV03gXT8O/isj5Nmp6KiY0d45pIQ==", + "dev": true, + "license": "Apache-2.0 OR MIT" + }, + "node_modules/it-merge": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/it-merge/-/it-merge-3.0.5.tgz", + "integrity": "sha512-2l7+mPf85pyRF5pqi0dKcA54E5Jm/2FyY5GsOaN51Ta0ipC7YZ3szuAsH8wOoB6eKY4XsU4k2X+mzPmFBMayEA==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "it-pushable": "^3.2.3" + } + }, + "node_modules/it-parallel-batch": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/it-parallel-batch/-/it-parallel-batch-3.0.6.tgz", + "integrity": "sha512-3wgiQGvMMHy65OXScrtrtmY+bJSF7P6St1AP+BU+SK83fEr8NNk/MrmJKrtB1+MahYX2a8I+pOGKDj8qVtuV0Q==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "it-batch": "^3.0.0" + } + }, + "node_modules/it-peekable": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/it-peekable/-/it-peekable-3.0.5.tgz", + "integrity": "sha512-JWQOGMt6rKiPcY30zUVMR4g6YxkpueTwHVE7CMs/aGqCf4OydM6w+7ZM3PvmO1e0TocjuR4aL8xyZWR46cTqCQ==", + "dev": true, + "license": "Apache-2.0 OR MIT" + }, + "node_modules/it-pushable": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/it-pushable/-/it-pushable-3.2.3.tgz", + "integrity": "sha512-gzYnXYK8Y5t5b/BnJUr7glfQLO4U5vyb05gPx/TyTw+4Bv1zM9gFk4YsOrnulWefMewlphCjKkakFvj1y99Tcg==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "p-defer": "^4.0.0" + } + }, + "node_modules/it-stream-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/it-stream-types/-/it-stream-types-2.0.2.tgz", + "integrity": "sha512-Rz/DEZ6Byn/r9+/SBCuJhpPATDF9D+dz5pbgSUyBsCDtza6wtNATrz/jz1gDyNanC3XdLboriHnOC925bZRBww==", + "dev": true, + "license": "Apache-2.0 OR MIT" + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/keccak": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loupe": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", + "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", + "dev": true + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/micro-ftch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", + "dev": true, + "license": "MIT" + }, + "node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true, + "license": "MIT" + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/multiformats": { + "version": "13.3.1", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.3.1.tgz", + "integrity": "sha512-QxowxTNwJ3r5RMctoGA5p13w5RbRT2QDkoM+yFlqfLiioBp78nhDjnRLvmSBI9+KAqN4VdgOVWM9c0CHd86m3g==", + "dev": true, + "license": "Apache-2.0 OR MIT" + }, + "node_modules/murmurhash3js-revisited": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/murmurhash3js-revisited/-/murmurhash3js-revisited-3.0.0.tgz", + "integrity": "sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/nan": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", + "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/node-abi": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", + "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "semver": "^5.4.1" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", + "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", + "dev": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-hid": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-1.3.0.tgz", + "integrity": "sha512-BA6G4V84kiNd1uAChub/Z/5s/xS3EHBCxotQ0nyYrUG65mXewUDHE1tWOSqA2dp3N+mV0Ffq9wo2AW9t4p/G7g==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.14.0", + "node-abi": "^2.18.0", + "prebuild-install": "^5.3.4" + }, + "bin": { + "hid-showdevices": "src/show-devices.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/noop-logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", + "integrity": "sha512-6kM8CLXvuW5crTxsAtva2YLrRrDaiTIkIePWs9moLHqbFWT94WpNFjwS/5dfLfECg5i/lkmw3aoqVidxt23TEQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/oboe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", + "integrity": "sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA==", + "dev": true, + "license": "BSD", + "dependencies": { + "http-https": "^1.0.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ox": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/ox/-/ox-0.6.7.tgz", + "integrity": "sha512-17Gk/eFsFRAZ80p5eKqv89a57uXjd3NgIf1CaXojATPBuujVc/fQSVhBeAU9JCRB+k7J50WQAyWTxK19T9GgbA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "dependencies": { + "@adraffy/ens-normalize": "^1.10.1", + "@noble/curves": "^1.6.0", + "@noble/hashes": "^1.5.0", + "@scure/bip32": "^1.5.0", + "@scure/bip39": "^1.4.0", + "abitype": "^1.0.6", + "eventemitter3": "5.0.1" + }, + "peerDependencies": { + "typescript": ">=5.4.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/ox/node_modules/@noble/hashes": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz", + "integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==", + "dev": true, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ox/node_modules/@scure/base": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.4.tgz", + "integrity": "sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ==", + "dev": true, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ox/node_modules/@scure/bip32": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.6.2.tgz", + "integrity": "sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==", + "dev": true, + "dependencies": { + "@noble/curves": "~1.8.1", + "@noble/hashes": "~1.7.1", + "@scure/base": "~1.2.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ox/node_modules/@scure/bip39": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.5.4.tgz", + "integrity": "sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==", + "dev": true, + "dependencies": { + "@noble/hashes": "~1.7.1", + "@scure/base": "~1.2.4" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ox/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/p-defer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-4.0.1.tgz", + "integrity": "sha512-Mr5KC5efvAK5VUptYEIopP1bakB85k2IWXaRC0rsh1uwn1L6M0LVml8OIQ4Gudg4oyZakf7FmeRLkMMtZW1i5A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.0.1.tgz", + "integrity": "sha512-NXzu9aQJTAzbBqOt2hwsR63ea7yvxJc0PwN/zobNAudYfb1B7R08SzB4TsLeSbUCuG467NhnoT0oO6w1qRO+BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.1", + "p-timeout": "^6.1.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true, + "license": "MIT" + }, + "node_modules/p-timeout": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.3.tgz", + "integrity": "sha512-UJUyfKbwvr/uZSV6btANfb+0t/mOhKV/KXcCUTp8FcQI+v/0d+wXqH4htrW0E4rR6WiEO/EPvUFiV9D5OI4vlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true + }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "dev": true, + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prebuild-install": { + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.6.tgz", + "integrity": "sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.7.0", + "noop-logger": "^0.1.1", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0", + "which-pm-runs": "^1.0.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prettier": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", + "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-solidity": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.3.tgz", + "integrity": "sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@solidity-parser/parser": "^0.16.0", + "semver": "^7.3.8", + "solidity-comments-extractor": "^0.0.7" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "prettier": ">=2.3.0 || >=3.0.0-alpha.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/progress-events": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/progress-events/-/progress-events-1.0.1.tgz", + "integrity": "sha512-MOzLIwhpt64KIVN64h1MwdKWiyKFNc/S6BoYKPIVUHFg0/eIEyBulhWCgn678v/4c0ri3FdGuzXymNCv02MUIw==", + "dev": true, + "license": "Apache-2.0 OR MIT" + }, + "node_modules/protons-runtime": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/protons-runtime/-/protons-runtime-5.5.0.tgz", + "integrity": "sha512-EsALjF9QsrEk6gbCx3lmfHxVN0ah7nG3cY7GySD4xf4g8cr7g543zB88Foh897Sr1RQJ9yDCUsoT1i1H/cVUFA==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "uint8-varint": "^2.0.2", + "uint8arraylist": "^2.4.3", + "uint8arrays": "^5.0.1" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/rabin-wasm": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/rabin-wasm/-/rabin-wasm-0.1.5.tgz", + "integrity": "sha512-uWgQTo7pim1Rnj5TuWcCewRDTf0PEFTSlaUjWP4eY9EbLV9em08v89oCz/WO+wRxpYuO36XEHp4wgYQnAgOHzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@assemblyscript/loader": "^0.9.4", + "bl": "^5.0.0", + "debug": "^4.3.1", + "minimist": "^1.2.5", + "node-fetch": "^2.6.1", + "readable-stream": "^3.6.0" + }, + "bin": { + "rabin-wasm": "cli/bin.js" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "optional": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/rollup": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.37.0.tgz", + "integrity": "sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.37.0", + "@rollup/rollup-android-arm64": "4.37.0", + "@rollup/rollup-darwin-arm64": "4.37.0", + "@rollup/rollup-darwin-x64": "4.37.0", + "@rollup/rollup-freebsd-arm64": "4.37.0", + "@rollup/rollup-freebsd-x64": "4.37.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.37.0", + "@rollup/rollup-linux-arm-musleabihf": "4.37.0", + "@rollup/rollup-linux-arm64-gnu": "4.37.0", + "@rollup/rollup-linux-arm64-musl": "4.37.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.37.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.37.0", + "@rollup/rollup-linux-riscv64-gnu": "4.37.0", + "@rollup/rollup-linux-riscv64-musl": "4.37.0", + "@rollup/rollup-linux-s390x-gnu": "4.37.0", + "@rollup/rollup-linux-x64-gnu": "4.37.0", + "@rollup/rollup-linux-x64-musl": "4.37.0", + "@rollup/rollup-win32-arm64-msvc": "4.37.0", + "@rollup/rollup-win32-ia32-msvc": "4.37.0", + "@rollup/rollup-win32-x64-msvc": "4.37.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup/node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true + }, + "node_modules/run-async": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", + "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "dev": true, + "license": "MIT" + }, + "node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/secp256k1/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/secp256k1/node_modules/elliptic": { + "version": "6.5.6", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.6.tgz", + "integrity": "sha512-mpzdtpeCLuS3BmE3pO3Cpp5bbjlOPY2Q0PgoF+Od1XZrHLYI28Xe3ossCmYCQt11FQKEYd9+PF8jymTvtWJSHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true, + "license": "MIT" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/solidity-comments-extractor": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", + "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sparse-array": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/sparse-array/-/sparse-array-1.3.2.tgz", + "integrity": "sha512-ZT711fePGn3+kQyLuv1fpd3rNSkNF8vd5Kv2D+qnOANeyKs3fx6bUMGWRPvgTTcYV64QMqZKZwcuaQSP3AZ0tg==", + "dev": true, + "license": "ISC" + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.1.tgz", + "integrity": "sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==", + "dev": true + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/tar-stream/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true + }, + "node_modules/tinypool": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.1.tgz", + "integrity": "sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, + "license": "0BSD" + }, + "node_modules/tsx": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.0.tgz", + "integrity": "sha512-bV30kM7bsLZKZIOCHeMNVMJ32/LuJzLVajkQI/qf92J2Qr08ueLQvW00PUZGiuLPP760UINwupgUj8qrSCPUKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.23.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", + "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/u2f-api": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/u2f-api/-/u2f-api-0.2.7.tgz", + "integrity": "sha512-fqLNg8vpvLOD5J/z4B6wpPg4Lvowz1nJ9xdHcCzdUPKcFE/qNCceV2gNZxSJd5vhAZemHr/K/hbzVA0zxB5mkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/uint8-varint": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/uint8-varint/-/uint8-varint-2.0.4.tgz", + "integrity": "sha512-FwpTa7ZGA/f/EssWAb5/YV6pHgVF1fViKdW8cWaEarjB8t7NyofSWBdOTyFPaGuUG4gx3v1O3PQ8etsiOs3lcw==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "uint8arraylist": "^2.0.0", + "uint8arrays": "^5.0.0" + } + }, + "node_modules/uint8arraylist": { + "version": "2.4.8", + "resolved": "https://registry.npmjs.org/uint8arraylist/-/uint8arraylist-2.4.8.tgz", + "integrity": "sha512-vc1PlGOzglLF0eae1M8mLRTBivsvrGsdmJ5RbK3e+QRvRLOZfZhQROTwH/OfyF3+ZVUg9/8hE8bmKP2CvP9quQ==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "uint8arrays": "^5.0.1" + } + }, + "node_modules/uint8arrays": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.1.0.tgz", + "integrity": "sha512-vA6nFepEmlSKkMBnLBaUMVvAC4G3CTmO58C12y4sq6WPDOR7mOFYOi7GlrQ4djeSbP6JG9Pv9tJDM97PedRSww==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^13.0.0" + } + }, + "node_modules/undici-types": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", + "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==", + "dev": true, + "license": "MIT" + }, + "node_modules/usb": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/usb/-/usb-1.9.2.tgz", + "integrity": "sha512-dryNz030LWBPAf6gj8vyq0Iev3vPbCLHCT8dBw3gQRXRzVNsIdeuU+VjPp3ksmSPkeMAl1k+kQ14Ij0QHyeiAg==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-addon-api": "^4.2.0", + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/usb/node_modules/node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", + "dev": true, + "optional": true + }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, + "node_modules/viem": { + "version": "2.23.6", + "resolved": "https://registry.npmjs.org/viem/-/viem-2.23.6.tgz", + "integrity": "sha512-+yUeK8rktbGFQaLIvY4Tki22HUjian9Z4eKGAUT72RF9bcfkYgK8CJZz9P83tgoeLpiTyX3xcBM4xJZrJyKmsA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "dependencies": { + "@noble/curves": "1.8.1", + "@noble/hashes": "1.7.1", + "@scure/bip32": "1.6.2", + "@scure/bip39": "1.5.4", + "abitype": "1.0.8", + "isows": "1.0.6", + "ox": "0.6.7", + "ws": "8.18.0" + }, + "peerDependencies": { + "typescript": ">=5.0.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/viem/node_modules/@noble/hashes": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz", + "integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==", + "dev": true, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/@scure/base": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.4.tgz", + "integrity": "sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ==", + "dev": true, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/@scure/bip32": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.6.2.tgz", + "integrity": "sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==", + "dev": true, + "dependencies": { + "@noble/curves": "~1.8.1", + "@noble/hashes": "~1.7.1", + "@scure/base": "~1.2.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/@scure/bip39": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.5.4.tgz", + "integrity": "sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==", + "dev": true, + "dependencies": { + "@noble/hashes": "~1.7.1", + "@scure/base": "~1.2.4" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/vite": { + "version": "5.4.15", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.15.tgz", + "integrity": "sha512-6ANcZRivqL/4WtwPGTKNaosuNJr5tWiftOC7liM7G9+rMb8+oeJeyzymDu4rTN93seySBmbjSfsS3Vzr19KNtA==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.9.tgz", + "integrity": "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==", + "dev": true, + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.7", + "es-module-lexer": "^1.5.4", + "pathe": "^1.1.2", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/vitest": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.9.tgz", + "integrity": "sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==", + "dev": true, + "dependencies": { + "@vitest/expect": "2.1.9", + "@vitest/mocker": "2.1.9", + "@vitest/pretty-format": "^2.1.9", + "@vitest/runner": "2.1.9", + "@vitest/snapshot": "2.1.9", + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.1.9", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.1.9", + "@vitest/ui": "2.1.9", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/weald": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/weald/-/weald-1.0.4.tgz", + "integrity": "sha512-+kYTuHonJBwmFhP1Z4YQK/dGi3jAnJGCYhyODFpHK73rbxnp9lnZQj7a2m+WVgn8fXr5bJaxUpF6l8qZpPeNWQ==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "ms": "^3.0.0-canary.1", + "supports-color": "^9.4.0" + } + }, + "node_modules/weald/node_modules/ms": { + "version": "3.0.0-canary.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-3.0.0-canary.1.tgz", + "integrity": "sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.13" + } + }, + "node_modules/weald/node_modules/supports-color": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz", + "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/web3-core": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.10.4.tgz", + "integrity": "sha512-B6elffYm81MYZDTrat7aEhnhdtVE3lDBUZft16Z8awYMZYJDbnykEbJVS+l3mnA7AQTnSDr/1MjWofGDLBJPww==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@types/bn.js": "^5.1.1", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.10.4", + "web3-core-method": "1.10.4", + "web3-core-requestmanager": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-helpers": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-method": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.10.4.tgz", + "integrity": "sha512-uZTb7flr+Xl6LaDsyTeE2L1TylokCJwTDrIVfIfnrGmnwLc6bmTWCCrm71sSrQ0hqs6vp/MKbQYIYqUN0J8WyA==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@ethersproject/transactions": "^5.6.2", + "web3-core-helpers": "1.10.4", + "web3-core-promievent": "1.10.4", + "web3-core-subscriptions": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-promievent": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.10.4.tgz", + "integrity": "sha512-2de5WnJQ72YcIhYwV/jHLc4/cWJnznuoGTJGD29ncFQHAfwW/MItHFSVKPPA5v8AhJe+r6y4Y12EKvZKjQVBvQ==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-requestmanager": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.10.4.tgz", + "integrity": "sha512-vqP6pKH8RrhT/2MoaU+DY/OsYK9h7HmEBNCdoMj+4ZwujQtw/Mq2JifjwsJ7gits7Q+HWJwx8q6WmQoVZAWugg==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "util": "^0.12.5", + "web3-core-helpers": "1.10.4", + "web3-providers-http": "1.10.4", + "web3-providers-ipc": "1.10.4", + "web3-providers-ws": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-subscriptions": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.10.4.tgz", + "integrity": "sha512-o0lSQo/N/f7/L76C0HV63+S54loXiE9fUPfHFcTtpJRQNDBVsSDdWRdePbWwR206XlsBqD5VHApck1//jEafTw==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-eth-iban": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-http": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.10.4.tgz", + "integrity": "sha512-m2P5Idc8hdiO0l60O6DSCPw0kw64Zgi0pMjbEFRmxKIck2Py57RQMu4bxvkxJwkF06SlGaEQF8rFZBmuX7aagQ==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "abortcontroller-polyfill": "^1.7.5", + "cross-fetch": "^4.0.0", + "es6-promise": "^4.2.8", + "web3-core-helpers": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-ipc": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.10.4.tgz", + "integrity": "sha512-YRF/bpQk9z3WwjT+A6FI/GmWRCASgd+gC0si7f9zbBWLXjwzYAKG73bQBaFRAHex1hl4CVcM5WUMaQXf3Opeuw==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "oboe": "2.1.5", + "web3-core-helpers": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-ws": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.10.4.tgz", + "integrity": "sha512-j3FBMifyuFFmUIPVQR4pj+t5ILhAexAui0opgcpu9R5LxQrLRUZxHSnU+YO25UycSOa/NAX8A+qkqZNpcFAlxA==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.10.4", + "websocket": "^1.0.32" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-utils": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.4.tgz", + "integrity": "sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@ethereumjs/util": "^8.1.0", + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereum-cryptography": "^2.1.2", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/websocket": { + "version": "1.0.35", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.35.tgz", + "integrity": "sha512-/REy6amwPZl44DDzvRCkaI1q1bIiQB0mEFQLUrhz3z2EK91cp3n72rAjUlrTP0zV22HJIUOVHQGPxhFRjxjt+Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.63", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/websocket/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/websocket/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which-pm-runs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", + "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.32" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zksync-web3": { + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/zksync-web3/-/zksync-web3-0.14.4.tgz", + "integrity": "sha512-kYehMD/S6Uhe1g434UnaMN+sBr9nQm23Ywn0EUP5BfQCsbjcr3ORuS68PosZw8xUTu3pac7G6YMSnNHk+fwzvg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ethers": "^5.7.0" + } + }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/package.json b/package.json index 3f63768..2aa9c4f 100644 --- a/package.json +++ b/package.json @@ -22,10 +22,11 @@ "url": "https://github.com/bgd-labs/aave-risk-stewards-2/issues" }, "homepage": "https://github.com/bgd-labs/aave-risk-stewards-2#readme", + "packageManager": "^npm@10.0.0", "devDependencies": { "prettier": "2.8.7", "prettier-plugin-solidity": "1.1.3", - "vitest": "^2.0.4", + "vitest": "^2.1.8", "@bgd-labs/aave-address-book": "^4.16.1", "@bgd-labs/aave-cli": "^1.1.12", "@bgd-labs/js-utils": "^1.4.7", From f203e01be5ebf6dfdeb6766ae975fc311f43f709 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Fri, 28 Mar 2025 21:09:12 +0530 Subject: [PATCH 13/25] fix: certora ci --- certora/confs/rules.conf | 4 +++- certora/confs/sanity.conf | 4 +++- remappings.txt | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/certora/confs/rules.conf b/certora/confs/rules.conf index 61a1992..371fcc8 100644 --- a/certora/confs/rules.conf +++ b/certora/confs/rules.conf @@ -14,7 +14,9 @@ "lib/aave-helpers:aave-v3-origin=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/src", "aave-v3-origin=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin", "aave-capo=lib/aave-capo/src", - "lib/aave-capo:cl-synchronicity-price-adapter=lib/aave-capo/lib/cl-synchronicity-price-adapter/src" + "lib/aave-capo:cl-synchronicity-price-adapter=lib/aave-capo/lib/cl-synchronicity-price-adapter/src", + "openzeppelin-contracts-upgradeable=lib/aave-capo/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable", + "openzeppelin-contracts=lib/aave-capo/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts" ], "optimistic_loop": true, "loop_iter": "2", diff --git a/certora/confs/sanity.conf b/certora/confs/sanity.conf index 683b9d6..4413799 100644 --- a/certora/confs/sanity.conf +++ b/certora/confs/sanity.conf @@ -10,7 +10,9 @@ "lib/aave-helpers:aave-v3-origin=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/src", "aave-v3-origin=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin", "aave-capo=lib/aave-capo/src", - "lib/aave-capo:cl-synchronicity-price-adapter=lib/aave-capo/lib/cl-synchronicity-price-adapter/src" + "lib/aave-capo:cl-synchronicity-price-adapter=lib/aave-capo/lib/cl-synchronicity-price-adapter/src", + "openzeppelin-contracts-upgradeable=lib/aave-capo/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable", + "openzeppelin-contracts=lib/aave-capo/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts" ], "optimistic_loop": true, "prover_args": ["-depth 15","-mediumTimeout 1000"], diff --git a/remappings.txt b/remappings.txt index f8dbf3a..3c9c628 100644 --- a/remappings.txt +++ b/remappings.txt @@ -5,4 +5,6 @@ solidity-utils/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/lib/so lib/aave-helpers:aave-v3-origin/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/src aave-v3-origin/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/ aave-capo/=lib/aave-capo/src -lib/aave-capo:cl-synchronicity-price-adapter/=lib/aave-capo/lib/cl-synchronicity-price-adapter/src/ \ No newline at end of file +lib/aave-capo:cl-synchronicity-price-adapter/=lib/aave-capo/lib/cl-synchronicity-price-adapter/src/ +openzeppelin-contracts-upgradeable/=lib/aave-capo/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/ +openzeppelin-contracts/=lib/aave-capo/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/ From 282a923b5644da7b0da496ac8e2338183b5ca6b5 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Fri, 28 Mar 2025 21:18:31 +0530 Subject: [PATCH 14/25] fix: ci --- .github/workflows/certora.yml | 4 ++-- certora/confs/rules.conf | 2 +- certora/confs/sanity.conf | 2 +- remappings.txt | 2 -- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/certora.yml b/.github/workflows/certora.yml index 48e8182..52d5a82 100644 --- a/.github/workflows/certora.yml +++ b/.github/workflows/certora.yml @@ -32,9 +32,9 @@ jobs: - name: Install solc run: | - wget https://github.com/ethereum/solidity/releases/download/v0.8.19/solc-static-linux + wget https://github.com/ethereum/solidity/releases/download/v0.8.24/solc-static-linux chmod +x solc-static-linux - sudo mv solc-static-linux /usr/local/bin/solc8.19 + sudo mv solc-static-linux /usr/local/bin/solc8.24 - name: Verify rule ${{ matrix.rule }} run: | diff --git a/certora/confs/rules.conf b/certora/confs/rules.conf index 371fcc8..190e7b6 100644 --- a/certora/confs/rules.conf +++ b/certora/confs/rules.conf @@ -23,7 +23,7 @@ "rule_sanity": "basic", "prover_args": ["-depth 15","-mediumTimeout 1000"], "smt_timeout": "2000", - "solc": "solc8.19", + "solc": "solc8.24", "verify": "RiskSteward:certora/specs/rules.spec", "cache" :"none", "msg": "RISK-STEWARD::rules" diff --git a/certora/confs/sanity.conf b/certora/confs/sanity.conf index 4413799..d5a74d2 100644 --- a/certora/confs/sanity.conf +++ b/certora/confs/sanity.conf @@ -17,7 +17,7 @@ "optimistic_loop": true, "prover_args": ["-depth 15","-mediumTimeout 1000"], "smt_timeout": "2000", - "solc": "solc8.19", + "solc": "solc8.24", "verify": "RiskSteward:certora/specs/sanity.spec", "cache" :"none", "msg": "RISK-STEWARD::sanity" diff --git a/remappings.txt b/remappings.txt index 3c9c628..25e78da 100644 --- a/remappings.txt +++ b/remappings.txt @@ -6,5 +6,3 @@ lib/aave-helpers:aave-v3-origin/=lib/aave-helpers/lib/aave-address-book/lib/aave aave-v3-origin/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/ aave-capo/=lib/aave-capo/src lib/aave-capo:cl-synchronicity-price-adapter/=lib/aave-capo/lib/cl-synchronicity-price-adapter/src/ -openzeppelin-contracts-upgradeable/=lib/aave-capo/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/ -openzeppelin-contracts/=lib/aave-capo/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/ From de3ed286a7c62b09cf80d0ad34fe6c5b1b9e3142 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Fri, 28 Mar 2025 22:59:51 +0530 Subject: [PATCH 15/25] refactor: config struct --- .github/workflows/certora.yml | 4 +- certora/confs/rules.conf | 6 +- certora/confs/sanity.conf | 6 +- foundry.toml | 2 +- remappings.txt | 2 +- scripts/RiskStewardsBase.s.sol | 24 +- scripts/deploy/DeployCapInjector.s.sol | 48 ++-- scripts/deploy/DeployRateInjector.s.sol | 48 ++-- scripts/deploy/DeployStewards.s.sol | 76 ++++--- src/contracts/EdgeRiskStewardCaps.sol | 10 +- src/contracts/EdgeRiskStewardRates.sol | 10 +- src/contracts/RiskSteward.sol | 113 +++++----- src/interfaces/IRiskSteward.sol | 49 ++++- tests/AaveStewardsInjectorCaps.t.sol | 22 +- tests/AaveStewardsInjectorRates.t.sol | 24 +- tests/EdgeRiskStewardCaps.t.sol | 55 +---- tests/EdgeRiskStewardRates.t.sol | 48 +--- tests/RiskSteward.t.sol | 279 ++++++++++-------------- tests/RiskStewardCapo.t.sol | 27 +-- 19 files changed, 366 insertions(+), 487 deletions(-) diff --git a/.github/workflows/certora.yml b/.github/workflows/certora.yml index 48e8182..52d5a82 100644 --- a/.github/workflows/certora.yml +++ b/.github/workflows/certora.yml @@ -32,9 +32,9 @@ jobs: - name: Install solc run: | - wget https://github.com/ethereum/solidity/releases/download/v0.8.19/solc-static-linux + wget https://github.com/ethereum/solidity/releases/download/v0.8.24/solc-static-linux chmod +x solc-static-linux - sudo mv solc-static-linux /usr/local/bin/solc8.19 + sudo mv solc-static-linux /usr/local/bin/solc8.24 - name: Verify rule ${{ matrix.rule }} run: | diff --git a/certora/confs/rules.conf b/certora/confs/rules.conf index 61a1992..190e7b6 100644 --- a/certora/confs/rules.conf +++ b/certora/confs/rules.conf @@ -14,14 +14,16 @@ "lib/aave-helpers:aave-v3-origin=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/src", "aave-v3-origin=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin", "aave-capo=lib/aave-capo/src", - "lib/aave-capo:cl-synchronicity-price-adapter=lib/aave-capo/lib/cl-synchronicity-price-adapter/src" + "lib/aave-capo:cl-synchronicity-price-adapter=lib/aave-capo/lib/cl-synchronicity-price-adapter/src", + "openzeppelin-contracts-upgradeable=lib/aave-capo/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable", + "openzeppelin-contracts=lib/aave-capo/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts" ], "optimistic_loop": true, "loop_iter": "2", "rule_sanity": "basic", "prover_args": ["-depth 15","-mediumTimeout 1000"], "smt_timeout": "2000", - "solc": "solc8.19", + "solc": "solc8.24", "verify": "RiskSteward:certora/specs/rules.spec", "cache" :"none", "msg": "RISK-STEWARD::rules" diff --git a/certora/confs/sanity.conf b/certora/confs/sanity.conf index 683b9d6..d5a74d2 100644 --- a/certora/confs/sanity.conf +++ b/certora/confs/sanity.conf @@ -10,12 +10,14 @@ "lib/aave-helpers:aave-v3-origin=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/src", "aave-v3-origin=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin", "aave-capo=lib/aave-capo/src", - "lib/aave-capo:cl-synchronicity-price-adapter=lib/aave-capo/lib/cl-synchronicity-price-adapter/src" + "lib/aave-capo:cl-synchronicity-price-adapter=lib/aave-capo/lib/cl-synchronicity-price-adapter/src", + "openzeppelin-contracts-upgradeable=lib/aave-capo/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable", + "openzeppelin-contracts=lib/aave-capo/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts" ], "optimistic_loop": true, "prover_args": ["-depth 15","-mediumTimeout 1000"], "smt_timeout": "2000", - "solc": "solc8.19", + "solc": "solc8.24", "verify": "RiskSteward:certora/specs/sanity.spec", "cache" :"none", "msg": "RISK-STEWARD::sanity" diff --git a/foundry.toml b/foundry.toml index 6e326b1..e648ae3 100644 --- a/foundry.toml +++ b/foundry.toml @@ -3,7 +3,7 @@ src = 'src' test = 'tests' script = 'scripts' out = 'out' -solc = '0.8.22' +solc = '0.8.24' optimizer = true optimizer_runs = 200 libs = ['lib'] diff --git a/remappings.txt b/remappings.txt index f8dbf3a..25e78da 100644 --- a/remappings.txt +++ b/remappings.txt @@ -5,4 +5,4 @@ solidity-utils/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/lib/so lib/aave-helpers:aave-v3-origin/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/src aave-v3-origin/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/ aave-capo/=lib/aave-capo/src -lib/aave-capo:cl-synchronicity-price-adapter/=lib/aave-capo/lib/cl-synchronicity-price-adapter/src/ \ No newline at end of file +lib/aave-capo:cl-synchronicity-price-adapter/=lib/aave-capo/lib/cl-synchronicity-price-adapter/src/ diff --git a/scripts/RiskStewardsBase.s.sol b/scripts/RiskStewardsBase.s.sol index 9bc0c9b..e955168 100644 --- a/scripts/RiskStewardsBase.s.sol +++ b/scripts/RiskStewardsBase.s.sol @@ -95,26 +95,26 @@ abstract contract RiskStewardsBase is ProtocolV3TestBase { IRiskSteward.Config memory riskConfig = STEWARD.getRiskConfig(); if (capUpdates.length != 0) { - timelocks[index++] = riskConfig.supplyCap.minDelay; - timelocks[index++] = riskConfig.borrowCap.minDelay; + timelocks[index++] = riskConfig.capConfig.supplyCap.minDelay; + timelocks[index++] = riskConfig.capConfig.borrowCap.minDelay; } if (collateralUpdates.length != 0) { - timelocks[index++] = riskConfig.ltv.minDelay; - timelocks[index++] = riskConfig.liquidationThreshold.minDelay; - timelocks[index++] = riskConfig.liquidationBonus.minDelay; - timelocks[index++] = riskConfig.debtCeiling.minDelay; + timelocks[index++] = riskConfig.collateralConfig.ltv.minDelay; + timelocks[index++] = riskConfig.collateralConfig.liquidationThreshold.minDelay; + timelocks[index++] = riskConfig.collateralConfig.liquidationBonus.minDelay; + timelocks[index++] = riskConfig.collateralConfig.debtCeiling.minDelay; } if (rateUpdates.length != 0) { - timelocks[index++] = riskConfig.baseVariableBorrowRate.minDelay; - timelocks[index++] = riskConfig.optimalUsageRatio.minDelay; - timelocks[index++] = riskConfig.variableRateSlope1.minDelay; - timelocks[index++] = riskConfig.variableRateSlope2.minDelay; + timelocks[index++] = riskConfig.rateConfig.baseVariableBorrowRate.minDelay; + timelocks[index++] = riskConfig.rateConfig.optimalUsageRatio.minDelay; + timelocks[index++] = riskConfig.rateConfig.variableRateSlope1.minDelay; + timelocks[index++] = riskConfig.rateConfig.variableRateSlope2.minDelay; } if (lstPriceCapUpdates.length != 0) { - timelocks[index++] = riskConfig.priceCapLst.minDelay; + timelocks[index++] = riskConfig.priceCapConfig.priceCapLst.minDelay; } if (stablePriceCapUpdates.length != 0) { - timelocks[index++] = riskConfig.priceCapStable.minDelay; + timelocks[index++] = riskConfig.priceCapConfig.priceCapStable.minDelay; } uint40 maxTimelock = 0; for (uint256 i = 0; i < timelocks.length; i++) { diff --git a/scripts/deploy/DeployCapInjector.s.sol b/scripts/deploy/DeployCapInjector.s.sol index 5cbce81..ba05128 100644 --- a/scripts/deploy/DeployCapInjector.s.sol +++ b/scripts/deploy/DeployCapInjector.s.sol @@ -6,28 +6,27 @@ import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; import {AaveV3Arbitrum, AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; import {ICreate3Factory} from 'solidity-utils/contracts/create3/interfaces/ICreate3Factory.sol'; -import {IOwnable} from 'aave-address-book/common/IOwnable.sol'; -import {EdgeRiskStewardCaps, IRiskSteward, IPoolDataProvider, IEngine} from '../../src/contracts/EdgeRiskStewardCaps.sol'; +import {EdgeRiskStewardCaps, IRiskSteward} from '../../src/contracts/EdgeRiskStewardCaps.sol'; import {AaveStewardInjectorCaps} from '../../src/contracts/AaveStewardInjectorCaps.sol'; library DeployStewardContracts { address constant EDGE_RISK_ORACLE = 0x861eeAdB55E41f161F31Acb1BFD4c70E3a964Aed; function _deployRiskStewards( - address poolDataProvider, + address pool, address configEngine, address riskCouncil, address governance ) internal returns (address) { address riskSteward = address( new EdgeRiskStewardCaps( - IPoolDataProvider(poolDataProvider), - IEngine(configEngine), + pool, + configEngine, riskCouncil, + governance, _getRiskConfig() ) ); - IOwnable(riskSteward).transferOwnership(governance); return riskSteward; } @@ -53,27 +52,26 @@ library DeployStewardContracts { function _getRiskConfig() internal pure returns (IRiskSteward.Config memory) { return IRiskSteward.Config({ - ltv: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 25}), - liquidationThreshold: IRiskSteward.RiskParamConfig({ - minDelay: 3 days, - maxPercentChange: 25 + collateralConfig: IRiskSteward.CollateralConfig({ + ltv: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), + liquidationThreshold: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), + liquidationBonus: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), + debtCeiling: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00}) }), - liquidationBonus: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), - supplyCap: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 30_00}), - borrowCap: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 30_00}), - debtCeiling: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00}), - baseVariableBorrowRate: IRiskSteward.RiskParamConfig({ - minDelay: 3 days, - maxPercentChange: 50 + rateConfig: IRiskSteward.RateConfig({ + baseVariableBorrowRate: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 1_00}), + variableRateSlope1: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 1_00}), + variableRateSlope2: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00}), + optimalUsageRatio: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 3_00}) }), - variableRateSlope1: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), - variableRateSlope2: IRiskSteward.RiskParamConfig({ - minDelay: 3 days, - maxPercentChange: 5_00 + capConfig: IRiskSteward.CapConfig({ + supplyCap: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 30_00}), + borrowCap: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 30_00}) }), - optimalUsageRatio: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 3_00}), - priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 5_00}), - priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}) + priceCapConfig: IRiskSteward.PriceCapConfig({ + priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 5_00}), + priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}) + }) }); } } @@ -89,7 +87,7 @@ contract DeployArbitrum is ArbitrumScript { .predictAddress(msg.sender, salt); address riskSteward = DeployStewardContracts._deployRiskStewards( - address(AaveV3Arbitrum.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Arbitrum.POOL), AaveV3Arbitrum.CONFIG_ENGINE, predictedStewardsInjector, GovernanceV3Arbitrum.EXECUTOR_LVL_1 diff --git a/scripts/deploy/DeployRateInjector.s.sol b/scripts/deploy/DeployRateInjector.s.sol index 0fe52d1..93d0914 100644 --- a/scripts/deploy/DeployRateInjector.s.sol +++ b/scripts/deploy/DeployRateInjector.s.sol @@ -6,28 +6,27 @@ import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; import {AaveV3EthereumLido, AaveV3EthereumLidoAssets} from 'aave-address-book/AaveV3EthereumLido.sol'; import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; import {ICreate3Factory} from 'solidity-utils/contracts/create3/interfaces/ICreate3Factory.sol'; -import {IOwnable} from 'aave-address-book/common/IOwnable.sol'; -import {EdgeRiskStewardRates, IRiskSteward, IPoolDataProvider, IEngine} from '../../src/contracts/EdgeRiskStewardRates.sol'; +import {EdgeRiskStewardRates, IRiskSteward} from '../../src/contracts/EdgeRiskStewardRates.sol'; import {AaveStewardInjectorRates} from '../../src/contracts/AaveStewardInjectorRates.sol'; library DeployStewardContracts { address constant EDGE_RISK_ORACLE = 0x7ABB46C690C52E919687D19ebF89C81A6136C1F2; function _deployRiskStewards( - address poolDataProvider, + address pool, address configEngine, address riskCouncil, address governance ) internal returns (address) { address riskSteward = address( new EdgeRiskStewardRates( - IPoolDataProvider(poolDataProvider), - IEngine(configEngine), + pool, + configEngine, riskCouncil, + governance, _getRiskConfig() ) ); - IOwnable(riskSteward).transferOwnership(governance); return riskSteward; } @@ -51,27 +50,26 @@ library DeployStewardContracts { function _getRiskConfig() internal pure returns (IRiskSteward.Config memory) { return IRiskSteward.Config({ - ltv: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 25}), - liquidationThreshold: IRiskSteward.RiskParamConfig({ - minDelay: 1 days, - maxPercentChange: 25 + collateralConfig: IRiskSteward.CollateralConfig({ + ltv: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}), + liquidationThreshold: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}), + liquidationBonus: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}), + debtCeiling: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 20_00}) }), - liquidationBonus: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}), - supplyCap: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 100_00}), - borrowCap: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 100_00}), - debtCeiling: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 20_00}), - baseVariableBorrowRate: IRiskSteward.RiskParamConfig({ - minDelay: 1 days, - maxPercentChange: 50 + rateConfig: IRiskSteward.RateConfig({ + baseVariableBorrowRate: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}), + variableRateSlope1: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 1_00}), + variableRateSlope2: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 5_00}), + optimalUsageRatio: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 3_00}) }), - variableRateSlope1: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}), - variableRateSlope2: IRiskSteward.RiskParamConfig({ - minDelay: 1 days, - maxPercentChange: 5_00 + capConfig: IRiskSteward.CapConfig({ + supplyCap: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 100_00}), + borrowCap: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 100_00}) }), - optimalUsageRatio: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 3_00}), - priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 5_00}), - priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}) + priceCapConfig: IRiskSteward.PriceCapConfig({ + priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 5_00}), + priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}) + }) }); } } @@ -87,7 +85,7 @@ contract DeployEthereumLido is EthereumScript { .predictAddress(msg.sender, salt); address riskSteward = DeployStewardContracts._deployRiskStewards( - address(AaveV3EthereumLido.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3EthereumLido.POOL), AaveV3EthereumLido.CONFIG_ENGINE, predictedStewardsInjector, GovernanceV3Ethereum.EXECUTOR_LVL_1 diff --git a/scripts/deploy/DeployStewards.s.sol b/scripts/deploy/DeployStewards.s.sol index 69e66eb..a0a0bd4 100644 --- a/scripts/deploy/DeployStewards.s.sol +++ b/scripts/deploy/DeployStewards.s.sol @@ -30,52 +30,50 @@ import {AaveV3Sonic} from 'aave-address-book/AaveV3Sonic.sol'; import {GovernanceV3Sonic} from 'aave-address-book/GovernanceV3Sonic.sol'; import {AaveV3Celo} from 'aave-address-book/AaveV3Celo.sol'; import {GovernanceV3Celo} from 'aave-address-book/GovernanceV3Celo.sol'; -import {IOwnable} from 'aave-address-book/common/IOwnable.sol'; -import {RiskSteward, IRiskSteward, IPoolDataProvider, IEngine} from '../../src/contracts/RiskSteward.sol'; +import {RiskSteward, IRiskSteward} from '../../src/contracts/RiskSteward.sol'; library DeployRiskStewards { function _deployRiskStewards( - address poolDataProvider, + address pool, address configEngine, address riskCouncil, address governance ) internal returns (address) { address riskSteward = address( new RiskSteward( - IPoolDataProvider(poolDataProvider), - IEngine(configEngine), + pool, + configEngine, riskCouncil, + governance, _getRiskConfig() ) ); - IOwnable(riskSteward).transferOwnership(governance); return riskSteward; } function _getRiskConfig() internal pure returns (IRiskSteward.Config memory) { return IRiskSteward.Config({ - ltv: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 25}), - liquidationThreshold: IRiskSteward.RiskParamConfig({ - minDelay: 3 days, - maxPercentChange: 25 + collateralConfig: IRiskSteward.CollateralConfig({ + ltv: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), + liquidationThreshold: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), + liquidationBonus: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), + debtCeiling: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00}) }), - liquidationBonus: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), - supplyCap: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 100_00}), - borrowCap: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 100_00}), - debtCeiling: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00}), - baseVariableBorrowRate: IRiskSteward.RiskParamConfig({ - minDelay: 3 days, - maxPercentChange: 50 + rateConfig: IRiskSteward.RateConfig({ + baseVariableBorrowRate: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 1_00}), + variableRateSlope1: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 1_00}), + variableRateSlope2: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00}), + optimalUsageRatio: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 3_00}) }), - variableRateSlope1: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), - variableRateSlope2: IRiskSteward.RiskParamConfig({ - minDelay: 3 days, - maxPercentChange: 5_00 + capConfig: IRiskSteward.CapConfig({ + supplyCap: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 100_00}), + borrowCap: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 100_00}) }), - optimalUsageRatio: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 3_00}), - priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 5_00}), - priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}) + priceCapConfig: IRiskSteward.PriceCapConfig({ + priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 5_00}), + priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}) + }) }); } } @@ -85,7 +83,7 @@ contract DeployEthereum is EthereumScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Ethereum.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Ethereum.POOL), AaveV3Ethereum.CONFIG_ENGINE, 0x47c71dFEB55Ebaa431Ae3fbF99Ea50e0D3d30fA8, // eth-risk-council GovernanceV3Ethereum.EXECUTOR_LVL_1 @@ -99,7 +97,7 @@ contract DeployEthereumLido is EthereumScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3EthereumLido.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3EthereumLido.POOL), AaveV3EthereumLido.CONFIG_ENGINE, 0x47c71dFEB55Ebaa431Ae3fbF99Ea50e0D3d30fA8, // eth-risk-council GovernanceV3Ethereum.EXECUTOR_LVL_1 @@ -113,7 +111,7 @@ contract DeployEthereumEtherFi is EthereumScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3EthereumEtherFi.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3EthereumEtherFi.POOL), AaveV3EthereumEtherFi.CONFIG_ENGINE, 0x47c71dFEB55Ebaa431Ae3fbF99Ea50e0D3d30fA8, // eth-risk-council GovernanceV3Ethereum.EXECUTOR_LVL_1 @@ -127,7 +125,7 @@ contract DeployPolygon is PolygonScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Polygon.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Polygon.POOL), AaveV3Polygon.CONFIG_ENGINE, 0x2C40FB1ACe63084fc0bB95F83C31B5854C6C4cB5, // pol-risk-council GovernanceV3Polygon.EXECUTOR_LVL_1 @@ -141,7 +139,7 @@ contract DeployArbitrum is ArbitrumScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Arbitrum.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Arbitrum.POOL), AaveV3Arbitrum.CONFIG_ENGINE, 0x3Be327F22eB4BD8042e6944073b8826dCf357Aa2, // arb-risk-council GovernanceV3Arbitrum.EXECUTOR_LVL_1 @@ -155,7 +153,7 @@ contract DeployOptimism is OptimismScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Optimism.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Optimism.POOL), AaveV3Optimism.CONFIG_ENGINE, 0xCb86256A994f0c505c5e15c75BF85fdFEa0F2a56, // opt-risk-council GovernanceV3Optimism.EXECUTOR_LVL_1 @@ -169,7 +167,7 @@ contract DeployAvalanche is AvalancheScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Avalanche.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Avalanche.POOL), AaveV3Avalanche.CONFIG_ENGINE, 0xCa66149425E7DC8f81276F6D80C4b486B9503D1a, // ava-risk-council GovernanceV3Avalanche.EXECUTOR_LVL_1 @@ -183,7 +181,7 @@ contract DeployScroll is ScrollScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Scroll.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Scroll.POOL), AaveV3Scroll.CONFIG_ENGINE, 0x611439a74546888c3535B4dd119A5Cbb9f5332EA, // scroll-risk-council GovernanceV3Scroll.EXECUTOR_LVL_1 @@ -197,7 +195,7 @@ contract DeployGnosis is GnosisScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Gnosis.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Gnosis.POOL), AaveV3Gnosis.CONFIG_ENGINE, 0xF221B08dD10e0C68D74F035764931Baa3b030481, // gnosis-risk-council GovernanceV3Gnosis.EXECUTOR_LVL_1 @@ -211,7 +209,7 @@ contract DeployBNB is BNBScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3BNB.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3BNB.POOL), AaveV3BNB.CONFIG_ENGINE, 0x126dc589cc75f17385dD95516F3F1788d862E7bc, // bnb-risk-council GovernanceV3BNB.EXECUTOR_LVL_1 @@ -225,7 +223,7 @@ contract DeployBase is BaseScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Base.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Base.POOL), AaveV3Base.CONFIG_ENGINE, 0xfbeB4AcB31340bA4de9C87B11dfBf7e2bc8C0bF1, // base-risk-council GovernanceV3Base.EXECUTOR_LVL_1 @@ -239,7 +237,7 @@ contract DeployMetis is MetisScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Metis.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Metis.POOL), AaveV3Metis.CONFIG_ENGINE, 0x0f547846920C34E70FBE4F3d87E46452a3FeAFfa, // metis-risk-council GovernanceV3Metis.EXECUTOR_LVL_1 @@ -253,7 +251,7 @@ contract DeployLinea is LineaScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Linea.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Linea.POOL), AaveV3Linea.CONFIG_ENGINE, 0xF092A5aC5E284E7c433dAFE5b8B138bFcA53a4Ee, // linea-risk-council GovernanceV3Linea.EXECUTOR_LVL_1 @@ -267,7 +265,7 @@ contract DeploySonic is SonicScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Sonic.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Sonic.POOL), AaveV3Sonic.CONFIG_ENGINE, 0x1dE39A17a9Fa8c76899fff37488482EEb7835d04, // sonic-risk-council GovernanceV3Sonic.EXECUTOR_LVL_1 @@ -281,7 +279,7 @@ contract DeployCelo is SonicScript { function run() external { vm.startBroadcast(); DeployRiskStewards._deployRiskStewards( - address(AaveV3Celo.AAVE_PROTOCOL_DATA_PROVIDER), + address(AaveV3Celo.POOL), AaveV3Celo.CONFIG_ENGINE, 0xd85786B5FC61E2A0c0a3144a33A0fC70646a99f6, // celo-risk-council GovernanceV3Celo.EXECUTOR_LVL_1 diff --git a/src/contracts/EdgeRiskStewardCaps.sol b/src/contracts/EdgeRiskStewardCaps.sol index 9a17487..35c8e3a 100644 --- a/src/contracts/EdgeRiskStewardCaps.sol +++ b/src/contracts/EdgeRiskStewardCaps.sol @@ -11,17 +11,19 @@ import './RiskSteward.sol'; */ contract EdgeRiskStewardCaps is RiskSteward { /** - * @param poolDataProvider The pool data provider of the pool to be controlled by the steward + * @param pool the aave pool to be controlled by the steward * @param engine the config engine to be used by the steward * @param riskCouncil the safe address of the council being able to interact with the steward + * @param owner the owner of the risk steward being able to set configs and mark items as restricted * @param riskConfig the risk configuration to setup for each individual risk param */ constructor( - IPoolDataProvider poolDataProvider, - IEngine engine, + address pool, + address engine, address riskCouncil, + address owner, Config memory riskConfig - ) RiskSteward(poolDataProvider, engine, riskCouncil, riskConfig) {} + ) RiskSteward(pool, engine, riskCouncil, owner, riskConfig) {} /// @inheritdoc IRiskSteward function updateRates( diff --git a/src/contracts/EdgeRiskStewardRates.sol b/src/contracts/EdgeRiskStewardRates.sol index 924f220..d1a08e7 100644 --- a/src/contracts/EdgeRiskStewardRates.sol +++ b/src/contracts/EdgeRiskStewardRates.sol @@ -11,17 +11,19 @@ import './RiskSteward.sol'; */ contract EdgeRiskStewardRates is RiskSteward { /** - * @param poolDataProvider The pool data provider of the pool to be controlled by the steward + * @param pool the aave pool to be controlled by the steward * @param engine the config engine to be used by the steward * @param riskCouncil the safe address of the council being able to interact with the steward + * @param owner the owner of the risk steward being able to set configs and mark items as restricted * @param riskConfig the risk configuration to setup for each individual risk param */ constructor( - IPoolDataProvider poolDataProvider, - IEngine engine, + address pool, + address engine, address riskCouncil, + address owner, Config memory riskConfig - ) RiskSteward(poolDataProvider, engine, riskCouncil, riskConfig) {} + ) RiskSteward(pool, engine, riskCouncil, owner, riskConfig) {} /// @inheritdoc IRiskSteward function updateCaps(IEngine.CapsUpdate[] calldata) external virtual override onlyRiskCouncil { diff --git a/src/contracts/RiskSteward.sol b/src/contracts/RiskSteward.sol index 909e752..4e29693 100644 --- a/src/contracts/RiskSteward.sol +++ b/src/contracts/RiskSteward.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import {IPoolDataProvider} from 'aave-address-book/AaveV3.sol'; +import {ReserveConfiguration, DataTypes} from 'aave-v3-origin/src/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; +import {IPool} from 'aave-address-book/AaveV3.sol'; import {Address} from 'openzeppelin-contracts/contracts/utils/Address.sol'; import {SafeCast} from 'openzeppelin-contracts/contracts/utils/math/SafeCast.sol'; import {EngineFlags} from 'aave-v3-origin/src/contracts/extensions/v3-config-engine/EngineFlags.sol'; @@ -19,6 +20,7 @@ import {IPriceCapAdapterStable} from 'aave-capo/interfaces/IPriceCapAdapterStabl * This contract can update the following risk params: caps, ltv, liqThreshold, liqBonus, debtCeiling, interest rates params. */ contract RiskSteward is Ownable, IRiskSteward { + using ReserveConfiguration for DataTypes.ReserveConfigurationMap; using Address for address; using SafeCast for uint256; using SafeCast for int256; @@ -27,7 +29,7 @@ contract RiskSteward is Ownable, IRiskSteward { IEngine public immutable CONFIG_ENGINE; /// @inheritdoc IRiskSteward - IPoolDataProvider public immutable POOL_DATA_PROVIDER; + IPool public immutable POOL; /// @inheritdoc IRiskSteward address public immutable RISK_COUNCIL; @@ -36,7 +38,7 @@ contract RiskSteward is Ownable, IRiskSteward { Config internal _riskConfig; - mapping(address => Debounce) internal _timelocks; + mapping(bytes20 id => Debounce) internal _timelocks; mapping(address => bool) internal _restrictedAddresses; @@ -49,19 +51,21 @@ contract RiskSteward is Ownable, IRiskSteward { } /** - * @param poolDataProvider The pool data provider of the pool to be controlled by the steward + * @param pool The aave pool to be controlled by the steward * @param engine the config engine to be used by the steward * @param riskCouncil the safe address of the council being able to interact with the steward + * @param owner the owner of the risk steward being able to set configs and mark items as restricted * @param riskConfig the risk configuration to setup for each individual risk param */ constructor( - IPoolDataProvider poolDataProvider, - IEngine engine, + address pool, + address engine, address riskCouncil, + address owner, Config memory riskConfig - ) Ownable(msg.sender) { - POOL_DATA_PROVIDER = poolDataProvider; - CONFIG_ENGINE = engine; + ) Ownable(owner) { + POOL = IPool(pool); + CONFIG_ENGINE = IEngine(engine); RISK_COUNCIL = riskCouncil; _riskConfig = riskConfig; } @@ -106,7 +110,7 @@ contract RiskSteward is Ownable, IRiskSteward { /// @inheritdoc IRiskSteward function getTimelock(address asset) external view returns (Debounce memory) { - return _timelocks[asset]; + return _timelocks[bytes20(asset)]; } /// @inheritdoc IRiskSteward @@ -145,16 +149,14 @@ contract RiskSteward is Ownable, IRiskSteward { if (capsUpdate[i].supplyCap == 0 || capsUpdate[i].borrowCap == 0) revert InvalidUpdateToZero(); - (uint256 currentBorrowCap, uint256 currentSupplyCap) = POOL_DATA_PROVIDER.getReserveCaps( - capsUpdate[i].asset - ); + (uint256 currentBorrowCap, uint256 currentSupplyCap) = POOL.getConfiguration(asset).getCaps(); _validateParamUpdate( ParamUpdateValidationInput({ currentValue: currentSupplyCap, newValue: capsUpdate[i].supplyCap, - lastUpdated: _timelocks[asset].supplyCapLastUpdated, - riskConfig: _riskConfig.supplyCap, + lastUpdated: _timelocks[bytes20(asset)].supplyCapLastUpdated, + riskConfig: _riskConfig.capConfig.supplyCap, isChangeRelative: true }) ); @@ -162,8 +164,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentBorrowCap, newValue: capsUpdate[i].borrowCap, - lastUpdated: _timelocks[asset].borrowCapLastUpdated, - riskConfig: _riskConfig.borrowCap, + lastUpdated: _timelocks[bytes20(asset)].borrowCapLastUpdated, + riskConfig: _riskConfig.capConfig.borrowCap, isChangeRelative: true }) ); @@ -192,8 +194,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentOptimalUsageRatio, newValue: ratesUpdate[i].params.optimalUsageRatio, - lastUpdated: _timelocks[asset].optimalUsageRatioLastUpdated, - riskConfig: _riskConfig.optimalUsageRatio, + lastUpdated: _timelocks[bytes20(asset)].optimalUsageRatioLastUpdated, + riskConfig: _riskConfig.rateConfig.optimalUsageRatio, isChangeRelative: false }) ); @@ -201,8 +203,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentBaseVariableBorrowRate, newValue: ratesUpdate[i].params.baseVariableBorrowRate, - lastUpdated: _timelocks[asset].baseVariableRateLastUpdated, - riskConfig: _riskConfig.baseVariableBorrowRate, + lastUpdated: _timelocks[bytes20(asset)].baseVariableRateLastUpdated, + riskConfig: _riskConfig.rateConfig.baseVariableBorrowRate, isChangeRelative: false }) ); @@ -210,8 +212,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentVariableRateSlope1, newValue: ratesUpdate[i].params.variableRateSlope1, - lastUpdated: _timelocks[asset].variableRateSlope1LastUpdated, - riskConfig: _riskConfig.variableRateSlope1, + lastUpdated: _timelocks[bytes20(asset)].variableRateSlope1LastUpdated, + riskConfig: _riskConfig.rateConfig.variableRateSlope1, isChangeRelative: false }) ); @@ -219,8 +221,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentVariableRateSlope2, newValue: ratesUpdate[i].params.variableRateSlope2, - lastUpdated: _timelocks[asset].variableRateSlope2LastUpdated, - riskConfig: _riskConfig.variableRateSlope2, + lastUpdated: _timelocks[bytes20(asset)].variableRateSlope2LastUpdated, + riskConfig: _riskConfig.rateConfig.variableRateSlope2, isChangeRelative: false }) ); @@ -249,26 +251,21 @@ contract RiskSteward is Ownable, IRiskSteward { collateralUpdates[i].debtCeiling == 0 ) revert InvalidUpdateToZero(); + DataTypes.ReserveConfigurationMap memory configuration = POOL.getConfiguration(asset); ( - , uint256 currentLtv, uint256 currentLiquidationThreshold, uint256 currentLiquidationBonus, , - , - , - , - , - - ) = POOL_DATA_PROVIDER.getReserveConfigurationData(asset); - uint256 currentDebtCeiling = POOL_DATA_PROVIDER.getDebtCeiling(asset); + ) = configuration.getParams(); + uint256 currentDebtCeiling = configuration.getDebtCeiling(); _validateParamUpdate( ParamUpdateValidationInput({ currentValue: currentLtv, newValue: collateralUpdates[i].ltv, - lastUpdated: _timelocks[asset].ltvLastUpdated, - riskConfig: _riskConfig.ltv, + lastUpdated: _timelocks[bytes20(asset)].ltvLastUpdated, + riskConfig: _riskConfig.collateralConfig.ltv, isChangeRelative: false }) ); @@ -276,8 +273,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentLiquidationThreshold, newValue: collateralUpdates[i].liqThreshold, - lastUpdated: _timelocks[asset].liquidationThresholdLastUpdated, - riskConfig: _riskConfig.liquidationThreshold, + lastUpdated: _timelocks[bytes20(asset)].liquidationThresholdLastUpdated, + riskConfig: _riskConfig.collateralConfig.liquidationThreshold, isChangeRelative: false }) ); @@ -285,8 +282,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentLiquidationBonus - 100_00, // as the definition is 100% + x%, and config engine takes into account x% for simplicity. newValue: collateralUpdates[i].liqBonus, - lastUpdated: _timelocks[asset].liquidationBonusLastUpdated, - riskConfig: _riskConfig.liquidationBonus, + lastUpdated: _timelocks[bytes20(asset)].liquidationBonusLastUpdated, + riskConfig: _riskConfig.collateralConfig.liquidationBonus, isChangeRelative: false }) ); @@ -294,8 +291,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentDebtCeiling / 100, // as the definition is with 2 decimals, and config engine does not take the decimals into account. newValue: collateralUpdates[i].debtCeiling, - lastUpdated: _timelocks[asset].debtCeilingLastUpdated, - riskConfig: _riskConfig.debtCeiling, + lastUpdated: _timelocks[bytes20(asset)].debtCeilingLastUpdated, + riskConfig: _riskConfig.collateralConfig.debtCeiling, isChangeRelative: true }) ); @@ -332,8 +329,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentMaxYearlyGrowthPercent, newValue: priceCapsUpdate[i].priceCapUpdateParams.maxYearlyRatioGrowthPercent, - lastUpdated: _timelocks[oracle].priceCapLastUpdated, - riskConfig: _riskConfig.priceCapLst, + lastUpdated: _timelocks[bytes20(oracle)].priceCapLastUpdated, + riskConfig: _riskConfig.priceCapConfig.priceCapLst, isChangeRelative: true }) ); @@ -362,8 +359,8 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentPriceCap.toUint256(), newValue: priceCapsUpdate[i].priceCap, - lastUpdated: _timelocks[oracle].priceCapLastUpdated, - riskConfig: _riskConfig.priceCapStable, + lastUpdated: _timelocks[bytes20(oracle)].priceCapLastUpdated, + riskConfig: _riskConfig.priceCapConfig.priceCapStable, isChangeRelative: true }) ); @@ -398,11 +395,11 @@ contract RiskSteward is Ownable, IRiskSteward { address asset = capsUpdate[i].asset; if (capsUpdate[i].supplyCap != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].supplyCapLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].supplyCapLastUpdated = uint40(block.timestamp); } if (capsUpdate[i].borrowCap != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].borrowCapLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].borrowCapLastUpdated = uint40(block.timestamp); } } @@ -420,19 +417,19 @@ contract RiskSteward is Ownable, IRiskSteward { address asset = ratesUpdate[i].asset; if (ratesUpdate[i].params.optimalUsageRatio != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].optimalUsageRatioLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].optimalUsageRatioLastUpdated = uint40(block.timestamp); } if (ratesUpdate[i].params.baseVariableBorrowRate != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].baseVariableRateLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].baseVariableRateLastUpdated = uint40(block.timestamp); } if (ratesUpdate[i].params.variableRateSlope1 != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].variableRateSlope1LastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].variableRateSlope1LastUpdated = uint40(block.timestamp); } if (ratesUpdate[i].params.variableRateSlope2 != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].variableRateSlope2LastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].variableRateSlope2LastUpdated = uint40(block.timestamp); } } @@ -450,19 +447,19 @@ contract RiskSteward is Ownable, IRiskSteward { address asset = collateralUpdates[i].asset; if (collateralUpdates[i].ltv != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].ltvLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].ltvLastUpdated = uint40(block.timestamp); } if (collateralUpdates[i].liqThreshold != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].liquidationThresholdLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].liquidationThresholdLastUpdated = uint40(block.timestamp); } if (collateralUpdates[i].liqBonus != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].liquidationBonusLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].liquidationBonusLastUpdated = uint40(block.timestamp); } if (collateralUpdates[i].debtCeiling != EngineFlags.KEEP_CURRENT) { - _timelocks[asset].debtCeilingLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(asset)].debtCeilingLastUpdated = uint40(block.timestamp); } } @@ -479,7 +476,7 @@ contract RiskSteward is Ownable, IRiskSteward { for (uint256 i = 0; i < priceCapsUpdate.length; i++) { address oracle = priceCapsUpdate[i].oracle; - _timelocks[oracle].priceCapLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(oracle)].priceCapLastUpdated = uint40(block.timestamp); IPriceCapAdapter(oracle).setCapParameters(priceCapsUpdate[i].priceCapUpdateParams); @@ -495,7 +492,7 @@ contract RiskSteward is Ownable, IRiskSteward { for (uint256 i = 0; i < priceCapsUpdate.length; i++) { address oracle = priceCapsUpdate[i].oracle; - _timelocks[oracle].priceCapLastUpdated = uint40(block.timestamp); + _timelocks[bytes20(oracle)].priceCapLastUpdated = uint40(block.timestamp); IPriceCapAdapterStable(oracle).setPriceCap(priceCapsUpdate[i].priceCap.toInt256()); } @@ -521,7 +518,7 @@ contract RiskSteward is Ownable, IRiskSteward { uint256 variableRateSlope2 ) { - address rateStrategyAddress = POOL_DATA_PROVIDER.getInterestRateStrategyAddress(asset); + address rateStrategyAddress = POOL.getReserveData(asset).interestRateStrategyAddress; IDefaultInterestRateStrategyV2.InterestRateData memory interestRateData = IDefaultInterestRateStrategyV2(rateStrategyAddress) .getInterestRateDataBps(asset); diff --git a/src/interfaces/IRiskSteward.sol b/src/interfaces/IRiskSteward.sol index d233e3b..447c327 100644 --- a/src/interfaces/IRiskSteward.sol +++ b/src/interfaces/IRiskSteward.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {IPoolDataProvider} from 'aave-address-book/AaveV3.sol'; +import {IPool} from 'aave-address-book/AaveV3.sol'; import {IAaveV3ConfigEngine as IEngine} from 'aave-v3-origin/src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol'; import {IPriceCapAdapter} from 'aave-capo/interfaces/IPriceCapAdapter.sol'; @@ -78,17 +78,17 @@ interface IRiskSteward { * @notice Struct storing the last update by the steward of each risk param */ struct Debounce { - uint40 supplyCapLastUpdated; - uint40 borrowCapLastUpdated; uint40 ltvLastUpdated; uint40 liquidationBonusLastUpdated; uint40 liquidationThresholdLastUpdated; - uint40 debtCeilingLastUpdated; + uint40 optimalUsageRatioLastUpdated; uint40 baseVariableRateLastUpdated; uint40 variableRateSlope1LastUpdated; uint40 variableRateSlope2LastUpdated; - uint40 optimalUsageRatioLastUpdated; + uint40 debtCeilingLastUpdated; uint40 priceCapLastUpdated; + uint40 supplyCapLastUpdated; + uint40 borrowCapLastUpdated; } /** @@ -119,16 +119,44 @@ interface IRiskSteward { * @notice Struct storing the risk configuration for all the risk param */ struct Config { + CollateralConfig collateralConfig; + RateConfig rateConfig; + CapConfig capConfig; + PriceCapConfig priceCapConfig; + } + + /** + * @notice Struct storing the risk configuration for collateral side param + */ + struct CollateralConfig { RiskParamConfig ltv; RiskParamConfig liquidationThreshold; RiskParamConfig liquidationBonus; - RiskParamConfig supplyCap; - RiskParamConfig borrowCap; RiskParamConfig debtCeiling; + } + + /** + * @notice Struct storing the risk configuration for rate param + */ + struct RateConfig { RiskParamConfig baseVariableBorrowRate; RiskParamConfig variableRateSlope1; RiskParamConfig variableRateSlope2; RiskParamConfig optimalUsageRatio; + } + + /** + * @notice Struct storing the risk configuration for cap param + */ + struct CapConfig { + RiskParamConfig supplyCap; + RiskParamConfig borrowCap; + } + + /** + * @notice Struct storing the risk configuration for price cap param + */ + struct PriceCapConfig { RiskParamConfig priceCapLst; RiskParamConfig priceCapStable; } @@ -155,9 +183,9 @@ interface IRiskSteward { function CONFIG_ENGINE() external view returns (IEngine); /** - * @notice The pool data provider of the POOL the steward controls + * @notice The aave pool of the instance steward controls */ - function POOL_DATA_PROVIDER() external view returns (IPoolDataProvider); + function POOL() external view returns (IPool); /** * @notice The safe controlling the steward @@ -221,7 +249,8 @@ interface IRiskSteward { /** * @notice Returns the timelock for a specific asset i.e the last updated timestamp * @param asset for which to fetch the timelock - * @return struct containing the latest updated timestamps of all the risk params by the steward + * @return struct containing the latest updated timestamps of all the risk params by the steward except eMode + * @dev the emode timelock params of the struct returned will be unused */ function getTimelock(address asset) external view returns (Debounce memory); diff --git a/tests/AaveStewardsInjectorCaps.t.sol b/tests/AaveStewardsInjectorCaps.t.sol index a2a273b..6ec912e 100644 --- a/tests/AaveStewardsInjectorCaps.t.sol +++ b/tests/AaveStewardsInjectorCaps.t.sol @@ -18,20 +18,9 @@ contract AaveStewardsInjectorCaps_Test is AaveStewardsInjectorBaseTest { minDelay: 3 days, maxPercentChange: 100_00 }); - IRiskSteward.Config memory riskConfig = IRiskSteward.Config({ - ltv: defaultRiskParamConfig, - liquidationThreshold: defaultRiskParamConfig, - liquidationBonus: defaultRiskParamConfig, - supplyCap: defaultRiskParamConfig, - borrowCap: defaultRiskParamConfig, - debtCeiling: defaultRiskParamConfig, - baseVariableBorrowRate: defaultRiskParamConfig, - variableRateSlope1: defaultRiskParamConfig, - variableRateSlope2: defaultRiskParamConfig, - optimalUsageRatio: defaultRiskParamConfig, - priceCapLst: defaultRiskParamConfig, - priceCapStable: defaultRiskParamConfig - }); + IRiskSteward.Config memory riskConfig; + riskConfig.capConfig.supplyCap = defaultRiskParamConfig; + riskConfig.capConfig.borrowCap = defaultRiskParamConfig; // setup risk oracle vm.startPrank(_riskOracleOwner); @@ -61,9 +50,10 @@ contract AaveStewardsInjectorCaps_Test is AaveStewardsInjectorBaseTest { // setup risk steward _riskSteward = new RiskSteward( - contracts.protocolDataProvider, - IEngine(report.configEngine), + address(contracts.poolProxy), + report.configEngine, address(_stewardInjector), + address(this), riskConfig ); vm.assertEq(computedRiskStewardAddress, address(_riskSteward)); diff --git a/tests/AaveStewardsInjectorRates.t.sol b/tests/AaveStewardsInjectorRates.t.sol index dd6e921..e935e7e 100644 --- a/tests/AaveStewardsInjectorRates.t.sol +++ b/tests/AaveStewardsInjectorRates.t.sol @@ -12,20 +12,11 @@ contract AaveStewardsInjectorRates_Test is AaveStewardsInjectorBaseTest { minDelay: 3 days, maxPercentChange: 5_00 // 5% }); - IRiskSteward.Config memory riskConfig = IRiskSteward.Config({ - ltv: defaultRiskParamConfig, - liquidationThreshold: defaultRiskParamConfig, - liquidationBonus: defaultRiskParamConfig, - supplyCap: defaultRiskParamConfig, - borrowCap: defaultRiskParamConfig, - debtCeiling: defaultRiskParamConfig, - baseVariableBorrowRate: defaultRiskParamConfig, - variableRateSlope1: defaultRiskParamConfig, - variableRateSlope2: defaultRiskParamConfig, - optimalUsageRatio: defaultRiskParamConfig, - priceCapLst: defaultRiskParamConfig, - priceCapStable: defaultRiskParamConfig - }); + IRiskSteward.Config memory riskConfig; + riskConfig.rateConfig.baseVariableBorrowRate = defaultRiskParamConfig; + riskConfig.rateConfig.variableRateSlope1 = defaultRiskParamConfig; + riskConfig.rateConfig.variableRateSlope2 = defaultRiskParamConfig; + riskConfig.rateConfig.optimalUsageRatio = defaultRiskParamConfig; // setup risk oracle vm.startPrank(_riskOracleOwner); @@ -54,9 +45,10 @@ contract AaveStewardsInjectorRates_Test is AaveStewardsInjectorBaseTest { // setup risk steward _riskSteward = new RiskSteward( - contracts.protocolDataProvider, - IEngine(report.configEngine), + address(contracts.poolProxy), + report.configEngine, address(_stewardInjector), + address(this), riskConfig ); diff --git a/tests/EdgeRiskStewardCaps.t.sol b/tests/EdgeRiskStewardCaps.t.sol index 52458be..818a6e7 100644 --- a/tests/EdgeRiskStewardCaps.t.sol +++ b/tests/EdgeRiskStewardCaps.t.sol @@ -9,37 +9,22 @@ contract EdgeRiskStewardCaps_Test is RiskSteward_Test { function setUp() public override { super.setUp(); - vm.startPrank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward = new EdgeRiskStewardCaps( - AaveV3Ethereum.AAVE_PROTOCOL_DATA_PROVIDER, - IEngine(configEngine), + address(AaveV3Ethereum.POOL), + AaveV3Ethereum.CONFIG_ENGINE, riskCouncil, + GovernanceV3Ethereum.EXECUTOR_LVL_1, riskConfig ); + + vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); AaveV3Ethereum.ACL_MANAGER.addRiskAdmin(address(steward)); - vm.stopPrank(); } /* ----------------------------- Rates Tests ----------------------------- */ function test_updateRates() public override { - ( - uint256 beforeOptimalUsageRatio, - uint256 beforeBaseVariableBorrowRate, - uint256 beforeVariableRateSlope1, - uint256 beforeVariableRateSlope2 - ) = _getInterestRatesForAsset(AaveV3EthereumAssets.WETH_UNDERLYING); - IEngine.RateStrategyUpdate[] memory rateUpdates = new IEngine.RateStrategyUpdate[](1); - rateUpdates[0] = IEngine.RateStrategyUpdate({ - asset: AaveV3EthereumAssets.WETH_UNDERLYING, - params: IEngine.InterestRateInputData({ - optimalUsageRatio: beforeOptimalUsageRatio + 5_00, // 5% absolute increase - baseVariableBorrowRate: beforeBaseVariableBorrowRate + 10_00, // 10% absolute increase - variableRateSlope1: beforeVariableRateSlope1 + 10_00, // 10% absolute increase - variableRateSlope2: beforeVariableRateSlope2 + 10_00 // 10% absolute increase - }) - }); vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); @@ -61,24 +46,7 @@ contract EdgeRiskStewardCaps_Test is RiskSteward_Test { /* ----------------------------- Collateral Tests ----------------------------- */ function test_updateCollateralSide() public override { - (, uint256 ltvBefore, uint256 ltBefore, uint256 lbBefore, , , , , , ) = AaveV3Ethereum - .AAVE_PROTOCOL_DATA_PROVIDER - .getReserveConfigurationData(AaveV3EthereumAssets.UNI_UNDERLYING); - - // as the definition is with 2 decimals, and config engine does not take the decimals into account, so we divide by 100. - uint256 debtCeilingBefore = AaveV3Ethereum.AAVE_PROTOCOL_DATA_PROVIDER.getDebtCeiling( - AaveV3EthereumAssets.UNI_UNDERLYING - ) / 100; - IEngine.CollateralUpdate[] memory collateralUpdates = new IEngine.CollateralUpdate[](1); - collateralUpdates[0] = IEngine.CollateralUpdate({ - asset: AaveV3EthereumAssets.UNI_UNDERLYING, - ltv: ltvBefore + 10_00, // 10% absolute increase - liqThreshold: ltBefore + 5_00, // 5% absolute increase - liqBonus: (lbBefore - 100_00) + 2_00, // 2% absolute increase - debtCeiling: (debtCeilingBefore * 110) / 100, // 10% relative increase - liqProtocolFee: EngineFlags.KEEP_CURRENT - }); vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); @@ -107,14 +75,6 @@ contract EdgeRiskStewardCaps_Test is RiskSteward_Test { IRiskSteward.PriceCapLstUpdate[] memory priceCapUpdates = new IRiskSteward.PriceCapLstUpdate[]( 1 ); - priceCapUpdates[0] = IRiskSteward.PriceCapLstUpdate({ - oracle: AaveV3EthereumAssets.wstETH_ORACLE, - priceCapUpdateParams: IPriceCapAdapter.PriceCapUpdateParams({ - snapshotTimestamp: uint48(block.timestamp - 2), - snapshotRatio: 1.1e18, - maxYearlyRatioGrowthPercent: 9_68 - }) - }); vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); @@ -127,11 +87,6 @@ contract EdgeRiskStewardCaps_Test is RiskSteward_Test { IRiskSteward.PriceCapStableUpdate[] memory priceCapUpdates = new IRiskSteward.PriceCapStableUpdate[](1); - priceCapUpdates[0] = IRiskSteward.PriceCapStableUpdate({ - oracle: AaveV3EthereumAssets.USDT_ORACLE, - priceCap: 1060000 - }); - vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); steward.updateStablePriceCaps(priceCapUpdates); diff --git a/tests/EdgeRiskStewardRates.t.sol b/tests/EdgeRiskStewardRates.t.sol index dc69453..e470fb1 100644 --- a/tests/EdgeRiskStewardRates.t.sol +++ b/tests/EdgeRiskStewardRates.t.sol @@ -9,30 +9,22 @@ contract EdgeRiskStewardRates_Test is RiskSteward_Test { function setUp() public override { super.setUp(); - vm.startPrank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward = new EdgeRiskStewardRates( - AaveV3Ethereum.AAVE_PROTOCOL_DATA_PROVIDER, - IEngine(configEngine), + address(AaveV3Ethereum.POOL), + AaveV3Ethereum.CONFIG_ENGINE, riskCouncil, + GovernanceV3Ethereum.EXECUTOR_LVL_1, riskConfig ); + + vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); AaveV3Ethereum.ACL_MANAGER.addRiskAdmin(address(steward)); - vm.stopPrank(); } /* ----------------------------- Caps Tests ----------------------------- */ function test_updateCaps() public override { - (uint256 daiBorrowCapBefore, uint256 daiSupplyCapBefore) = AaveV3Ethereum - .AAVE_PROTOCOL_DATA_PROVIDER - .getReserveCaps(AaveV3EthereumAssets.DAI_UNDERLYING); - IEngine.CapsUpdate[] memory capUpdates = new IEngine.CapsUpdate[](1); - capUpdates[0] = IEngine.CapsUpdate( - AaveV3EthereumAssets.DAI_UNDERLYING, - (daiSupplyCapBefore * 110) / 100, // 10% relative increase - (daiBorrowCapBefore * 110) / 100 // 10% relative increase - ); vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); @@ -56,24 +48,7 @@ contract EdgeRiskStewardRates_Test is RiskSteward_Test { /* ----------------------------- Collateral Tests ----------------------------- */ function test_updateCollateralSide() public override { - (, uint256 ltvBefore, uint256 ltBefore, uint256 lbBefore, , , , , , ) = AaveV3Ethereum - .AAVE_PROTOCOL_DATA_PROVIDER - .getReserveConfigurationData(AaveV3EthereumAssets.UNI_UNDERLYING); - - // as the definition is with 2 decimals, and config engine does not take the decimals into account, so we divide by 100. - uint256 debtCeilingBefore = AaveV3Ethereum.AAVE_PROTOCOL_DATA_PROVIDER.getDebtCeiling( - AaveV3EthereumAssets.UNI_UNDERLYING - ) / 100; - IEngine.CollateralUpdate[] memory collateralUpdates = new IEngine.CollateralUpdate[](1); - collateralUpdates[0] = IEngine.CollateralUpdate({ - asset: AaveV3EthereumAssets.UNI_UNDERLYING, - ltv: ltvBefore + 10_00, // 10% absolute increase - liqThreshold: ltBefore + 5_00, // 5% absolute increase - liqBonus: (lbBefore - 100_00) + 2_00, // 2% absolute increase - debtCeiling: (debtCeilingBefore * 110) / 100, // 10% relative increase - liqProtocolFee: EngineFlags.KEEP_CURRENT - }); vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); @@ -102,14 +77,6 @@ contract EdgeRiskStewardRates_Test is RiskSteward_Test { IRiskSteward.PriceCapLstUpdate[] memory priceCapUpdates = new IRiskSteward.PriceCapLstUpdate[]( 1 ); - priceCapUpdates[0] = IRiskSteward.PriceCapLstUpdate({ - oracle: AaveV3EthereumAssets.wstETH_ORACLE, - priceCapUpdateParams: IPriceCapAdapter.PriceCapUpdateParams({ - snapshotTimestamp: uint48(block.timestamp - 2), - snapshotRatio: 1.1e18, - maxYearlyRatioGrowthPercent: 9_68 - }) - }); vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); @@ -122,11 +89,6 @@ contract EdgeRiskStewardRates_Test is RiskSteward_Test { IRiskSteward.PriceCapStableUpdate[] memory priceCapUpdates = new IRiskSteward.PriceCapStableUpdate[](1); - priceCapUpdates[0] = IRiskSteward.PriceCapStableUpdate({ - oracle: AaveV3EthereumAssets.USDT_ORACLE, - priceCap: 1060000 - }); - vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); steward.updateStablePriceCaps(priceCapUpdates); diff --git a/tests/RiskSteward.t.sol b/tests/RiskSteward.t.sol index 5994c16..c44051a 100644 --- a/tests/RiskSteward.t.sol +++ b/tests/RiskSteward.t.sol @@ -2,7 +2,8 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; -import {IACLManager, IPoolConfigurator, IPoolDataProvider} from 'aave-address-book/AaveV3.sol'; +import {ReserveConfiguration, DataTypes} from 'aave-v3-origin/src/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; +import {IACLManager, IPoolConfigurator} from 'aave-address-book/AaveV3.sol'; import {IDefaultInterestRateStrategyV2} from 'aave-v3-origin/src/contracts/interfaces/IDefaultInterestRateStrategyV2.sol'; import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; @@ -11,56 +12,30 @@ import {IAaveV3ConfigEngine as IEngine} from 'aave-v3-origin/src/contracts/exten import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; import {ConfigEngineDeployer} from './utils/ConfigEngineDeployer.sol'; import {Ownable} from 'openzeppelin-contracts/contracts/access/Ownable.sol'; +import {DeployRiskStewards} from '../scripts/deploy/DeployStewards.s.sol'; contract RiskSteward_Test is Test { + using ReserveConfiguration for DataTypes.ReserveConfigurationMap; + address public constant riskCouncil = address(42); IRiskSteward public steward; - address public configEngine; - IRiskSteward.RiskParamConfig public defaultRiskParamConfig; IRiskSteward.Config public riskConfig; - event AddressRestricted(address indexed contractAddress, bool indexed isRestricted); - - event RiskConfigSet(IRiskSteward.Config indexed riskConfig); - function setUp() public virtual { vm.createSelectFork(vm.rpcUrl('mainnet'), 21974363); - configEngine = AaveV3Ethereum.CONFIG_ENGINE; + riskConfig = DeployRiskStewards._getRiskConfig(); - defaultRiskParamConfig = IRiskSteward.RiskParamConfig({ - minDelay: 5 days, - maxPercentChange: 10_00 // 10% - }); - IRiskSteward.RiskParamConfig memory liquidationBonusParamConfig = IRiskSteward.RiskParamConfig({ - minDelay: 5 days, - maxPercentChange: 2_00 // 2% - }); - - riskConfig = IRiskSteward.Config({ - ltv: defaultRiskParamConfig, - liquidationThreshold: defaultRiskParamConfig, - liquidationBonus: liquidationBonusParamConfig, - supplyCap: defaultRiskParamConfig, - borrowCap: defaultRiskParamConfig, - debtCeiling: defaultRiskParamConfig, - baseVariableBorrowRate: defaultRiskParamConfig, - variableRateSlope1: defaultRiskParamConfig, - variableRateSlope2: defaultRiskParamConfig, - optimalUsageRatio: defaultRiskParamConfig, - priceCapLst: defaultRiskParamConfig, - priceCapStable: defaultRiskParamConfig - }); - - vm.startPrank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward = new RiskSteward( - AaveV3Ethereum.AAVE_PROTOCOL_DATA_PROVIDER, - IEngine(configEngine), + address(AaveV3Ethereum.POOL), + AaveV3Ethereum.CONFIG_ENGINE, riskCouncil, + GovernanceV3Ethereum.EXECUTOR_LVL_1, riskConfig ); + + vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); AaveV3Ethereum.ACL_MANAGER.addRiskAdmin(address(steward)); - vm.stopPrank(); } /* ----------------------------- Caps Tests ----------------------------- */ @@ -93,7 +68,7 @@ contract RiskSteward_Test is Test { assertEq(lastUpdated.borrowCapLastUpdated, block.timestamp); // after min time passed test caps decrease - vm.warp(block.timestamp + 5 days + 1); + vm.warp(block.timestamp + 3 days + 1); (daiBorrowCapBefore, daiSupplyCapBefore) = AaveV3Ethereum .AAVE_PROTOCOL_DATA_PROVIDER .getReserveCaps(AaveV3EthereumAssets.DAI_UNDERLYING); @@ -122,19 +97,31 @@ contract RiskSteward_Test is Test { IEngine.CapsUpdate[] memory capUpdates = new IEngine.CapsUpdate[](1); capUpdates[0] = IEngine.CapsUpdate( AaveV3EthereumAssets.DAI_UNDERLYING, - (daiSupplyCapBefore * 120) / 100, // 20% relative increase (current maxChangePercent configured is 10%) - (daiBorrowCapBefore * 120) / 100 // 20% relative increase + (daiSupplyCapBefore * 210) / 100, // 110% relative increase (current maxChangePercent configured is 100%) + (daiBorrowCapBefore * 210) / 100 // 110% relative increase ); - vm.startPrank(riskCouncil); + vm.prank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotInRange.selector); steward.updateCaps(capUpdates); + IRiskSteward.RiskParamConfig memory newConfig = IRiskSteward.RiskParamConfig({ + minDelay: 3 days, + maxPercentChange: 10_00 + }); + IRiskSteward.Config memory config = riskConfig; + config.capConfig.supplyCap = newConfig; + config.capConfig.borrowCap = newConfig; + + vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); + steward.setRiskConfig(config); + capUpdates[0] = IEngine.CapsUpdate( AaveV3EthereumAssets.DAI_UNDERLYING, (daiSupplyCapBefore * 80) / 100, // 20% relative decrease (daiBorrowCapBefore * 80) / 100 // 20% relative decrease ); + vm.prank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotInRange.selector); steward.updateCaps(capUpdates); @@ -248,12 +235,12 @@ contract RiskSteward_Test is Test { function test_updateCaps_toValueZeroNotAllowed() public virtual { // set risk config to allow 100% cap change to 0 IRiskSteward.RiskParamConfig memory capsParamConfig = IRiskSteward.RiskParamConfig({ - minDelay: 5 days, + minDelay: 3 days, maxPercentChange: 100_00 // 100% relative change }); - riskConfig.supplyCap = capsParamConfig; - riskConfig.borrowCap = capsParamConfig; + riskConfig.capConfig.supplyCap = capsParamConfig; + riskConfig.capConfig.borrowCap = capsParamConfig; vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward.setRiskConfig(riskConfig); @@ -284,10 +271,10 @@ contract RiskSteward_Test is Test { rateUpdates[0] = IEngine.RateStrategyUpdate({ asset: AaveV3EthereumAssets.WETH_UNDERLYING, params: IEngine.InterestRateInputData({ - optimalUsageRatio: beforeOptimalUsageRatio + 5_00, // 5% absolute increase - baseVariableBorrowRate: beforeBaseVariableBorrowRate + 10_00, // 10% absolute increase - variableRateSlope1: beforeVariableRateSlope1 + 10_00, // 10% absolute increase - variableRateSlope2: beforeVariableRateSlope2 + 10_00 // 10% absolute increase + optimalUsageRatio: beforeOptimalUsageRatio + 3_00, // 3% absolute increase + baseVariableBorrowRate: beforeBaseVariableBorrowRate + 1_00, // 1% absolute increase + variableRateSlope1: beforeVariableRateSlope1 + 1_00, // 1% absolute increase + variableRateSlope2: beforeVariableRateSlope2 + 20_00 // 20% absolute increase }) }); @@ -315,7 +302,7 @@ contract RiskSteward_Test is Test { assertEq(lastUpdated.variableRateSlope2LastUpdated, block.timestamp); // after min time passed test rates decrease - vm.warp(block.timestamp + 5 days + 1); + vm.warp(block.timestamp + 3 days + 1); ( beforeOptimalUsageRatio, @@ -327,10 +314,10 @@ contract RiskSteward_Test is Test { rateUpdates[0] = IEngine.RateStrategyUpdate({ asset: AaveV3EthereumAssets.WETH_UNDERLYING, params: IEngine.InterestRateInputData({ - optimalUsageRatio: beforeOptimalUsageRatio - 10_00, // 10% decrease + optimalUsageRatio: beforeOptimalUsageRatio - 3_00, // 3% decrease baseVariableBorrowRate: beforeBaseVariableBorrowRate - 1_00, // 1% decrease variableRateSlope1: beforeVariableRateSlope1 - 1_00, // 1% decrease - variableRateSlope2: beforeVariableRateSlope2 - 10_00 // 10% absolute decrease + variableRateSlope2: beforeVariableRateSlope2 - 20_00 // 20% absolute decrease }) }); steward.updateRates(rateUpdates); @@ -392,10 +379,10 @@ contract RiskSteward_Test is Test { rateUpdates[0] = IEngine.RateStrategyUpdate({ asset: AaveV3EthereumAssets.WETH_UNDERLYING, params: IEngine.InterestRateInputData({ - optimalUsageRatio: beforeOptimalUsageRatio + 5_00, // 5% absolute increase - baseVariableBorrowRate: beforeBaseVariableBorrowRate + 10_00, // 10% absolute increase - variableRateSlope1: beforeVariableRateSlope1 + 10_00, // 10% absolute increase - variableRateSlope2: beforeVariableRateSlope2 + 10_00 // 10% absolute increase + optimalUsageRatio: beforeOptimalUsageRatio + 3_00, // 3% absolute increase + baseVariableBorrowRate: beforeBaseVariableBorrowRate + 1_00, // 1% absolute increase + variableRateSlope1: beforeVariableRateSlope1 + 1_00, // 1% absolute increase + variableRateSlope2: beforeVariableRateSlope2 + 20_00 // 20% absolute increase }) }); @@ -548,10 +535,10 @@ contract RiskSteward_Test is Test { IEngine.CollateralUpdate[] memory collateralUpdates = new IEngine.CollateralUpdate[](1); collateralUpdates[0] = IEngine.CollateralUpdate({ asset: AaveV3EthereumAssets.UNI_UNDERLYING, - ltv: ltvBefore + 10_00, // 10% absolute increase - liqThreshold: ltBefore + 5_00, // 5% absolute increase - liqBonus: (lbBefore - 100_00) + 2_00, // 2% absolute increase - debtCeiling: (debtCeilingBefore * 110) / 100, // 10% relative increase + ltv: ltvBefore + 50, // 0.5% absolute increase + liqThreshold: ltBefore + 50, // 0.5% absolute increase + liqBonus: (lbBefore - 100_00) + 50, // 0.5% absolute increase + debtCeiling: (debtCeilingBefore * 120) / 100, // 20% relative increase liqProtocolFee: EngineFlags.KEEP_CURRENT }); @@ -581,7 +568,7 @@ contract RiskSteward_Test is Test { assertEq(lastUpdated.debtCeilingLastUpdated, block.timestamp); // after min time passed test collateral update decrease - vm.warp(block.timestamp + 5 days + 1); + vm.warp(block.timestamp + 3 days + 1); (, ltvBefore, ltBefore, lbBefore, , , , , , ) = AaveV3Ethereum .AAVE_PROTOCOL_DATA_PROVIDER @@ -595,10 +582,10 @@ contract RiskSteward_Test is Test { collateralUpdates[0] = IEngine.CollateralUpdate({ asset: AaveV3EthereumAssets.UNI_UNDERLYING, - ltv: ltvBefore - 10_00, // 10% absolute decrease - liqThreshold: ltBefore - 10_00, // 10% absolute decrease - liqBonus: (lbBefore - 100_00) - 2_00, // 2% absolute decrease - debtCeiling: (debtCeilingBefore * 90) / 100, // 10% relative decrease + ltv: ltvBefore - 50, // 0.5% absolute decrease + liqThreshold: ltBefore - 50, // 0.5% absolute decrease + liqBonus: (lbBefore - 100_00) - 50, // 0.5% absolute decrease + debtCeiling: (debtCeilingBefore * 80) / 100, // 20% relative decrease liqProtocolFee: EngineFlags.KEEP_CURRENT }); steward.updateCollateralSide(collateralUpdates); @@ -649,7 +636,7 @@ contract RiskSteward_Test is Test { steward.updateCollateralSide(collateralUpdates); // after min time passed test collateral update decrease - vm.warp(block.timestamp + 5 days + 1); + vm.warp(block.timestamp + 3 days + 1); collateralUpdates[0] = IEngine.CollateralUpdate({ asset: AaveV3EthereumAssets.UNI_UNDERLYING, @@ -763,14 +750,14 @@ contract RiskSteward_Test is Test { function test_updateCollateralSide_toValueZeroNotAllowed() public virtual { // set risk config to allow 100% collateral param change to 0 IRiskSteward.RiskParamConfig memory collateralParamConfig = IRiskSteward.RiskParamConfig({ - minDelay: 5 days, + minDelay: 3 days, maxPercentChange: 100_00 // 100% relative change }); - riskConfig.ltv = collateralParamConfig; - riskConfig.liquidationThreshold = collateralParamConfig; - riskConfig.liquidationBonus = collateralParamConfig; - riskConfig.debtCeiling = collateralParamConfig; + riskConfig.collateralConfig.ltv = collateralParamConfig; + riskConfig.collateralConfig.liquidationThreshold = collateralParamConfig; + riskConfig.collateralConfig.liquidationBonus = collateralParamConfig; + riskConfig.collateralConfig.debtCeiling = collateralParamConfig; vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward.setRiskConfig(riskConfig); @@ -906,7 +893,7 @@ contract RiskSteward_Test is Test { steward.updateCollateralSide(collateralUpdates); vm.expectRevert(IRiskSteward.InvalidCaller.selector); - steward.updateRates(rateStrategyUpdate); + steward.updateCollateralSide(collateralUpdates); vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, caller)); steward.setRiskConfig(riskConfig); @@ -919,7 +906,7 @@ contract RiskSteward_Test is Test { function test_assetRestricted() public { vm.expectEmit(); - emit AddressRestricted(AaveV3EthereumAssets.GHO_UNDERLYING, true); + emit IRiskSteward.AddressRestricted(AaveV3EthereumAssets.GHO_UNDERLYING, true); vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward.setAddressRestricted(AaveV3EthereumAssets.GHO_UNDERLYING, true); @@ -927,7 +914,7 @@ contract RiskSteward_Test is Test { assertTrue(steward.isAddressRestricted(AaveV3EthereumAssets.GHO_UNDERLYING)); vm.expectEmit(); - emit AddressRestricted(AaveV3EthereumAssets.GHO_UNDERLYING, false); + emit IRiskSteward.AddressRestricted(AaveV3EthereumAssets.GHO_UNDERLYING, false); vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward.setAddressRestricted(AaveV3EthereumAssets.GHO_UNDERLYING, false); @@ -942,22 +929,30 @@ contract RiskSteward_Test is Test { }); IRiskSteward.Config memory initialRiskConfig = IRiskSteward.Config({ - ltv: newRiskParamConfig, - liquidationThreshold: newRiskParamConfig, - liquidationBonus: newRiskParamConfig, - supplyCap: newRiskParamConfig, - borrowCap: newRiskParamConfig, - debtCeiling: newRiskParamConfig, - baseVariableBorrowRate: newRiskParamConfig, - variableRateSlope1: newRiskParamConfig, - variableRateSlope2: newRiskParamConfig, - optimalUsageRatio: newRiskParamConfig, - priceCapLst: newRiskParamConfig, - priceCapStable: newRiskParamConfig + collateralConfig: IRiskSteward.CollateralConfig({ + ltv: newRiskParamConfig, + liquidationThreshold: newRiskParamConfig, + liquidationBonus: newRiskParamConfig, + debtCeiling: newRiskParamConfig + }), + rateConfig: IRiskSteward.RateConfig({ + baseVariableBorrowRate: newRiskParamConfig, + variableRateSlope1: newRiskParamConfig, + variableRateSlope2: newRiskParamConfig, + optimalUsageRatio: newRiskParamConfig + }), + capConfig: IRiskSteward.CapConfig({ + supplyCap: newRiskParamConfig, + borrowCap: newRiskParamConfig + }), + priceCapConfig: IRiskSteward.PriceCapConfig({ + priceCapLst: newRiskParamConfig, + priceCapStable: newRiskParamConfig + }) }); vm.expectEmit(); - emit RiskConfigSet(initialRiskConfig); + emit IRiskSteward.RiskConfigSet(initialRiskConfig); vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward.setRiskConfig(initialRiskConfig); @@ -965,117 +960,85 @@ contract RiskSteward_Test is Test { _validateRiskConfig(initialRiskConfig, steward.getRiskConfig()); } - function test_constructor() public { - riskConfig = IRiskSteward.Config({ - ltv: defaultRiskParamConfig, - liquidationThreshold: defaultRiskParamConfig, - liquidationBonus: defaultRiskParamConfig, - supplyCap: defaultRiskParamConfig, - borrowCap: defaultRiskParamConfig, - debtCeiling: defaultRiskParamConfig, - baseVariableBorrowRate: defaultRiskParamConfig, - variableRateSlope1: defaultRiskParamConfig, - variableRateSlope2: defaultRiskParamConfig, - optimalUsageRatio: defaultRiskParamConfig, - priceCapLst: defaultRiskParamConfig, - priceCapStable: defaultRiskParamConfig - }); - - steward = new RiskSteward( - AaveV3Ethereum.AAVE_PROTOCOL_DATA_PROVIDER, - IEngine(configEngine), - riskCouncil, - riskConfig - ); - - assertEq( - address(steward.POOL_DATA_PROVIDER()), - address(AaveV3Ethereum.AAVE_PROTOCOL_DATA_PROVIDER) - ); - assertEq(address(steward.CONFIG_ENGINE()), address(IEngine(configEngine))); - assertEq(steward.RISK_COUNCIL(), riskCouncil); - _validateRiskConfig(riskConfig, steward.getRiskConfig()); - } - function _validateRiskConfig( IRiskSteward.Config memory initialRiskConfig, IRiskSteward.Config memory updatedRiskConfig ) internal pure { - assertEq(initialRiskConfig.ltv.minDelay, updatedRiskConfig.ltv.minDelay); - assertEq(initialRiskConfig.ltv.maxPercentChange, updatedRiskConfig.ltv.maxPercentChange); + assertEq(initialRiskConfig.collateralConfig.ltv.minDelay, updatedRiskConfig.collateralConfig.ltv.minDelay); + assertEq(initialRiskConfig.collateralConfig.ltv.maxPercentChange, updatedRiskConfig.collateralConfig.ltv.maxPercentChange); assertEq( - initialRiskConfig.liquidationThreshold.minDelay, - updatedRiskConfig.liquidationThreshold.minDelay + initialRiskConfig.collateralConfig.liquidationThreshold.minDelay, + updatedRiskConfig.collateralConfig.liquidationThreshold.minDelay ); assertEq( - initialRiskConfig.liquidationThreshold.maxPercentChange, - updatedRiskConfig.liquidationThreshold.maxPercentChange + initialRiskConfig.collateralConfig.liquidationThreshold.maxPercentChange, + updatedRiskConfig.collateralConfig.liquidationThreshold.maxPercentChange ); assertEq( - initialRiskConfig.liquidationBonus.minDelay, - updatedRiskConfig.liquidationBonus.minDelay + initialRiskConfig.collateralConfig.liquidationBonus.minDelay, + updatedRiskConfig.collateralConfig.liquidationBonus.minDelay ); assertEq( - initialRiskConfig.liquidationBonus.maxPercentChange, - updatedRiskConfig.liquidationBonus.maxPercentChange + initialRiskConfig.collateralConfig.liquidationBonus.maxPercentChange, + updatedRiskConfig.collateralConfig.liquidationBonus.maxPercentChange ); - assertEq(initialRiskConfig.supplyCap.minDelay, updatedRiskConfig.supplyCap.minDelay); + assertEq(initialRiskConfig.capConfig.supplyCap.minDelay, updatedRiskConfig.capConfig.supplyCap.minDelay); assertEq( - initialRiskConfig.supplyCap.maxPercentChange, - updatedRiskConfig.supplyCap.maxPercentChange + initialRiskConfig.capConfig.supplyCap.maxPercentChange, + updatedRiskConfig.capConfig.supplyCap.maxPercentChange ); - assertEq(initialRiskConfig.borrowCap.minDelay, updatedRiskConfig.borrowCap.minDelay); + assertEq(initialRiskConfig.capConfig.borrowCap.minDelay, updatedRiskConfig.capConfig.borrowCap.minDelay); assertEq( - initialRiskConfig.borrowCap.maxPercentChange, - updatedRiskConfig.borrowCap.maxPercentChange + initialRiskConfig.capConfig.borrowCap.maxPercentChange, + updatedRiskConfig.capConfig.borrowCap.maxPercentChange ); - assertEq(initialRiskConfig.debtCeiling.minDelay, updatedRiskConfig.debtCeiling.minDelay); + assertEq(initialRiskConfig.collateralConfig.debtCeiling.minDelay, updatedRiskConfig.collateralConfig.debtCeiling.minDelay); assertEq( - initialRiskConfig.debtCeiling.maxPercentChange, - updatedRiskConfig.debtCeiling.maxPercentChange + initialRiskConfig.collateralConfig.debtCeiling.maxPercentChange, + updatedRiskConfig.collateralConfig.debtCeiling.maxPercentChange ); assertEq( - initialRiskConfig.baseVariableBorrowRate.minDelay, - updatedRiskConfig.baseVariableBorrowRate.minDelay + initialRiskConfig.rateConfig.baseVariableBorrowRate.minDelay, + updatedRiskConfig.rateConfig.baseVariableBorrowRate.minDelay ); assertEq( - initialRiskConfig.baseVariableBorrowRate.maxPercentChange, - updatedRiskConfig.baseVariableBorrowRate.maxPercentChange + initialRiskConfig.rateConfig.baseVariableBorrowRate.maxPercentChange, + updatedRiskConfig.rateConfig.baseVariableBorrowRate.maxPercentChange ); assertEq( - initialRiskConfig.variableRateSlope1.minDelay, - updatedRiskConfig.variableRateSlope1.minDelay + initialRiskConfig.rateConfig.variableRateSlope1.minDelay, + updatedRiskConfig.rateConfig.variableRateSlope1.minDelay ); assertEq( - initialRiskConfig.variableRateSlope1.maxPercentChange, - updatedRiskConfig.variableRateSlope1.maxPercentChange + initialRiskConfig.rateConfig.variableRateSlope1.maxPercentChange, + updatedRiskConfig.rateConfig.variableRateSlope1.maxPercentChange ); assertEq( - initialRiskConfig.variableRateSlope2.minDelay, - updatedRiskConfig.variableRateSlope2.minDelay + initialRiskConfig.rateConfig.variableRateSlope2.minDelay, + updatedRiskConfig.rateConfig.variableRateSlope2.minDelay ); assertEq( - initialRiskConfig.variableRateSlope2.maxPercentChange, - updatedRiskConfig.variableRateSlope2.maxPercentChange + initialRiskConfig.rateConfig.variableRateSlope2.maxPercentChange, + updatedRiskConfig.rateConfig.variableRateSlope2.maxPercentChange ); assertEq( - initialRiskConfig.optimalUsageRatio.minDelay, - updatedRiskConfig.optimalUsageRatio.minDelay + initialRiskConfig.rateConfig.optimalUsageRatio.minDelay, + updatedRiskConfig.rateConfig.optimalUsageRatio.minDelay ); assertEq( - initialRiskConfig.optimalUsageRatio.maxPercentChange, - updatedRiskConfig.optimalUsageRatio.maxPercentChange + initialRiskConfig.rateConfig.optimalUsageRatio.maxPercentChange, + updatedRiskConfig.rateConfig.optimalUsageRatio.maxPercentChange ); assertEq( - initialRiskConfig.priceCapLst.maxPercentChange, - updatedRiskConfig.priceCapLst.maxPercentChange + initialRiskConfig.priceCapConfig.priceCapLst.maxPercentChange, + updatedRiskConfig.priceCapConfig.priceCapLst.maxPercentChange ); - assertEq(initialRiskConfig.priceCapLst.minDelay, updatedRiskConfig.priceCapLst.minDelay); + assertEq(initialRiskConfig.priceCapConfig.priceCapLst.minDelay, updatedRiskConfig.priceCapConfig.priceCapLst.minDelay); assertEq( - initialRiskConfig.priceCapStable.maxPercentChange, - updatedRiskConfig.priceCapStable.maxPercentChange + initialRiskConfig.priceCapConfig.priceCapStable.maxPercentChange, + updatedRiskConfig.priceCapConfig.priceCapStable.maxPercentChange ); - assertEq(initialRiskConfig.priceCapStable.minDelay, updatedRiskConfig.priceCapStable.minDelay); + assertEq(initialRiskConfig.priceCapConfig.priceCapStable.minDelay, updatedRiskConfig.priceCapConfig.priceCapStable.minDelay); } function _getInterestRatesForAsset( diff --git a/tests/RiskStewardCapo.t.sol b/tests/RiskStewardCapo.t.sol index 0506ea5..47b69a0 100644 --- a/tests/RiskStewardCapo.t.sol +++ b/tests/RiskStewardCapo.t.sol @@ -32,31 +32,20 @@ contract RiskSteward_Capo_Test is Test { minDelay: 5 days, maxPercentChange: 10_00 // 10% }); + IRiskSteward.Config memory riskConfig; + riskConfig.priceCapConfig.priceCapLst = defaultRiskParamConfig; + riskConfig.priceCapConfig.priceCapStable = defaultRiskParamConfig; - IRiskSteward.Config memory riskConfig = IRiskSteward.Config({ - ltv: defaultRiskParamConfig, - liquidationThreshold: defaultRiskParamConfig, - liquidationBonus: defaultRiskParamConfig, - supplyCap: defaultRiskParamConfig, - borrowCap: defaultRiskParamConfig, - debtCeiling: defaultRiskParamConfig, - baseVariableBorrowRate: defaultRiskParamConfig, - variableRateSlope1: defaultRiskParamConfig, - variableRateSlope2: defaultRiskParamConfig, - optimalUsageRatio: defaultRiskParamConfig, - priceCapLst: defaultRiskParamConfig, - priceCapStable: defaultRiskParamConfig - }); - - vm.startPrank(GovernanceV3Ethereum.EXECUTOR_LVL_1); steward = new RiskSteward( - AaveV3Ethereum.AAVE_PROTOCOL_DATA_PROVIDER, - IEngine(AaveV3Ethereum.CONFIG_ENGINE), + address(AaveV3Ethereum.POOL), + AaveV3Ethereum.CONFIG_ENGINE, riskCouncil, + GovernanceV3Ethereum.EXECUTOR_LVL_1, riskConfig ); + + vm.prank(GovernanceV3Ethereum.EXECUTOR_LVL_1); AaveV3Ethereum.ACL_MANAGER.addRiskAdmin(address(steward)); - vm.stopPrank(); currentRatio = IPriceCapAdapter(AaveV3EthereumAssets.wstETH_ORACLE) .getRatio() From ae8d10d5e1bec6c928841c7d12d0d70c7635cf2e Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Tue, 1 Apr 2025 18:46:16 +0530 Subject: [PATCH 16/25] refactor: rename stablePriceCapUpdates --- README.md | 4 +-- certora/specs/rules.spec | 30 ++++++++-------- .../stablePriceCapUpdates.spec.ts.snap | 2 +- generator/features/mocks/configs.ts | 2 +- .../features/stablePriceCapUpdates.spec.ts | 8 ++--- generator/features/stablePriceCapsUpdates.ts | 10 +++--- generator/types.ts | 4 +-- scripts/RiskStewardsBase.s.sol | 10 +++--- src/contracts/EdgeRiskStewardCaps.sol | 2 +- src/contracts/EdgeRiskStewardRates.sol | 2 +- src/contracts/RiskSteward.sol | 6 ++-- .../AaveV3Ethereum_A_20250401.sol | 35 +++++++++++++++++++ .../20250401_AaveV3Ethereum_A/config.ts | 17 +++++++++ src/interfaces/IRiskSteward.sol | 4 +-- tests/EdgeRiskStewardCaps.t.sol | 2 +- tests/EdgeRiskStewardRates.t.sol | 2 +- tests/RiskStewardCapo.t.sol | 18 +++++----- 17 files changed, 105 insertions(+), 53 deletions(-) create mode 100644 src/contracts/updates/20250401_AaveV3Ethereum_A/AaveV3Ethereum_A_20250401.sol create mode 100644 src/contracts/updates/20250401_AaveV3Ethereum_A/config.ts diff --git a/README.md b/README.md index b38cc15..cc27b67 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ For each risk param, `maxPercentChange` is the maximum percent change allowed (b - LST Cap adapter params: `snapshotRatio` must be less or equal to the actual one. The `maxPercentChange` is applied to `maxYearlyGrowthPercent`, it is relative and is denominated in BPS. (Ex. `10_00` for +-10% relative change). For example, for a max yearly growth percent at 10_00 and `maxPercentChange` configured at `10_00`, the max yearly growth percent that can be configured is 11_00 and the minimum 9_00 via the steward. -- Stable price cap: the `maxPercentChange` is in relative values. +- Stablecoin price cap: the `maxPercentChange` is in relative values. For example, for a current price cap of an oracle configured at 1_10_000000 and `maxPercentChange` configured at `1_00`, the max price cap that can be configured is 1_11_100000 and the minimum 1_08_900000 via the steward. After the activation proposal, these params could only be changed by the governance by calling the `setRiskConfig()` method. @@ -158,7 +158,7 @@ $ tsx generator/cli â—¯ CapsUpdates (supplyCap, borrowCap) â—¯ CollateralsUpdates (ltv,lt,lb,debtCeiling,liqProtocolFee,eModeCategory) â—¯ LstPriceCapUpdates (snapshotTimestamp,snapshotRatio,maxYearlyRatioGrowthPercent) - â—¯ StablePriceCapUpdates (priceCap) + â—¯ StablecoinPriceCapUpdates (priceCap) ? Select the assets you want to amend WETH Fetching info for WETH diff --git a/certora/specs/rules.spec b/certora/specs/rules.spec index 59aada6..18de79c 100644 --- a/certora/specs/rules.spec +++ b/certora/specs/rules.spec @@ -69,7 +69,7 @@ ghost uint256 KEEP_CURRENT { Rule: updateCaps_validity. Description: the rule checks that: - 1. After a successed call to updateCaps, the fields supplyCapLastUpdated and borrowCapLastUpdated + 1. After a successed call to updateCaps, the fields supplyCapLastUpdated and borrowCapLastUpdated get the value of current timestamp. 2. The function AaveV3ConfigEngine.updateCaps is called. @@ -81,7 +81,7 @@ rule updateCaps_validity(env e) { require capsUpdate.length <= 2; // The length of the array is either 1 or 2. // Accordingly loop_iter==2 uint i; // this is the entry of the array that we shall look at - require i==1 || i==2; + require i==1 || i==2; require capsUpdate[i].supplyCap != KEEP_CURRENT; require capsUpdate[i].borrowCap != KEEP_CURRENT; @@ -112,13 +112,13 @@ rule updateRates_validity(env e) { require ratesUpdate.length <= 2; // The length of the array is either 1 or 2. // Accordingly loop_iter==2 uint i; // this is the entry of the array that we shall look at - require i==1 || i==2; - + require i==1 || i==2; + require ratesUpdate[i].params.optimalUsageRatio != KEEP_CURRENT; require ratesUpdate[i].params.baseVariableBorrowRate != KEEP_CURRENT; require ratesUpdate[i].params.variableRateSlope1 != KEEP_CURRENT; require ratesUpdate[i].params.variableRateSlope2 != KEEP_CURRENT; - + updateRates(e,ratesUpdate); address asset = ratesUpdate[i].asset; @@ -147,13 +147,13 @@ rule updateCollateralSide_validity(env e) { require collateralUpdate.length <= 2; // The length of the array is either 1 or 2. // Accordingly loop_iter==2 uint i; // this is the entry of the array that we shall look at - require i==1 || i==2; - + require i==1 || i==2; + require collateralUpdate[i].ltv != KEEP_CURRENT; require collateralUpdate[i].liqThreshold != KEEP_CURRENT; require collateralUpdate[i].liqBonus != KEEP_CURRENT; require collateralUpdate[i].debtCeiling != KEEP_CURRENT; - + updateCollateralSide(e,collateralUpdate); address asset = collateralUpdate[i].asset; @@ -185,8 +185,8 @@ rule updateLstPriceCaps_validity(env e) { require priceCapUpdates.length <= 2; // The length of the array is either 1 or 2. // Accordingly loop_iter==2 uint i; // this is the entry of the array that we shall look at - require i==1 || i==2; - + require i==1 || i==2; + updateLstPriceCaps(e,priceCapUpdates); address oracle = priceCapUpdates[i].oracle; @@ -202,7 +202,7 @@ rule updateLstPriceCaps_validity(env e) { Rule: updateStablePriceCaps_validity Description: the rule checks that: - 1. After a successed call to updateStablePriceCaps, the field priceCapLastUpdated + 1. After a successed call to updateStablecoinPriceCaps, the field priceCapLastUpdated get the value of current timestamp. 2. The function IPriceCapAdapterStable.setPriceCap is called. @@ -214,10 +214,10 @@ rule updateStablePriceCaps_validity(env e) { require priceCapUpdates.length <= 2; // The length of the array is either 1 or 2. // Accordingly loop_iter==2 uint i; // this is the entry of the array that we shall look at - require i==1 || i==2; - - - updateStablePriceCaps(e,priceCapUpdates); + require i==1 || i==2; + + + updateStablecoinPriceCaps(e,priceCapUpdates); address oracle = priceCapUpdates[i].oracle; diff --git a/generator/features/__snapshots__/stablePriceCapUpdates.spec.ts.snap b/generator/features/__snapshots__/stablePriceCapUpdates.spec.ts.snap index dcab199..8b6bb46 100644 --- a/generator/features/__snapshots__/stablePriceCapUpdates.spec.ts.snap +++ b/generator/features/__snapshots__/stablePriceCapUpdates.spec.ts.snap @@ -14,7 +14,7 @@ export const config: ConfigFile = { }, poolOptions: { AaveV3Ethereum: { - configs: {STABLE_PRICE_CAP_UPDATE: [{asset: 'USDT', priceCap: '108000000'}]}, + configs: {STABLECOIN_PRICE_CAP_UPDATE: [{asset: 'USDT', priceCap: '108000000'}]}, cache: {blockNumber: 42}, }, }, diff --git a/generator/features/mocks/configs.ts b/generator/features/mocks/configs.ts index 2f3879c..2a39563 100644 --- a/generator/features/mocks/configs.ts +++ b/generator/features/mocks/configs.ts @@ -86,7 +86,7 @@ export const lstPriceCapUpdate: LstPriceCapUpdate[] = [ }, ]; -export const stablePriceCapUpdate: StablePriceCapUpdate[] = [ +export const stablecoinPriceCapUpdate: StablePriceCapUpdate[] = [ { asset: 'USDT', priceCap: '108000000' diff --git a/generator/features/stablePriceCapUpdates.spec.ts b/generator/features/stablePriceCapUpdates.spec.ts index de8f539..5d2ecd1 100644 --- a/generator/features/stablePriceCapUpdates.spec.ts +++ b/generator/features/stablePriceCapUpdates.spec.ts @@ -1,6 +1,6 @@ // sum.test.js import {expect, describe, it} from 'vitest'; -import {MOCK_OPTIONS, stablePriceCapUpdate} from './mocks/configs'; +import {MOCK_OPTIONS, stablecoinPriceCapUpdate} from './mocks/configs'; import {generateFiles} from '../generator'; import {FEATURE, PoolConfigs} from '../types'; import {stablePriceCapsUpdates} from './stablePriceCapsUpdates'; @@ -10,7 +10,7 @@ describe('feature: capUpdates', () => { const output = stablePriceCapsUpdates.build({ options: MOCK_OPTIONS, pool: 'AaveV3Ethereum', - cfg: stablePriceCapUpdate, + cfg: stablecoinPriceCapUpdate, cache: {blockNumber: 42}, }); expect(output).toMatchSnapshot(); @@ -23,11 +23,11 @@ describe('feature: capUpdates', () => { stablePriceCapsUpdates.build({ options: {...MOCK_OPTIONS, pools: ['AaveV3Ethereum']}, pool: 'AaveV3Ethereum', - cfg: stablePriceCapUpdate, + cfg: stablecoinPriceCapUpdate, cache: {blockNumber: 42}, }), ], - configs: {[FEATURE.STABLE_PRICE_CAP_UPDATE]: stablePriceCapUpdate}, + configs: {[FEATURE.STABLECOIN_PRICE_CAP_UPDATE]: stablecoinPriceCapUpdate}, cache: {blockNumber: 42}, }, }; diff --git a/generator/features/stablePriceCapsUpdates.ts b/generator/features/stablePriceCapsUpdates.ts index f7ce479..d06f991 100644 --- a/generator/features/stablePriceCapsUpdates.ts +++ b/generator/features/stablePriceCapsUpdates.ts @@ -20,15 +20,15 @@ export async function fetchStablePriceCapUpdate( }; } -type StablePriceCapUpdates = StablePriceCapUpdate[]; +type StablecoinPriceCapUpdates = StablePriceCapUpdate[]; -export const stablePriceCapsUpdates: FeatureModule = { - value: FEATURE.STABLE_PRICE_CAP_UPDATE, - description: 'StablePriceCapUpdates (priceCap)', +export const stablePriceCapsUpdates: FeatureModule = { + value: FEATURE.STABLECOIN_PRICE_CAP_UPDATE, + description: 'StablecoinPriceCapUpdates (priceCap)', async cli({pool}) { console.log(`Fetching information for Stable Price Cap Updates on ${pool}`); - const response: StablePriceCapUpdates = []; + const response: StablecoinPriceCapUpdates = []; const assets = await assetsSelectPrompt({ message: 'Select the asset whose oracle you want to amend', pool, diff --git a/generator/types.ts b/generator/types.ts index 12dba94..5ceb54e 100644 --- a/generator/types.ts +++ b/generator/types.ts @@ -58,7 +58,7 @@ export enum FEATURE { COLLATERALS_UPDATE = 'COLLATERALS_UPDATE', RATE_UPDATE_V3 = 'RATE_UPDATE_V3', LST_PRICE_CAP_UPDATE = 'LST_PRICE_CAP_UPDATE', - STABLE_PRICE_CAP_UPDATE = 'STABLE_PRICE_CAP_UPDATE', + STABLECOIN_PRICE_CAP_UPDATE = 'STABLECOIN_PRICE_CAP_UPDATE', } export interface FeatureModule { @@ -92,7 +92,7 @@ export interface PoolConfig { [FEATURE.COLLATERALS_UPDATE]?: CollateralUpdate[]; [FEATURE.RATE_UPDATE_V3]?: RateStrategyUpdate[]; [FEATURE.LST_PRICE_CAP_UPDATE]?: LstPriceCapUpdate[]; - [FEATURE.STABLE_PRICE_CAP_UPDATE]?: StablePriceCapUpdate[]; + [FEATURE.STABLECOIN_PRICE_CAP_UPDATE]?: StablePriceCapUpdate[]; }; cache: PoolCache; } diff --git a/scripts/RiskStewardsBase.s.sol b/scripts/RiskStewardsBase.s.sol index e955168..0ab69b4 100644 --- a/scripts/RiskStewardsBase.s.sol +++ b/scripts/RiskStewardsBase.s.sol @@ -85,7 +85,7 @@ abstract contract RiskStewardsBase is ProtocolV3TestBase { IEngine.CollateralUpdate[] memory collateralUpdates = collateralsUpdates(); IEngine.RateStrategyUpdate[] memory rateUpdates = rateStrategiesUpdates(); IRiskSteward.PriceCapLstUpdate[] memory lstPriceCapUpdates = lstPriceCapsUpdates(); - IRiskSteward.PriceCapStableUpdate[] memory stablePriceCapUpdates = stablePriceCapsUpdates(); + IRiskSteward.PriceCapStableUpdate[] memory stablecoinPriceCapUpdates = stablePriceCapsUpdates(); if (skipTimelock) { // warp to the max timelock @@ -113,7 +113,7 @@ abstract contract RiskStewardsBase is ProtocolV3TestBase { if (lstPriceCapUpdates.length != 0) { timelocks[index++] = riskConfig.priceCapConfig.priceCapLst.minDelay; } - if (stablePriceCapUpdates.length != 0) { + if (stablecoinPriceCapUpdates.length != 0) { timelocks[index++] = riskConfig.priceCapConfig.priceCapStable.minDelay; } uint40 maxTimelock = 0; @@ -162,10 +162,10 @@ abstract contract RiskStewardsBase is ProtocolV3TestBase { txCount++; } - if (stablePriceCapUpdates.length != 0) { + if (stablecoinPriceCapUpdates.length != 0) { callDatas[txCount] = abi.encodeWithSelector( - IRiskSteward.updateStablePriceCaps.selector, - stablePriceCapUpdates + IRiskSteward.updateStablecoinPriceCaps.selector, + stablecoinPriceCapUpdates ); (bool success, bytes memory resultData) = address(STEWARD).call(callDatas[txCount]); _verifyCallResult(success, resultData); diff --git a/src/contracts/EdgeRiskStewardCaps.sol b/src/contracts/EdgeRiskStewardCaps.sol index 35c8e3a..3351052 100644 --- a/src/contracts/EdgeRiskStewardCaps.sol +++ b/src/contracts/EdgeRiskStewardCaps.sol @@ -47,7 +47,7 @@ contract EdgeRiskStewardCaps is RiskSteward { } /// @inheritdoc IRiskSteward - function updateStablePriceCaps( + function updateStablecoinPriceCaps( PriceCapStableUpdate[] calldata ) external virtual override onlyRiskCouncil { revert UpdateNotAllowed(); diff --git a/src/contracts/EdgeRiskStewardRates.sol b/src/contracts/EdgeRiskStewardRates.sol index d1a08e7..a51c6a1 100644 --- a/src/contracts/EdgeRiskStewardRates.sol +++ b/src/contracts/EdgeRiskStewardRates.sol @@ -45,7 +45,7 @@ contract EdgeRiskStewardRates is RiskSteward { } /// @inheritdoc IRiskSteward - function updateStablePriceCaps( + function updateStablecoinPriceCaps( PriceCapStableUpdate[] calldata ) external virtual override onlyRiskCouncil { revert UpdateNotAllowed(); diff --git a/src/contracts/RiskSteward.sol b/src/contracts/RiskSteward.sol index 4e29693..a8de36e 100644 --- a/src/contracts/RiskSteward.sol +++ b/src/contracts/RiskSteward.sol @@ -101,7 +101,7 @@ contract RiskSteward is Ownable, IRiskSteward { } /// @inheritdoc IRiskSteward - function updateStablePriceCaps( + function updateStablecoinPriceCaps( PriceCapStableUpdate[] calldata priceCapUpdates ) external virtual onlyRiskCouncil { _validatePriceCapStableUpdate(priceCapUpdates); @@ -338,7 +338,7 @@ contract RiskSteward is Ownable, IRiskSteward { } /** - * @notice method to validate the oracle stable price caps update + * @notice method to validate the stablecoin oracle price caps update * @param priceCapsUpdate list containing the new price cap values for the oracles */ function _validatePriceCapStableUpdate( @@ -485,7 +485,7 @@ contract RiskSteward is Ownable, IRiskSteward { } /** - * @notice method to update the oracle stable price caps update + * @notice method to update the stablecoin oracle price caps update * @param priceCapsUpdate list containing the new price cap values for the oracles */ function _updateStablePriceCaps(PriceCapStableUpdate[] calldata priceCapsUpdate) internal { diff --git a/src/contracts/updates/20250401_AaveV3Ethereum_A/AaveV3Ethereum_A_20250401.sol b/src/contracts/updates/20250401_AaveV3Ethereum_A/AaveV3Ethereum_A_20250401.sol new file mode 100644 index 0000000..61354b7 --- /dev/null +++ b/src/contracts/updates/20250401_AaveV3Ethereum_A/AaveV3Ethereum_A_20250401.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; +import {RiskStewardsEthereum} from '../../../../scripts/networks/RiskStewardsEthereum.s.sol'; +import {IRiskSteward} from '../../../interfaces/IRiskSteward.sol'; + +/** + * @title a + * @author a + * - discussion: a + * - deploy-command: make run-script contract=src/contracts/updates/20250401_AaveV3Ethereum_A/AaveV3Ethereum_A_20250401.sol:AaveV3Ethereum_A_20250401 network=mainnet broadcast=false generate_diff=true skip_timelock=false + */ +contract AaveV3Ethereum_A_20250401 is RiskStewardsEthereum { + function name() public pure override returns (string memory) { + return 'AaveV3Ethereum_A_20250401'; + } + + function stablePriceCapsUpdates() + public + pure + override + returns (IRiskSteward.PriceCapStableUpdate[] memory) + { + IRiskSteward.PriceCapStableUpdate[] + memory priceCapUpdates = new IRiskSteward.PriceCapStableUpdate[](1); + + priceCapUpdates[0] = IRiskSteward.PriceCapStableUpdate({ + oracle: AaveV3EthereumAssets.WETH_ORACLE, + priceCap: 30 + }); + + return priceCapUpdates; + } +} diff --git a/src/contracts/updates/20250401_AaveV3Ethereum_A/config.ts b/src/contracts/updates/20250401_AaveV3Ethereum_A/config.ts new file mode 100644 index 0000000..ef96b98 --- /dev/null +++ b/src/contracts/updates/20250401_AaveV3Ethereum_A/config.ts @@ -0,0 +1,17 @@ +import {ConfigFile} from '../../generator/types'; +export const config: ConfigFile = { + rootOptions: { + pools: ['AaveV3Ethereum'], + title: 'a', + shortName: 'A', + date: '20250401', + author: 'a', + discussion: 'a', + }, + poolOptions: { + AaveV3Ethereum: { + configs: {STABLECOIN_PRICE_CAP_UPDATE: [{asset: 'WETH', priceCap: '30'}]}, + cache: {blockNumber: 22174283}, + }, + }, +}; diff --git a/src/interfaces/IRiskSteward.sol b/src/interfaces/IRiskSteward.sol index 447c327..b091bc8 100644 --- a/src/interfaces/IRiskSteward.sol +++ b/src/interfaces/IRiskSteward.sol @@ -170,7 +170,7 @@ interface IRiskSteward { } /** - * @notice Struct used to update the stable cap params + * @notice Struct used to update the stablecoin cap params */ struct PriceCapStableUpdate { address oracle; @@ -230,7 +230,7 @@ interface IRiskSteward { * @dev A price cap increase / decrease is only allowed by a magnitude of maxPercentChange * @param priceCapUpdates struct containing new price cap params to be updated */ - function updateStablePriceCaps(PriceCapStableUpdate[] calldata priceCapUpdates) external; + function updateStablecoinPriceCaps(PriceCapStableUpdate[] calldata priceCapUpdates) external; /** * @notice method to check if an asset/oracle is restricted to be used by the risk stewards diff --git a/tests/EdgeRiskStewardCaps.t.sol b/tests/EdgeRiskStewardCaps.t.sol index 818a6e7..fc3fde7 100644 --- a/tests/EdgeRiskStewardCaps.t.sol +++ b/tests/EdgeRiskStewardCaps.t.sol @@ -89,6 +89,6 @@ contract EdgeRiskStewardCaps_Test is RiskSteward_Test { vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); - steward.updateStablePriceCaps(priceCapUpdates); + steward.updateStablecoinPriceCaps(priceCapUpdates); } } diff --git a/tests/EdgeRiskStewardRates.t.sol b/tests/EdgeRiskStewardRates.t.sol index e470fb1..732de71 100644 --- a/tests/EdgeRiskStewardRates.t.sol +++ b/tests/EdgeRiskStewardRates.t.sol @@ -91,6 +91,6 @@ contract EdgeRiskStewardRates_Test is RiskSteward_Test { vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); - steward.updateStablePriceCaps(priceCapUpdates); + steward.updateStablecoinPriceCaps(priceCapUpdates); } } diff --git a/tests/RiskStewardCapo.t.sol b/tests/RiskStewardCapo.t.sol index 47b69a0..0719c7b 100644 --- a/tests/RiskStewardCapo.t.sol +++ b/tests/RiskStewardCapo.t.sol @@ -373,7 +373,7 @@ contract RiskSteward_Capo_Test is Test { }); vm.startPrank(riskCouncil); - steward.updateStablePriceCaps(priceCapUpdates); + steward.updateStablecoinPriceCaps(priceCapUpdates); RiskSteward.Debounce memory lastUpdated = steward.getTimelock(AaveV3EthereumAssets.USDT_ORACLE); @@ -392,7 +392,7 @@ contract RiskSteward_Capo_Test is Test { priceCap: ((priceCapAfter * 90) / 100) // -10% relative change }); - steward.updateStablePriceCaps(priceCapUpdates); + steward.updateStablecoinPriceCaps(priceCapUpdates); lastUpdated = steward.getTimelock(AaveV3EthereumAssets.USDT_ORACLE); @@ -420,7 +420,7 @@ contract RiskSteward_Capo_Test is Test { }); vm.startPrank(riskCouncil); - steward.updateStablePriceCaps(priceCapUpdates); + steward.updateStablecoinPriceCaps(priceCapUpdates); priceCapUpdates[0] = IRiskSteward.PriceCapStableUpdate({ oracle: AaveV3EthereumAssets.USDT_ORACLE, @@ -429,7 +429,7 @@ contract RiskSteward_Capo_Test is Test { // expect revert as minimum time has not passed for next update vm.expectRevert(IRiskSteward.DebounceNotRespected.selector); - steward.updateStablePriceCaps(priceCapUpdates); + steward.updateStablecoinPriceCaps(priceCapUpdates); vm.stopPrank(); } @@ -451,7 +451,7 @@ contract RiskSteward_Capo_Test is Test { vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotInRange.selector); - steward.updateStablePriceCaps(priceCapUpdates); + steward.updateStablecoinPriceCaps(priceCapUpdates); vm.stopPrank(); } @@ -469,7 +469,7 @@ contract RiskSteward_Capo_Test is Test { vm.startPrank(riskCouncil); vm.expectRevert(); - steward.updateStablePriceCaps(priceCapUpdates); + steward.updateStablecoinPriceCaps(priceCapUpdates); vm.stopPrank(); } @@ -487,7 +487,7 @@ contract RiskSteward_Capo_Test is Test { vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.InvalidUpdateToZero.selector); - steward.updateStablePriceCaps(priceCapUpdates); + steward.updateStablecoinPriceCaps(priceCapUpdates); vm.stopPrank(); } @@ -513,7 +513,7 @@ contract RiskSteward_Capo_Test is Test { vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.OracleIsRestricted.selector); - steward.updateStablePriceCaps(priceCapUpdates); + steward.updateStablecoinPriceCaps(priceCapUpdates); vm.stopPrank(); } @@ -532,7 +532,7 @@ contract RiskSteward_Capo_Test is Test { }); vm.startPrank(riskCouncil); - steward.updateStablePriceCaps(priceCapUpdates); + steward.updateStablecoinPriceCaps(priceCapUpdates); uint256 priceCapAfter = IPriceCapAdapterStable(AaveV3EthereumAssets.USDT_ORACLE) .getPriceCap() From 1a66eeb2fd25b7dd18ddd8e3bed87719d747d83a Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Wed, 2 Apr 2025 13:33:25 +0530 Subject: [PATCH 17/25] Revert "refactor: rename stablePriceCapUpdates" This reverts commit ae8d10d5e1bec6c928841c7d12d0d70c7635cf2e. --- README.md | 4 +-- certora/specs/rules.spec | 30 ++++++++-------- .../stablePriceCapUpdates.spec.ts.snap | 2 +- generator/features/mocks/configs.ts | 2 +- .../features/stablePriceCapUpdates.spec.ts | 8 ++--- generator/features/stablePriceCapsUpdates.ts | 10 +++--- generator/types.ts | 4 +-- scripts/RiskStewardsBase.s.sol | 10 +++--- src/contracts/EdgeRiskStewardCaps.sol | 2 +- src/contracts/EdgeRiskStewardRates.sol | 2 +- src/contracts/RiskSteward.sol | 6 ++-- .../AaveV3Ethereum_A_20250401.sol | 35 ------------------- .../20250401_AaveV3Ethereum_A/config.ts | 17 --------- src/interfaces/IRiskSteward.sol | 4 +-- tests/EdgeRiskStewardCaps.t.sol | 2 +- tests/EdgeRiskStewardRates.t.sol | 2 +- tests/RiskStewardCapo.t.sol | 18 +++++----- 17 files changed, 53 insertions(+), 105 deletions(-) delete mode 100644 src/contracts/updates/20250401_AaveV3Ethereum_A/AaveV3Ethereum_A_20250401.sol delete mode 100644 src/contracts/updates/20250401_AaveV3Ethereum_A/config.ts diff --git a/README.md b/README.md index cc27b67..b38cc15 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ For each risk param, `maxPercentChange` is the maximum percent change allowed (b - LST Cap adapter params: `snapshotRatio` must be less or equal to the actual one. The `maxPercentChange` is applied to `maxYearlyGrowthPercent`, it is relative and is denominated in BPS. (Ex. `10_00` for +-10% relative change). For example, for a max yearly growth percent at 10_00 and `maxPercentChange` configured at `10_00`, the max yearly growth percent that can be configured is 11_00 and the minimum 9_00 via the steward. -- Stablecoin price cap: the `maxPercentChange` is in relative values. +- Stable price cap: the `maxPercentChange` is in relative values. For example, for a current price cap of an oracle configured at 1_10_000000 and `maxPercentChange` configured at `1_00`, the max price cap that can be configured is 1_11_100000 and the minimum 1_08_900000 via the steward. After the activation proposal, these params could only be changed by the governance by calling the `setRiskConfig()` method. @@ -158,7 +158,7 @@ $ tsx generator/cli â—¯ CapsUpdates (supplyCap, borrowCap) â—¯ CollateralsUpdates (ltv,lt,lb,debtCeiling,liqProtocolFee,eModeCategory) â—¯ LstPriceCapUpdates (snapshotTimestamp,snapshotRatio,maxYearlyRatioGrowthPercent) - â—¯ StablecoinPriceCapUpdates (priceCap) + â—¯ StablePriceCapUpdates (priceCap) ? Select the assets you want to amend WETH Fetching info for WETH diff --git a/certora/specs/rules.spec b/certora/specs/rules.spec index 18de79c..59aada6 100644 --- a/certora/specs/rules.spec +++ b/certora/specs/rules.spec @@ -69,7 +69,7 @@ ghost uint256 KEEP_CURRENT { Rule: updateCaps_validity. Description: the rule checks that: - 1. After a successed call to updateCaps, the fields supplyCapLastUpdated and borrowCapLastUpdated + 1. After a successed call to updateCaps, the fields supplyCapLastUpdated and borrowCapLastUpdated get the value of current timestamp. 2. The function AaveV3ConfigEngine.updateCaps is called. @@ -81,7 +81,7 @@ rule updateCaps_validity(env e) { require capsUpdate.length <= 2; // The length of the array is either 1 or 2. // Accordingly loop_iter==2 uint i; // this is the entry of the array that we shall look at - require i==1 || i==2; + require i==1 || i==2; require capsUpdate[i].supplyCap != KEEP_CURRENT; require capsUpdate[i].borrowCap != KEEP_CURRENT; @@ -112,13 +112,13 @@ rule updateRates_validity(env e) { require ratesUpdate.length <= 2; // The length of the array is either 1 or 2. // Accordingly loop_iter==2 uint i; // this is the entry of the array that we shall look at - require i==1 || i==2; - + require i==1 || i==2; + require ratesUpdate[i].params.optimalUsageRatio != KEEP_CURRENT; require ratesUpdate[i].params.baseVariableBorrowRate != KEEP_CURRENT; require ratesUpdate[i].params.variableRateSlope1 != KEEP_CURRENT; require ratesUpdate[i].params.variableRateSlope2 != KEEP_CURRENT; - + updateRates(e,ratesUpdate); address asset = ratesUpdate[i].asset; @@ -147,13 +147,13 @@ rule updateCollateralSide_validity(env e) { require collateralUpdate.length <= 2; // The length of the array is either 1 or 2. // Accordingly loop_iter==2 uint i; // this is the entry of the array that we shall look at - require i==1 || i==2; - + require i==1 || i==2; + require collateralUpdate[i].ltv != KEEP_CURRENT; require collateralUpdate[i].liqThreshold != KEEP_CURRENT; require collateralUpdate[i].liqBonus != KEEP_CURRENT; require collateralUpdate[i].debtCeiling != KEEP_CURRENT; - + updateCollateralSide(e,collateralUpdate); address asset = collateralUpdate[i].asset; @@ -185,8 +185,8 @@ rule updateLstPriceCaps_validity(env e) { require priceCapUpdates.length <= 2; // The length of the array is either 1 or 2. // Accordingly loop_iter==2 uint i; // this is the entry of the array that we shall look at - require i==1 || i==2; - + require i==1 || i==2; + updateLstPriceCaps(e,priceCapUpdates); address oracle = priceCapUpdates[i].oracle; @@ -202,7 +202,7 @@ rule updateLstPriceCaps_validity(env e) { Rule: updateStablePriceCaps_validity Description: the rule checks that: - 1. After a successed call to updateStablecoinPriceCaps, the field priceCapLastUpdated + 1. After a successed call to updateStablePriceCaps, the field priceCapLastUpdated get the value of current timestamp. 2. The function IPriceCapAdapterStable.setPriceCap is called. @@ -214,10 +214,10 @@ rule updateStablePriceCaps_validity(env e) { require priceCapUpdates.length <= 2; // The length of the array is either 1 or 2. // Accordingly loop_iter==2 uint i; // this is the entry of the array that we shall look at - require i==1 || i==2; - - - updateStablecoinPriceCaps(e,priceCapUpdates); + require i==1 || i==2; + + + updateStablePriceCaps(e,priceCapUpdates); address oracle = priceCapUpdates[i].oracle; diff --git a/generator/features/__snapshots__/stablePriceCapUpdates.spec.ts.snap b/generator/features/__snapshots__/stablePriceCapUpdates.spec.ts.snap index 8b6bb46..dcab199 100644 --- a/generator/features/__snapshots__/stablePriceCapUpdates.spec.ts.snap +++ b/generator/features/__snapshots__/stablePriceCapUpdates.spec.ts.snap @@ -14,7 +14,7 @@ export const config: ConfigFile = { }, poolOptions: { AaveV3Ethereum: { - configs: {STABLECOIN_PRICE_CAP_UPDATE: [{asset: 'USDT', priceCap: '108000000'}]}, + configs: {STABLE_PRICE_CAP_UPDATE: [{asset: 'USDT', priceCap: '108000000'}]}, cache: {blockNumber: 42}, }, }, diff --git a/generator/features/mocks/configs.ts b/generator/features/mocks/configs.ts index 2a39563..2f3879c 100644 --- a/generator/features/mocks/configs.ts +++ b/generator/features/mocks/configs.ts @@ -86,7 +86,7 @@ export const lstPriceCapUpdate: LstPriceCapUpdate[] = [ }, ]; -export const stablecoinPriceCapUpdate: StablePriceCapUpdate[] = [ +export const stablePriceCapUpdate: StablePriceCapUpdate[] = [ { asset: 'USDT', priceCap: '108000000' diff --git a/generator/features/stablePriceCapUpdates.spec.ts b/generator/features/stablePriceCapUpdates.spec.ts index 5d2ecd1..de8f539 100644 --- a/generator/features/stablePriceCapUpdates.spec.ts +++ b/generator/features/stablePriceCapUpdates.spec.ts @@ -1,6 +1,6 @@ // sum.test.js import {expect, describe, it} from 'vitest'; -import {MOCK_OPTIONS, stablecoinPriceCapUpdate} from './mocks/configs'; +import {MOCK_OPTIONS, stablePriceCapUpdate} from './mocks/configs'; import {generateFiles} from '../generator'; import {FEATURE, PoolConfigs} from '../types'; import {stablePriceCapsUpdates} from './stablePriceCapsUpdates'; @@ -10,7 +10,7 @@ describe('feature: capUpdates', () => { const output = stablePriceCapsUpdates.build({ options: MOCK_OPTIONS, pool: 'AaveV3Ethereum', - cfg: stablecoinPriceCapUpdate, + cfg: stablePriceCapUpdate, cache: {blockNumber: 42}, }); expect(output).toMatchSnapshot(); @@ -23,11 +23,11 @@ describe('feature: capUpdates', () => { stablePriceCapsUpdates.build({ options: {...MOCK_OPTIONS, pools: ['AaveV3Ethereum']}, pool: 'AaveV3Ethereum', - cfg: stablecoinPriceCapUpdate, + cfg: stablePriceCapUpdate, cache: {blockNumber: 42}, }), ], - configs: {[FEATURE.STABLECOIN_PRICE_CAP_UPDATE]: stablecoinPriceCapUpdate}, + configs: {[FEATURE.STABLE_PRICE_CAP_UPDATE]: stablePriceCapUpdate}, cache: {blockNumber: 42}, }, }; diff --git a/generator/features/stablePriceCapsUpdates.ts b/generator/features/stablePriceCapsUpdates.ts index d06f991..f7ce479 100644 --- a/generator/features/stablePriceCapsUpdates.ts +++ b/generator/features/stablePriceCapsUpdates.ts @@ -20,15 +20,15 @@ export async function fetchStablePriceCapUpdate( }; } -type StablecoinPriceCapUpdates = StablePriceCapUpdate[]; +type StablePriceCapUpdates = StablePriceCapUpdate[]; -export const stablePriceCapsUpdates: FeatureModule = { - value: FEATURE.STABLECOIN_PRICE_CAP_UPDATE, - description: 'StablecoinPriceCapUpdates (priceCap)', +export const stablePriceCapsUpdates: FeatureModule = { + value: FEATURE.STABLE_PRICE_CAP_UPDATE, + description: 'StablePriceCapUpdates (priceCap)', async cli({pool}) { console.log(`Fetching information for Stable Price Cap Updates on ${pool}`); - const response: StablecoinPriceCapUpdates = []; + const response: StablePriceCapUpdates = []; const assets = await assetsSelectPrompt({ message: 'Select the asset whose oracle you want to amend', pool, diff --git a/generator/types.ts b/generator/types.ts index 5ceb54e..12dba94 100644 --- a/generator/types.ts +++ b/generator/types.ts @@ -58,7 +58,7 @@ export enum FEATURE { COLLATERALS_UPDATE = 'COLLATERALS_UPDATE', RATE_UPDATE_V3 = 'RATE_UPDATE_V3', LST_PRICE_CAP_UPDATE = 'LST_PRICE_CAP_UPDATE', - STABLECOIN_PRICE_CAP_UPDATE = 'STABLECOIN_PRICE_CAP_UPDATE', + STABLE_PRICE_CAP_UPDATE = 'STABLE_PRICE_CAP_UPDATE', } export interface FeatureModule { @@ -92,7 +92,7 @@ export interface PoolConfig { [FEATURE.COLLATERALS_UPDATE]?: CollateralUpdate[]; [FEATURE.RATE_UPDATE_V3]?: RateStrategyUpdate[]; [FEATURE.LST_PRICE_CAP_UPDATE]?: LstPriceCapUpdate[]; - [FEATURE.STABLECOIN_PRICE_CAP_UPDATE]?: StablePriceCapUpdate[]; + [FEATURE.STABLE_PRICE_CAP_UPDATE]?: StablePriceCapUpdate[]; }; cache: PoolCache; } diff --git a/scripts/RiskStewardsBase.s.sol b/scripts/RiskStewardsBase.s.sol index 0ab69b4..e955168 100644 --- a/scripts/RiskStewardsBase.s.sol +++ b/scripts/RiskStewardsBase.s.sol @@ -85,7 +85,7 @@ abstract contract RiskStewardsBase is ProtocolV3TestBase { IEngine.CollateralUpdate[] memory collateralUpdates = collateralsUpdates(); IEngine.RateStrategyUpdate[] memory rateUpdates = rateStrategiesUpdates(); IRiskSteward.PriceCapLstUpdate[] memory lstPriceCapUpdates = lstPriceCapsUpdates(); - IRiskSteward.PriceCapStableUpdate[] memory stablecoinPriceCapUpdates = stablePriceCapsUpdates(); + IRiskSteward.PriceCapStableUpdate[] memory stablePriceCapUpdates = stablePriceCapsUpdates(); if (skipTimelock) { // warp to the max timelock @@ -113,7 +113,7 @@ abstract contract RiskStewardsBase is ProtocolV3TestBase { if (lstPriceCapUpdates.length != 0) { timelocks[index++] = riskConfig.priceCapConfig.priceCapLst.minDelay; } - if (stablecoinPriceCapUpdates.length != 0) { + if (stablePriceCapUpdates.length != 0) { timelocks[index++] = riskConfig.priceCapConfig.priceCapStable.minDelay; } uint40 maxTimelock = 0; @@ -162,10 +162,10 @@ abstract contract RiskStewardsBase is ProtocolV3TestBase { txCount++; } - if (stablecoinPriceCapUpdates.length != 0) { + if (stablePriceCapUpdates.length != 0) { callDatas[txCount] = abi.encodeWithSelector( - IRiskSteward.updateStablecoinPriceCaps.selector, - stablecoinPriceCapUpdates + IRiskSteward.updateStablePriceCaps.selector, + stablePriceCapUpdates ); (bool success, bytes memory resultData) = address(STEWARD).call(callDatas[txCount]); _verifyCallResult(success, resultData); diff --git a/src/contracts/EdgeRiskStewardCaps.sol b/src/contracts/EdgeRiskStewardCaps.sol index 3351052..35c8e3a 100644 --- a/src/contracts/EdgeRiskStewardCaps.sol +++ b/src/contracts/EdgeRiskStewardCaps.sol @@ -47,7 +47,7 @@ contract EdgeRiskStewardCaps is RiskSteward { } /// @inheritdoc IRiskSteward - function updateStablecoinPriceCaps( + function updateStablePriceCaps( PriceCapStableUpdate[] calldata ) external virtual override onlyRiskCouncil { revert UpdateNotAllowed(); diff --git a/src/contracts/EdgeRiskStewardRates.sol b/src/contracts/EdgeRiskStewardRates.sol index a51c6a1..d1a08e7 100644 --- a/src/contracts/EdgeRiskStewardRates.sol +++ b/src/contracts/EdgeRiskStewardRates.sol @@ -45,7 +45,7 @@ contract EdgeRiskStewardRates is RiskSteward { } /// @inheritdoc IRiskSteward - function updateStablecoinPriceCaps( + function updateStablePriceCaps( PriceCapStableUpdate[] calldata ) external virtual override onlyRiskCouncil { revert UpdateNotAllowed(); diff --git a/src/contracts/RiskSteward.sol b/src/contracts/RiskSteward.sol index a8de36e..4e29693 100644 --- a/src/contracts/RiskSteward.sol +++ b/src/contracts/RiskSteward.sol @@ -101,7 +101,7 @@ contract RiskSteward is Ownable, IRiskSteward { } /// @inheritdoc IRiskSteward - function updateStablecoinPriceCaps( + function updateStablePriceCaps( PriceCapStableUpdate[] calldata priceCapUpdates ) external virtual onlyRiskCouncil { _validatePriceCapStableUpdate(priceCapUpdates); @@ -338,7 +338,7 @@ contract RiskSteward is Ownable, IRiskSteward { } /** - * @notice method to validate the stablecoin oracle price caps update + * @notice method to validate the oracle stable price caps update * @param priceCapsUpdate list containing the new price cap values for the oracles */ function _validatePriceCapStableUpdate( @@ -485,7 +485,7 @@ contract RiskSteward is Ownable, IRiskSteward { } /** - * @notice method to update the stablecoin oracle price caps update + * @notice method to update the oracle stable price caps update * @param priceCapsUpdate list containing the new price cap values for the oracles */ function _updateStablePriceCaps(PriceCapStableUpdate[] calldata priceCapsUpdate) internal { diff --git a/src/contracts/updates/20250401_AaveV3Ethereum_A/AaveV3Ethereum_A_20250401.sol b/src/contracts/updates/20250401_AaveV3Ethereum_A/AaveV3Ethereum_A_20250401.sol deleted file mode 100644 index 61354b7..0000000 --- a/src/contracts/updates/20250401_AaveV3Ethereum_A/AaveV3Ethereum_A_20250401.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; -import {RiskStewardsEthereum} from '../../../../scripts/networks/RiskStewardsEthereum.s.sol'; -import {IRiskSteward} from '../../../interfaces/IRiskSteward.sol'; - -/** - * @title a - * @author a - * - discussion: a - * - deploy-command: make run-script contract=src/contracts/updates/20250401_AaveV3Ethereum_A/AaveV3Ethereum_A_20250401.sol:AaveV3Ethereum_A_20250401 network=mainnet broadcast=false generate_diff=true skip_timelock=false - */ -contract AaveV3Ethereum_A_20250401 is RiskStewardsEthereum { - function name() public pure override returns (string memory) { - return 'AaveV3Ethereum_A_20250401'; - } - - function stablePriceCapsUpdates() - public - pure - override - returns (IRiskSteward.PriceCapStableUpdate[] memory) - { - IRiskSteward.PriceCapStableUpdate[] - memory priceCapUpdates = new IRiskSteward.PriceCapStableUpdate[](1); - - priceCapUpdates[0] = IRiskSteward.PriceCapStableUpdate({ - oracle: AaveV3EthereumAssets.WETH_ORACLE, - priceCap: 30 - }); - - return priceCapUpdates; - } -} diff --git a/src/contracts/updates/20250401_AaveV3Ethereum_A/config.ts b/src/contracts/updates/20250401_AaveV3Ethereum_A/config.ts deleted file mode 100644 index ef96b98..0000000 --- a/src/contracts/updates/20250401_AaveV3Ethereum_A/config.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {ConfigFile} from '../../generator/types'; -export const config: ConfigFile = { - rootOptions: { - pools: ['AaveV3Ethereum'], - title: 'a', - shortName: 'A', - date: '20250401', - author: 'a', - discussion: 'a', - }, - poolOptions: { - AaveV3Ethereum: { - configs: {STABLECOIN_PRICE_CAP_UPDATE: [{asset: 'WETH', priceCap: '30'}]}, - cache: {blockNumber: 22174283}, - }, - }, -}; diff --git a/src/interfaces/IRiskSteward.sol b/src/interfaces/IRiskSteward.sol index b091bc8..447c327 100644 --- a/src/interfaces/IRiskSteward.sol +++ b/src/interfaces/IRiskSteward.sol @@ -170,7 +170,7 @@ interface IRiskSteward { } /** - * @notice Struct used to update the stablecoin cap params + * @notice Struct used to update the stable cap params */ struct PriceCapStableUpdate { address oracle; @@ -230,7 +230,7 @@ interface IRiskSteward { * @dev A price cap increase / decrease is only allowed by a magnitude of maxPercentChange * @param priceCapUpdates struct containing new price cap params to be updated */ - function updateStablecoinPriceCaps(PriceCapStableUpdate[] calldata priceCapUpdates) external; + function updateStablePriceCaps(PriceCapStableUpdate[] calldata priceCapUpdates) external; /** * @notice method to check if an asset/oracle is restricted to be used by the risk stewards diff --git a/tests/EdgeRiskStewardCaps.t.sol b/tests/EdgeRiskStewardCaps.t.sol index fc3fde7..818a6e7 100644 --- a/tests/EdgeRiskStewardCaps.t.sol +++ b/tests/EdgeRiskStewardCaps.t.sol @@ -89,6 +89,6 @@ contract EdgeRiskStewardCaps_Test is RiskSteward_Test { vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); - steward.updateStablecoinPriceCaps(priceCapUpdates); + steward.updateStablePriceCaps(priceCapUpdates); } } diff --git a/tests/EdgeRiskStewardRates.t.sol b/tests/EdgeRiskStewardRates.t.sol index 732de71..e470fb1 100644 --- a/tests/EdgeRiskStewardRates.t.sol +++ b/tests/EdgeRiskStewardRates.t.sol @@ -91,6 +91,6 @@ contract EdgeRiskStewardRates_Test is RiskSteward_Test { vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotAllowed.selector); - steward.updateStablecoinPriceCaps(priceCapUpdates); + steward.updateStablePriceCaps(priceCapUpdates); } } diff --git a/tests/RiskStewardCapo.t.sol b/tests/RiskStewardCapo.t.sol index 0719c7b..47b69a0 100644 --- a/tests/RiskStewardCapo.t.sol +++ b/tests/RiskStewardCapo.t.sol @@ -373,7 +373,7 @@ contract RiskSteward_Capo_Test is Test { }); vm.startPrank(riskCouncil); - steward.updateStablecoinPriceCaps(priceCapUpdates); + steward.updateStablePriceCaps(priceCapUpdates); RiskSteward.Debounce memory lastUpdated = steward.getTimelock(AaveV3EthereumAssets.USDT_ORACLE); @@ -392,7 +392,7 @@ contract RiskSteward_Capo_Test is Test { priceCap: ((priceCapAfter * 90) / 100) // -10% relative change }); - steward.updateStablecoinPriceCaps(priceCapUpdates); + steward.updateStablePriceCaps(priceCapUpdates); lastUpdated = steward.getTimelock(AaveV3EthereumAssets.USDT_ORACLE); @@ -420,7 +420,7 @@ contract RiskSteward_Capo_Test is Test { }); vm.startPrank(riskCouncil); - steward.updateStablecoinPriceCaps(priceCapUpdates); + steward.updateStablePriceCaps(priceCapUpdates); priceCapUpdates[0] = IRiskSteward.PriceCapStableUpdate({ oracle: AaveV3EthereumAssets.USDT_ORACLE, @@ -429,7 +429,7 @@ contract RiskSteward_Capo_Test is Test { // expect revert as minimum time has not passed for next update vm.expectRevert(IRiskSteward.DebounceNotRespected.selector); - steward.updateStablecoinPriceCaps(priceCapUpdates); + steward.updateStablePriceCaps(priceCapUpdates); vm.stopPrank(); } @@ -451,7 +451,7 @@ contract RiskSteward_Capo_Test is Test { vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.UpdateNotInRange.selector); - steward.updateStablecoinPriceCaps(priceCapUpdates); + steward.updateStablePriceCaps(priceCapUpdates); vm.stopPrank(); } @@ -469,7 +469,7 @@ contract RiskSteward_Capo_Test is Test { vm.startPrank(riskCouncil); vm.expectRevert(); - steward.updateStablecoinPriceCaps(priceCapUpdates); + steward.updateStablePriceCaps(priceCapUpdates); vm.stopPrank(); } @@ -487,7 +487,7 @@ contract RiskSteward_Capo_Test is Test { vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.InvalidUpdateToZero.selector); - steward.updateStablecoinPriceCaps(priceCapUpdates); + steward.updateStablePriceCaps(priceCapUpdates); vm.stopPrank(); } @@ -513,7 +513,7 @@ contract RiskSteward_Capo_Test is Test { vm.startPrank(riskCouncil); vm.expectRevert(IRiskSteward.OracleIsRestricted.selector); - steward.updateStablecoinPriceCaps(priceCapUpdates); + steward.updateStablePriceCaps(priceCapUpdates); vm.stopPrank(); } @@ -532,7 +532,7 @@ contract RiskSteward_Capo_Test is Test { }); vm.startPrank(riskCouncil); - steward.updateStablecoinPriceCaps(priceCapUpdates); + steward.updateStablePriceCaps(priceCapUpdates); uint256 priceCapAfter = IPriceCapAdapterStable(AaveV3EthereumAssets.USDT_ORACLE) .getPriceCap() From 43391532b1cc53adacf68a00f484407b4ed2743a Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Wed, 2 Apr 2025 13:35:26 +0530 Subject: [PATCH 18/25] fix: remove bytes from timelock mapping --- src/contracts/RiskSteward.sol | 52 ++++++++++++++++----------------- src/interfaces/IRiskSteward.sol | 2 +- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/contracts/RiskSteward.sol b/src/contracts/RiskSteward.sol index 4e29693..5075336 100644 --- a/src/contracts/RiskSteward.sol +++ b/src/contracts/RiskSteward.sol @@ -38,7 +38,7 @@ contract RiskSteward is Ownable, IRiskSteward { Config internal _riskConfig; - mapping(bytes20 id => Debounce) internal _timelocks; + mapping(address => Debounce) internal _timelocks; mapping(address => bool) internal _restrictedAddresses; @@ -110,7 +110,7 @@ contract RiskSteward is Ownable, IRiskSteward { /// @inheritdoc IRiskSteward function getTimelock(address asset) external view returns (Debounce memory) { - return _timelocks[bytes20(asset)]; + return _timelocks[asset]; } /// @inheritdoc IRiskSteward @@ -155,7 +155,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentSupplyCap, newValue: capsUpdate[i].supplyCap, - lastUpdated: _timelocks[bytes20(asset)].supplyCapLastUpdated, + lastUpdated: _timelocks[asset].supplyCapLastUpdated, riskConfig: _riskConfig.capConfig.supplyCap, isChangeRelative: true }) @@ -164,7 +164,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentBorrowCap, newValue: capsUpdate[i].borrowCap, - lastUpdated: _timelocks[bytes20(asset)].borrowCapLastUpdated, + lastUpdated: _timelocks[asset].borrowCapLastUpdated, riskConfig: _riskConfig.capConfig.borrowCap, isChangeRelative: true }) @@ -194,7 +194,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentOptimalUsageRatio, newValue: ratesUpdate[i].params.optimalUsageRatio, - lastUpdated: _timelocks[bytes20(asset)].optimalUsageRatioLastUpdated, + lastUpdated: _timelocks[asset].optimalUsageRatioLastUpdated, riskConfig: _riskConfig.rateConfig.optimalUsageRatio, isChangeRelative: false }) @@ -203,7 +203,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentBaseVariableBorrowRate, newValue: ratesUpdate[i].params.baseVariableBorrowRate, - lastUpdated: _timelocks[bytes20(asset)].baseVariableRateLastUpdated, + lastUpdated: _timelocks[asset].baseVariableRateLastUpdated, riskConfig: _riskConfig.rateConfig.baseVariableBorrowRate, isChangeRelative: false }) @@ -212,7 +212,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentVariableRateSlope1, newValue: ratesUpdate[i].params.variableRateSlope1, - lastUpdated: _timelocks[bytes20(asset)].variableRateSlope1LastUpdated, + lastUpdated: _timelocks[asset].variableRateSlope1LastUpdated, riskConfig: _riskConfig.rateConfig.variableRateSlope1, isChangeRelative: false }) @@ -221,7 +221,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentVariableRateSlope2, newValue: ratesUpdate[i].params.variableRateSlope2, - lastUpdated: _timelocks[bytes20(asset)].variableRateSlope2LastUpdated, + lastUpdated: _timelocks[asset].variableRateSlope2LastUpdated, riskConfig: _riskConfig.rateConfig.variableRateSlope2, isChangeRelative: false }) @@ -264,7 +264,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentLtv, newValue: collateralUpdates[i].ltv, - lastUpdated: _timelocks[bytes20(asset)].ltvLastUpdated, + lastUpdated: _timelocks[asset].ltvLastUpdated, riskConfig: _riskConfig.collateralConfig.ltv, isChangeRelative: false }) @@ -273,7 +273,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentLiquidationThreshold, newValue: collateralUpdates[i].liqThreshold, - lastUpdated: _timelocks[bytes20(asset)].liquidationThresholdLastUpdated, + lastUpdated: _timelocks[asset].liquidationThresholdLastUpdated, riskConfig: _riskConfig.collateralConfig.liquidationThreshold, isChangeRelative: false }) @@ -282,7 +282,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentLiquidationBonus - 100_00, // as the definition is 100% + x%, and config engine takes into account x% for simplicity. newValue: collateralUpdates[i].liqBonus, - lastUpdated: _timelocks[bytes20(asset)].liquidationBonusLastUpdated, + lastUpdated: _timelocks[asset].liquidationBonusLastUpdated, riskConfig: _riskConfig.collateralConfig.liquidationBonus, isChangeRelative: false }) @@ -291,7 +291,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentDebtCeiling / 100, // as the definition is with 2 decimals, and config engine does not take the decimals into account. newValue: collateralUpdates[i].debtCeiling, - lastUpdated: _timelocks[bytes20(asset)].debtCeilingLastUpdated, + lastUpdated: _timelocks[asset].debtCeilingLastUpdated, riskConfig: _riskConfig.collateralConfig.debtCeiling, isChangeRelative: true }) @@ -329,7 +329,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentMaxYearlyGrowthPercent, newValue: priceCapsUpdate[i].priceCapUpdateParams.maxYearlyRatioGrowthPercent, - lastUpdated: _timelocks[bytes20(oracle)].priceCapLastUpdated, + lastUpdated: _timelocks[oracle].priceCapLastUpdated, riskConfig: _riskConfig.priceCapConfig.priceCapLst, isChangeRelative: true }) @@ -359,7 +359,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentPriceCap.toUint256(), newValue: priceCapsUpdate[i].priceCap, - lastUpdated: _timelocks[bytes20(oracle)].priceCapLastUpdated, + lastUpdated: _timelocks[oracle].priceCapLastUpdated, riskConfig: _riskConfig.priceCapConfig.priceCapStable, isChangeRelative: true }) @@ -395,11 +395,11 @@ contract RiskSteward is Ownable, IRiskSteward { address asset = capsUpdate[i].asset; if (capsUpdate[i].supplyCap != EngineFlags.KEEP_CURRENT) { - _timelocks[bytes20(asset)].supplyCapLastUpdated = uint40(block.timestamp); + _timelocks[asset].supplyCapLastUpdated = uint40(block.timestamp); } if (capsUpdate[i].borrowCap != EngineFlags.KEEP_CURRENT) { - _timelocks[bytes20(asset)].borrowCapLastUpdated = uint40(block.timestamp); + _timelocks[asset].borrowCapLastUpdated = uint40(block.timestamp); } } @@ -417,19 +417,19 @@ contract RiskSteward is Ownable, IRiskSteward { address asset = ratesUpdate[i].asset; if (ratesUpdate[i].params.optimalUsageRatio != EngineFlags.KEEP_CURRENT) { - _timelocks[bytes20(asset)].optimalUsageRatioLastUpdated = uint40(block.timestamp); + _timelocks[asset].optimalUsageRatioLastUpdated = uint40(block.timestamp); } if (ratesUpdate[i].params.baseVariableBorrowRate != EngineFlags.KEEP_CURRENT) { - _timelocks[bytes20(asset)].baseVariableRateLastUpdated = uint40(block.timestamp); + _timelocks[asset].baseVariableRateLastUpdated = uint40(block.timestamp); } if (ratesUpdate[i].params.variableRateSlope1 != EngineFlags.KEEP_CURRENT) { - _timelocks[bytes20(asset)].variableRateSlope1LastUpdated = uint40(block.timestamp); + _timelocks[asset].variableRateSlope1LastUpdated = uint40(block.timestamp); } if (ratesUpdate[i].params.variableRateSlope2 != EngineFlags.KEEP_CURRENT) { - _timelocks[bytes20(asset)].variableRateSlope2LastUpdated = uint40(block.timestamp); + _timelocks[asset].variableRateSlope2LastUpdated = uint40(block.timestamp); } } @@ -447,19 +447,19 @@ contract RiskSteward is Ownable, IRiskSteward { address asset = collateralUpdates[i].asset; if (collateralUpdates[i].ltv != EngineFlags.KEEP_CURRENT) { - _timelocks[bytes20(asset)].ltvLastUpdated = uint40(block.timestamp); + _timelocks[asset].ltvLastUpdated = uint40(block.timestamp); } if (collateralUpdates[i].liqThreshold != EngineFlags.KEEP_CURRENT) { - _timelocks[bytes20(asset)].liquidationThresholdLastUpdated = uint40(block.timestamp); + _timelocks[asset].liquidationThresholdLastUpdated = uint40(block.timestamp); } if (collateralUpdates[i].liqBonus != EngineFlags.KEEP_CURRENT) { - _timelocks[bytes20(asset)].liquidationBonusLastUpdated = uint40(block.timestamp); + _timelocks[asset].liquidationBonusLastUpdated = uint40(block.timestamp); } if (collateralUpdates[i].debtCeiling != EngineFlags.KEEP_CURRENT) { - _timelocks[bytes20(asset)].debtCeilingLastUpdated = uint40(block.timestamp); + _timelocks[asset].debtCeilingLastUpdated = uint40(block.timestamp); } } @@ -476,7 +476,7 @@ contract RiskSteward is Ownable, IRiskSteward { for (uint256 i = 0; i < priceCapsUpdate.length; i++) { address oracle = priceCapsUpdate[i].oracle; - _timelocks[bytes20(oracle)].priceCapLastUpdated = uint40(block.timestamp); + _timelocks[oracle].priceCapLastUpdated = uint40(block.timestamp); IPriceCapAdapter(oracle).setCapParameters(priceCapsUpdate[i].priceCapUpdateParams); @@ -492,7 +492,7 @@ contract RiskSteward is Ownable, IRiskSteward { for (uint256 i = 0; i < priceCapsUpdate.length; i++) { address oracle = priceCapsUpdate[i].oracle; - _timelocks[bytes20(oracle)].priceCapLastUpdated = uint40(block.timestamp); + _timelocks[oracle].priceCapLastUpdated = uint40(block.timestamp); IPriceCapAdapterStable(oracle).setPriceCap(priceCapsUpdate[i].priceCap.toInt256()); } diff --git a/src/interfaces/IRiskSteward.sol b/src/interfaces/IRiskSteward.sol index 447c327..cb8df3f 100644 --- a/src/interfaces/IRiskSteward.sol +++ b/src/interfaces/IRiskSteward.sol @@ -75,7 +75,7 @@ interface IRiskSteward { event RiskConfigSet(Config indexed riskConfig); /** - * @notice Struct storing the last update by the steward of each risk param + * @notice Struct storing the last update by the steward of risk param */ struct Debounce { uint40 ltvLastUpdated; From c0d1a3e54a908c4a26590a577dcdfe7a23c4b120 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Wed, 2 Apr 2025 13:43:51 +0530 Subject: [PATCH 19/25] fix: use different mapping for emode timelock --- src/contracts/RiskSteward.sol | 18 ++++++++++-------- src/interfaces/IRiskSteward.sol | 12 ++++++++++-- tests/RiskSteward.t.sol | 8 ++++---- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/contracts/RiskSteward.sol b/src/contracts/RiskSteward.sol index ead1d9f..019104e 100644 --- a/src/contracts/RiskSteward.sol +++ b/src/contracts/RiskSteward.sol @@ -40,6 +40,8 @@ contract RiskSteward is Ownable, IRiskSteward { mapping(address => Debounce) internal _timelocks; + mapping(uint8 => EModeDebounce) internal _eModeTimelocks; + mapping(address => bool) internal _restrictedAddresses; mapping(uint8 => bool) internal _restrictedEModes; @@ -124,8 +126,8 @@ contract RiskSteward is Ownable, IRiskSteward { } /// @inheritdoc IRiskSteward - function getEModeTimelock(uint8 eModeCategoryId) external view returns (Debounce memory) { - return _timelocks[bytes20(uint160(eModeCategoryId))]; + function getEModeTimelock(uint8 eModeCategoryId) external view returns (EModeDebounce memory) { + return _eModeTimelocks[eModeCategoryId]; } /// @inheritdoc IRiskSteward @@ -350,7 +352,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentEmodeConfig.ltv, newValue: eModeCategoryUpdates[i].ltv, - lastUpdated: _timelocks[bytes20(uint160(eModeId))].eModeLtvLastUpdated, + lastUpdated: _eModeTimelocks[eModeId].eModeLtvLastUpdated, riskConfig: _riskConfig.eModeConfig.ltv, isChangeRelative: false }) @@ -359,7 +361,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentEmodeConfig.liquidationThreshold, newValue: eModeCategoryUpdates[i].liqThreshold, - lastUpdated: _timelocks[bytes20(uint160(eModeId))].eModeLiquidationThresholdLastUpdated, + lastUpdated: _eModeTimelocks[eModeId].eModeLiquidationThresholdLastUpdated, riskConfig: _riskConfig.eModeConfig.liquidationThreshold, isChangeRelative: false }) @@ -368,7 +370,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentEmodeConfig.liquidationBonus - 100_00, // as the definition is 100% + x%, and config engine takes into account x% for simplicity. newValue: eModeCategoryUpdates[i].liqBonus, - lastUpdated: _timelocks[bytes20(uint160(eModeId))].eModeLiquidationBonusLastUpdated, + lastUpdated: _eModeTimelocks[eModeId].eModeLiquidationBonusLastUpdated, riskConfig: _riskConfig.eModeConfig.liquidationBonus, isChangeRelative: false }) @@ -554,15 +556,15 @@ contract RiskSteward is Ownable, IRiskSteward { uint8 eModeId = eModeCategoryUpdates[i].eModeCategory; if (eModeCategoryUpdates[i].ltv != EngineFlags.KEEP_CURRENT) { - _timelocks[bytes20(uint160(eModeId))].eModeLtvLastUpdated = uint40(block.timestamp); + _eModeTimelocks[eModeId].eModeLtvLastUpdated = uint40(block.timestamp); } if (eModeCategoryUpdates[i].liqThreshold != EngineFlags.KEEP_CURRENT) { - _timelocks[bytes20(uint160(eModeId))].eModeLiquidationThresholdLastUpdated = uint40(block.timestamp); + _eModeTimelocks[eModeId].eModeLiquidationThresholdLastUpdated = uint40(block.timestamp); } if (eModeCategoryUpdates[i].liqBonus != EngineFlags.KEEP_CURRENT) { - _timelocks[bytes20(uint160(eModeId))].eModeLiquidationBonusLastUpdated = uint40(block.timestamp); + _eModeTimelocks[eModeId].eModeLiquidationBonusLastUpdated = uint40(block.timestamp); } } diff --git a/src/interfaces/IRiskSteward.sol b/src/interfaces/IRiskSteward.sol index ebe8395..8df558b 100644 --- a/src/interfaces/IRiskSteward.sol +++ b/src/interfaces/IRiskSteward.sol @@ -106,6 +106,15 @@ interface IRiskSteward { uint40 borrowCapLastUpdated; } + /** + * @notice Struct storing the last update by the steward of eMode risk param + */ + struct EModeDebounce { + uint40 eModeLtvLastUpdated; + uint40 eModeLiquidationBonusLastUpdated; + uint40 eModeLiquidationThresholdLastUpdated; + } + /** * @notice Struct storing the params used for validation of the risk param update * @param currentValue the current value of the risk param @@ -305,9 +314,8 @@ interface IRiskSteward { * @notice Returns the timelock for a specific eMode category id i.e the last updated timestamp * @param eModeCategoryId the eMode category for which to fetch the timelock * @return struct containing the latest updated timestamps of eMode risk params by the steward - * @dev the non-emode timelock params of the struct returned will be unused */ - function getEModeTimelock(uint8 eModeCategoryId) external view returns (Debounce memory); + function getEModeTimelock(uint8 eModeCategoryId) external view returns (EModeDebounce memory); /** * @notice method to get the risk configuration set for all the risk params diff --git a/tests/RiskSteward.t.sol b/tests/RiskSteward.t.sol index e449623..bebdf20 100644 --- a/tests/RiskSteward.t.sol +++ b/tests/RiskSteward.t.sol @@ -870,7 +870,7 @@ contract RiskSteward_Test is Test { vm.startPrank(riskCouncil); steward.updateEModeCategories(eModeCategoryUpdates); - RiskSteward.Debounce memory lastUpdated = steward.getEModeTimelock(eModeId); + RiskSteward.EModeDebounce memory lastUpdated = steward.getEModeTimelock(eModeId); DataTypes.CollateralConfig memory afterEmodeConfig = AaveV3Ethereum.POOL.getEModeCategoryCollateralConfig(eModeId); string memory afterLabel = AaveV3Ethereum.POOL.getEModeCategoryLabel(eModeId); @@ -1034,7 +1034,7 @@ contract RiskSteward_Test is Test { uint8 eModeId = 1; DataTypes.CollateralConfig memory prevEmodeConfig = AaveV3Ethereum.POOL.getEModeCategoryCollateralConfig(eModeId); string memory prevLabel = AaveV3Ethereum.POOL.getEModeCategoryLabel(eModeId); - RiskSteward.Debounce memory prevLastUpdated = steward.getEModeTimelock(eModeId); + RiskSteward.EModeDebounce memory prevLastUpdated = steward.getEModeTimelock(eModeId); IEngine.EModeCategoryUpdate[] memory eModeCategoryUpdates = new IEngine.EModeCategoryUpdate[](1); eModeCategoryUpdates[0] = IEngine.EModeCategoryUpdate({ @@ -1049,7 +1049,7 @@ contract RiskSteward_Test is Test { steward.updateEModeCategories(eModeCategoryUpdates); DataTypes.CollateralConfig memory afterEmodeConfig = AaveV3Ethereum.POOL.getEModeCategoryCollateralConfig(eModeId); - RiskSteward.Debounce memory afterLastUpdated = steward.getEModeTimelock(eModeId); + RiskSteward.EModeDebounce memory afterLastUpdated = steward.getEModeTimelock(eModeId); string memory afterLabel = AaveV3Ethereum.POOL.getEModeCategoryLabel(eModeId); assertEq(afterEmodeConfig.ltv, prevEmodeConfig.ltv); @@ -1080,7 +1080,7 @@ contract RiskSteward_Test is Test { steward.updateEModeCategories(eModeCategoryUpdates); DataTypes.CollateralConfig memory afterEmodeConfig = AaveV3Ethereum.POOL.getEModeCategoryCollateralConfig(eModeId); - RiskSteward.Debounce memory afterLastUpdated = steward.getEModeTimelock(eModeId); + RiskSteward.EModeDebounce memory afterLastUpdated = steward.getEModeTimelock(eModeId); string memory afterLabel = AaveV3Ethereum.POOL.getEModeCategoryLabel(eModeId); assertEq(afterEmodeConfig.ltv, prevEmodeConfig.ltv); From ae13dc6542815c54c2d4237f2a25dc64dd22144e Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Wed, 2 Apr 2025 13:44:29 +0530 Subject: [PATCH 20/25] fix: struct --- src/interfaces/IRiskSteward.sol | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/interfaces/IRiskSteward.sol b/src/interfaces/IRiskSteward.sol index 8df558b..dbb681c 100644 --- a/src/interfaces/IRiskSteward.sol +++ b/src/interfaces/IRiskSteward.sol @@ -93,9 +93,6 @@ interface IRiskSteward { uint40 ltvLastUpdated; uint40 liquidationBonusLastUpdated; uint40 liquidationThresholdLastUpdated; - uint40 eModeLtvLastUpdated; - uint40 eModeLiquidationBonusLastUpdated; - uint40 eModeLiquidationThresholdLastUpdated; uint40 optimalUsageRatioLastUpdated; uint40 baseVariableRateLastUpdated; uint40 variableRateSlope1LastUpdated; From 6be86e055746e778e431d8bacb21d32994a1ac19 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Wed, 2 Apr 2025 13:48:01 +0530 Subject: [PATCH 21/25] fix: timelock --- src/contracts/RiskSteward.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/contracts/RiskSteward.sol b/src/contracts/RiskSteward.sol index dc1c61b..7fae7cb 100644 --- a/src/contracts/RiskSteward.sol +++ b/src/contracts/RiskSteward.sol @@ -477,7 +477,7 @@ contract RiskSteward is Ownable, IRiskSteward { ParamUpdateValidationInput({ currentValue: currentDiscount, newValue: priceCapsUpdate[i].discountRate, - lastUpdated: _timelocks[bytes20(oracle)].priceCapLastUpdated, + lastUpdated: _timelocks[oracle].priceCapLastUpdated, riskConfig: _riskConfig.priceCapConfig.priceCapPendle, isChangeRelative: true }) @@ -650,7 +650,7 @@ contract RiskSteward is Ownable, IRiskSteward { for (uint256 i = 0; i < priceCapsUpdate.length; i++) { address oracle = priceCapsUpdate[i].oracle; - _timelocks[bytes20(oracle)].priceCapLastUpdated = uint40(block.timestamp); + _timelocks[oracle].priceCapLastUpdated = uint40(block.timestamp); IPendlePriceCapAdapter(oracle).setDiscountRatePerYear(priceCapsUpdate[i].discountRate.toUint64()); } From d5d51a33929c76eaa09701fac006f005f1ec8ad7 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Wed, 2 Apr 2025 14:56:58 +0530 Subject: [PATCH 22/25] Update src/interfaces/IRiskSteward.sol Co-authored-by: Andrey --- src/interfaces/IRiskSteward.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/interfaces/IRiskSteward.sol b/src/interfaces/IRiskSteward.sol index cb8df3f..9930712 100644 --- a/src/interfaces/IRiskSteward.sol +++ b/src/interfaces/IRiskSteward.sol @@ -249,8 +249,7 @@ interface IRiskSteward { /** * @notice Returns the timelock for a specific asset i.e the last updated timestamp * @param asset for which to fetch the timelock - * @return struct containing the latest updated timestamps of all the risk params by the steward except eMode - * @dev the emode timelock params of the struct returned will be unused + * @return struct containing the latest updated timestamps of all the risk params by the steward per asset */ function getTimelock(address asset) external view returns (Debounce memory); From 3360ea948480b57321d002ed849673337b79bfda Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Wed, 2 Apr 2025 15:03:52 +0530 Subject: [PATCH 23/25] fix: Debounce struct order --- src/interfaces/IRiskSteward.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/interfaces/IRiskSteward.sol b/src/interfaces/IRiskSteward.sol index 9930712..df04bae 100644 --- a/src/interfaces/IRiskSteward.sol +++ b/src/interfaces/IRiskSteward.sol @@ -78,17 +78,17 @@ interface IRiskSteward { * @notice Struct storing the last update by the steward of risk param */ struct Debounce { + uint40 supplyCapLastUpdated; + uint40 borrowCapLastUpdated; uint40 ltvLastUpdated; uint40 liquidationBonusLastUpdated; uint40 liquidationThresholdLastUpdated; - uint40 optimalUsageRatioLastUpdated; + uint40 debtCeilingLastUpdated; uint40 baseVariableRateLastUpdated; uint40 variableRateSlope1LastUpdated; uint40 variableRateSlope2LastUpdated; - uint40 debtCeilingLastUpdated; + uint40 optimalUsageRatioLastUpdated; uint40 priceCapLastUpdated; - uint40 supplyCapLastUpdated; - uint40 borrowCapLastUpdated; } /** From 7d038adacb352a6a5b6df33e1d926f2c44be2047 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Wed, 2 Apr 2025 15:44:40 +0530 Subject: [PATCH 24/25] fix: dont allow emode label change --- src/contracts/RiskSteward.sol | 4 ++++ tests/EdgeRiskStewardCaps.t.sol | 2 +- tests/EdgeRiskStewardRates.t.sol | 2 +- tests/RiskSteward.t.sol | 20 +++----------------- 4 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/contracts/RiskSteward.sol b/src/contracts/RiskSteward.sol index 019104e..3921973 100644 --- a/src/contracts/RiskSteward.sol +++ b/src/contracts/RiskSteward.sol @@ -7,6 +7,7 @@ import {Address} from 'openzeppelin-contracts/contracts/utils/Address.sol'; import {SafeCast} from 'openzeppelin-contracts/contracts/utils/math/SafeCast.sol'; import {EngineFlags} from 'aave-v3-origin/src/contracts/extensions/v3-config-engine/EngineFlags.sol'; import {Ownable} from 'openzeppelin-contracts/contracts/access/Ownable.sol'; +import {Strings} from 'openzeppelin-contracts/contracts/utils/Strings.sol'; import {IAaveV3ConfigEngine as IEngine} from 'aave-v3-origin/src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol'; import {IRiskSteward} from '../interfaces/IRiskSteward.sol'; import {IDefaultInterestRateStrategyV2} from 'aave-v3-origin/src/contracts/interfaces/IDefaultInterestRateStrategyV2.sol'; @@ -21,6 +22,7 @@ import {IPriceCapAdapterStable} from 'aave-capo/interfaces/IPriceCapAdapterStabl */ contract RiskSteward is Ownable, IRiskSteward { using ReserveConfiguration for DataTypes.ReserveConfigurationMap; + using Strings for string; using Address for address; using SafeCast for uint256; using SafeCast for int256; @@ -339,6 +341,8 @@ contract RiskSteward is Ownable, IRiskSteward { for (uint256 i = 0; i < eModeCategoryUpdates.length; i++) { uint8 eModeId = eModeCategoryUpdates[i].eModeCategory; if (_restrictedEModes[eModeId]) revert EModeIsRestricted(); + if (!eModeCategoryUpdates[i].label.equal(EngineFlags.KEEP_CURRENT_STRING)) + revert ParamChangeNotAllowed(); if ( eModeCategoryUpdates[i].ltv == 0 || diff --git a/tests/EdgeRiskStewardCaps.t.sol b/tests/EdgeRiskStewardCaps.t.sol index b6a8e9f..0fb9c91 100644 --- a/tests/EdgeRiskStewardCaps.t.sol +++ b/tests/EdgeRiskStewardCaps.t.sol @@ -93,7 +93,7 @@ contract EdgeRiskStewardCaps_Test is RiskSteward_Test { function test_updateEModeCategories_sameUpdate() public override {} - function test_updateEModeCategories_onlyLabelChange() public override {} + function test_updateEModeCategories_labelChangeNotAllowed() public override {} /* ----------------------------- LST Price Cap Tests ----------------------------- */ diff --git a/tests/EdgeRiskStewardRates.t.sol b/tests/EdgeRiskStewardRates.t.sol index 6f231ea..31a272a 100644 --- a/tests/EdgeRiskStewardRates.t.sol +++ b/tests/EdgeRiskStewardRates.t.sol @@ -95,7 +95,7 @@ contract EdgeRiskStewardRates_Test is RiskSteward_Test { function test_updateEModeCategories_sameUpdate() public override {} - function test_updateEModeCategories_onlyLabelChange() public override {} + function test_updateEModeCategories_labelChangeNotAllowed() public override {} /* ----------------------------- LST Price Cap Tests ----------------------------- */ diff --git a/tests/RiskSteward.t.sol b/tests/RiskSteward.t.sol index bebdf20..7f04cc1 100644 --- a/tests/RiskSteward.t.sol +++ b/tests/RiskSteward.t.sol @@ -1093,7 +1093,7 @@ contract RiskSteward_Test is Test { assertEq(afterLastUpdated.eModeLiquidationBonusLastUpdated, block.timestamp); } - function test_updateEModeCategories_onlyLabelChange() public virtual { + function test_updateEModeCategories_labelChangeNotAllowed() public virtual { uint8 eModeId = 1; string memory newLabel = 'NEW_EMODE_LABEL'; @@ -1106,22 +1106,8 @@ contract RiskSteward_Test is Test { label: newLabel }); - vm.startPrank(riskCouncil); - steward.updateEModeCategories(eModeCategoryUpdates); - - string memory afterLabel = AaveV3Ethereum.POOL.getEModeCategoryLabel(eModeId); - assertEq(newLabel, afterLabel); - - eModeCategoryUpdates[0] = IEngine.EModeCategoryUpdate({ - eModeCategory: eModeId, - ltv: EngineFlags.KEEP_CURRENT, - liqThreshold: EngineFlags.KEEP_CURRENT, - liqBonus: EngineFlags.KEEP_CURRENT, - label: 'LABEL_CHANGE_AGAIN' - }); - - // no timelock for label change - vm.startPrank(riskCouncil); + vm.prank(riskCouncil); + vm.expectRevert(IRiskSteward.ParamChangeNotAllowed.selector); steward.updateEModeCategories(eModeCategoryUpdates); } From bcf0cdf641ed0a9843f895dbd0a3e95eccbdcfcb Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Wed, 2 Apr 2025 18:47:11 +0530 Subject: [PATCH 25/25] refactor: rename to updatePendleDiscountRates --- scripts/deploy/DeployCapInjector.s.sol | 2 +- scripts/deploy/DeployRateInjector.s.sol | 2 +- scripts/deploy/DeployStewards.s.sol | 2 +- src/contracts/EdgeRiskStewardCaps.sol | 4 +- src/contracts/EdgeRiskStewardRates.sol | 4 +- src/contracts/RiskSteward.sol | 40 +++++++------- src/interfaces/IRiskSteward.sol | 12 ++--- tests/RiskSteward.t.sol | 2 +- tests/RiskStewardCapo.t.sol | 70 ++++++++++++------------- 9 files changed, 69 insertions(+), 69 deletions(-) diff --git a/scripts/deploy/DeployCapInjector.s.sol b/scripts/deploy/DeployCapInjector.s.sol index e7f85fb..bd79317 100644 --- a/scripts/deploy/DeployCapInjector.s.sol +++ b/scripts/deploy/DeployCapInjector.s.sol @@ -76,7 +76,7 @@ library DeployStewardContracts { priceCapConfig: IRiskSteward.PriceCapConfig({ priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 5_00}), priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), - priceCapPendle: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00}) + discountRatePendle: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00}) }) }); } diff --git a/scripts/deploy/DeployRateInjector.s.sol b/scripts/deploy/DeployRateInjector.s.sol index 7467ec8..802c059 100644 --- a/scripts/deploy/DeployRateInjector.s.sol +++ b/scripts/deploy/DeployRateInjector.s.sol @@ -74,7 +74,7 @@ library DeployStewardContracts { priceCapConfig: IRiskSteward.PriceCapConfig({ priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 5_00}), priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}), - priceCapPendle: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 20_00}) + discountRatePendle: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 20_00}) }) }); } diff --git a/scripts/deploy/DeployStewards.s.sol b/scripts/deploy/DeployStewards.s.sol index a956ff3..8177c3e 100644 --- a/scripts/deploy/DeployStewards.s.sol +++ b/scripts/deploy/DeployStewards.s.sol @@ -78,7 +78,7 @@ library DeployRiskStewards { priceCapConfig: IRiskSteward.PriceCapConfig({ priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 5_00}), priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}), - priceCapPendle: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00}) + discountRatePendle: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00}) }) }); } diff --git a/src/contracts/EdgeRiskStewardCaps.sol b/src/contracts/EdgeRiskStewardCaps.sol index 9589c8d..a865f0d 100644 --- a/src/contracts/EdgeRiskStewardCaps.sol +++ b/src/contracts/EdgeRiskStewardCaps.sol @@ -61,8 +61,8 @@ contract EdgeRiskStewardCaps is RiskSteward { } /// @inheritdoc IRiskSteward - function updatePendlePriceCaps( - PriceCapPendleUpdate[] calldata + function updatePendleDiscountRates( + DiscountRatePendleUpdate[] calldata ) external virtual override onlyRiskCouncil { revert UpdateNotAllowed(); } diff --git a/src/contracts/EdgeRiskStewardRates.sol b/src/contracts/EdgeRiskStewardRates.sol index 5cc9406..e1a7376 100644 --- a/src/contracts/EdgeRiskStewardRates.sol +++ b/src/contracts/EdgeRiskStewardRates.sol @@ -59,8 +59,8 @@ contract EdgeRiskStewardRates is RiskSteward { } /// @inheritdoc IRiskSteward - function updatePendlePriceCaps( - PriceCapPendleUpdate[] calldata + function updatePendleDiscountRates( + DiscountRatePendleUpdate[] calldata ) external virtual override onlyRiskCouncil { revert UpdateNotAllowed(); } diff --git a/src/contracts/RiskSteward.sol b/src/contracts/RiskSteward.sol index 7fae7cb..5255964 100644 --- a/src/contracts/RiskSteward.sol +++ b/src/contracts/RiskSteward.sol @@ -122,11 +122,11 @@ contract RiskSteward is Ownable, IRiskSteward { } /// @inheritdoc IRiskSteward - function updatePendlePriceCaps( - PriceCapPendleUpdate[] calldata priceCapUpdates + function updatePendleDiscountRates( + DiscountRatePendleUpdate[] calldata discountRateUpdates ) external virtual onlyRiskCouncil { - _validatePendlePriceCapUpdate(priceCapUpdates); - _updatePendlePriceCaps(priceCapUpdates); + _validatePendleDiscountRateUpdate(discountRateUpdates); + _updatePendleDiscountRates(discountRateUpdates); } /// @inheritdoc IRiskSteward @@ -456,19 +456,19 @@ contract RiskSteward is Ownable, IRiskSteward { } /** - * @notice method to validate the pendle oracle price caps update - * @param priceCapsUpdate list containing the new price cap values for the oracles + * @notice method to validate the pendle oracle discount rate update + * @param discountRateUpdate list containing the new discount rate values for the pendle oracles */ - function _validatePendlePriceCapUpdate( - PriceCapPendleUpdate[] calldata priceCapsUpdate + function _validatePendleDiscountRateUpdate( + DiscountRatePendleUpdate[] calldata discountRateUpdate ) internal view { - if (priceCapsUpdate.length == 0) revert NoZeroUpdates(); + if (discountRateUpdate.length == 0) revert NoZeroUpdates(); - for (uint256 i = 0; i < priceCapsUpdate.length; i++) { - address oracle = priceCapsUpdate[i].oracle; + for (uint256 i = 0; i < discountRateUpdate.length; i++) { + address oracle = discountRateUpdate[i].oracle; if (_restrictedAddresses[oracle]) revert OracleIsRestricted(); - if (priceCapsUpdate[i].discountRate == 0) revert InvalidUpdateToZero(); + if (discountRateUpdate[i].discountRate == 0) revert InvalidUpdateToZero(); // get current rate uint256 currentDiscount = IPendlePriceCapAdapter(oracle).discountRatePerYear(); @@ -476,9 +476,9 @@ contract RiskSteward is Ownable, IRiskSteward { _validateParamUpdate( ParamUpdateValidationInput({ currentValue: currentDiscount, - newValue: priceCapsUpdate[i].discountRate, + newValue: discountRateUpdate[i].discountRate, lastUpdated: _timelocks[oracle].priceCapLastUpdated, - riskConfig: _riskConfig.priceCapConfig.priceCapPendle, + riskConfig: _riskConfig.priceCapConfig.discountRatePendle, isChangeRelative: true }) ); @@ -643,16 +643,16 @@ contract RiskSteward is Ownable, IRiskSteward { } /** - * @notice method to update the pendle oracle price caps update - * @param priceCapsUpdate list containing the new price cap values for the oracles + * @notice method to update the pendle oracle discount rate + * @param discountRateUpdate list containing the new discount rate values for the pendle oracles */ - function _updatePendlePriceCaps(PriceCapPendleUpdate[] calldata priceCapsUpdate) internal { - for (uint256 i = 0; i < priceCapsUpdate.length; i++) { - address oracle = priceCapsUpdate[i].oracle; + function _updatePendleDiscountRates(DiscountRatePendleUpdate[] calldata discountRateUpdate) internal { + for (uint256 i = 0; i < discountRateUpdate.length; i++) { + address oracle = discountRateUpdate[i].oracle; _timelocks[oracle].priceCapLastUpdated = uint40(block.timestamp); - IPendlePriceCapAdapter(oracle).setDiscountRatePerYear(priceCapsUpdate[i].discountRate.toUint64()); + IPendlePriceCapAdapter(oracle).setDiscountRatePerYear(discountRateUpdate[i].discountRate.toUint64()); } } diff --git a/src/interfaces/IRiskSteward.sol b/src/interfaces/IRiskSteward.sol index 735ab3e..2df01f0 100644 --- a/src/interfaces/IRiskSteward.sol +++ b/src/interfaces/IRiskSteward.sol @@ -190,7 +190,7 @@ interface IRiskSteward { struct PriceCapConfig { RiskParamConfig priceCapLst; RiskParamConfig priceCapStable; - RiskParamConfig priceCapPendle; + RiskParamConfig discountRatePendle; } /** @@ -212,7 +212,7 @@ interface IRiskSteward { /** * @notice Struct used to update the pendle cap params */ - struct PriceCapPendleUpdate { + struct DiscountRatePendleUpdate { address oracle; uint256 discountRate; } @@ -282,11 +282,11 @@ interface IRiskSteward { /** * @notice Allows updating pendle price cap params (i.e discount rate) across multiple oracles - * @dev A price cap update is only possible after minDelay has passed after last update - * @dev A price cap increase / decrease is only allowed by a magnitude of maxPercentChange - * @param priceCapUpdates struct containing new price cap params to be updated + * @dev A price cap (i.e discount rate) update is only possible after minDelay has passed after last update + * @dev A price cap (i.e discount rate) increase / decrease is only allowed by a magnitude of maxPercentChange + * @param discountRateUpdates struct containing new price cap params (i.e discount rate) to be updated */ - function updatePendlePriceCaps(PriceCapPendleUpdate[] calldata priceCapUpdates) external; + function updatePendleDiscountRates(DiscountRatePendleUpdate[] calldata discountRateUpdates) external; /** * @notice method to check if an asset/oracle is restricted to be used by the risk stewards diff --git a/tests/RiskSteward.t.sol b/tests/RiskSteward.t.sol index 421dfef..36d5c93 100644 --- a/tests/RiskSteward.t.sol +++ b/tests/RiskSteward.t.sol @@ -1261,7 +1261,7 @@ contract RiskSteward_Test is Test { priceCapConfig: IRiskSteward.PriceCapConfig({ priceCapLst: newRiskParamConfig, priceCapStable: newRiskParamConfig, - priceCapPendle: newRiskParamConfig + discountRatePendle: newRiskParamConfig }) }); diff --git a/tests/RiskStewardCapo.t.sol b/tests/RiskStewardCapo.t.sol index 6409072..28026f1 100644 --- a/tests/RiskStewardCapo.t.sol +++ b/tests/RiskStewardCapo.t.sol @@ -37,7 +37,7 @@ contract RiskSteward_Capo_Test is Test { IRiskSteward.Config memory riskConfig; riskConfig.priceCapConfig.priceCapLst = defaultRiskParamConfig; riskConfig.priceCapConfig.priceCapStable = defaultRiskParamConfig; - riskConfig.priceCapConfig.priceCapPendle = defaultRiskParamConfig; + riskConfig.priceCapConfig.discountRatePendle = defaultRiskParamConfig; steward = new RiskSteward( address(AaveV3Ethereum.POOL), @@ -558,16 +558,16 @@ contract RiskSteward_Capo_Test is Test { function test_updatePendlePriceCap() public { uint256 currentDiscount = pendleAdapter.discountRatePerYear(); - IRiskSteward.PriceCapPendleUpdate[] - memory priceCapUpdates = new IRiskSteward.PriceCapPendleUpdate[](1); + IRiskSteward.DiscountRatePendleUpdate[] + memory priceCapUpdates = new IRiskSteward.DiscountRatePendleUpdate[](1); - priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + priceCapUpdates[0] = IRiskSteward.DiscountRatePendleUpdate({ oracle: address(pendleAdapter), discountRate: ((currentDiscount * 110) / 100) // +10% relative change }); vm.startPrank(riskCouncil); - steward.updatePendlePriceCaps(priceCapUpdates); + steward.updatePendleDiscountRates(priceCapUpdates); RiskSteward.Debounce memory lastUpdated = steward.getTimelock(address(pendleAdapter)); @@ -580,12 +580,12 @@ contract RiskSteward_Capo_Test is Test { vm.warp(block.timestamp + 5 days + 1); currentDiscount = pendleAdapter.discountRatePerYear(); - priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + priceCapUpdates[0] = IRiskSteward.DiscountRatePendleUpdate({ oracle: address(pendleAdapter), discountRate: ((currentDiscount * 90) / 100) // -10% relative change }); - steward.updatePendlePriceCaps(priceCapUpdates); + steward.updatePendleDiscountRates(priceCapUpdates); lastUpdated = steward.getTimelock(address(pendleAdapter)); @@ -598,33 +598,33 @@ contract RiskSteward_Capo_Test is Test { function test_updatePendlePriceCap_debounceNotRespected() public { uint256 currentDiscount = pendleAdapter.discountRatePerYear(); - IRiskSteward.PriceCapPendleUpdate[] - memory priceCapUpdates = new IRiskSteward.PriceCapPendleUpdate[](1); + IRiskSteward.DiscountRatePendleUpdate[] + memory priceCapUpdates = new IRiskSteward.DiscountRatePendleUpdate[](1); - priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + priceCapUpdates[0] = IRiskSteward.DiscountRatePendleUpdate({ oracle: address(pendleAdapter), discountRate: ((currentDiscount * 110) / 100) // +10% relative change }); vm.startPrank(riskCouncil); - steward.updatePendlePriceCaps(priceCapUpdates); + steward.updatePendleDiscountRates(priceCapUpdates); - priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + priceCapUpdates[0] = IRiskSteward.DiscountRatePendleUpdate({ oracle: address(pendleAdapter), discountRate: ((currentDiscount * 105) / 100) // +10% relative change }); // expect revert as minimum time has not passed for next update vm.expectRevert(IRiskSteward.DebounceNotRespected.selector); - steward.updatePendlePriceCaps(priceCapUpdates); + steward.updatePendleDiscountRates(priceCapUpdates); } function test_updatePendlePriceCap_outOfRange() public { uint256 currentDiscount = pendleAdapter.discountRatePerYear(); - IRiskSteward.PriceCapPendleUpdate[] - memory priceCapUpdates = new IRiskSteward.PriceCapPendleUpdate[](1); + IRiskSteward.DiscountRatePendleUpdate[] + memory priceCapUpdates = new IRiskSteward.DiscountRatePendleUpdate[](1); - priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + priceCapUpdates[0] = IRiskSteward.DiscountRatePendleUpdate({ oracle: address(pendleAdapter), discountRate: ((currentDiscount * 111) / 100) // +11% relative increase }); @@ -632,21 +632,21 @@ contract RiskSteward_Capo_Test is Test { // expect revert as price cap (discountRate) is out of range vm.expectRevert(IRiskSteward.UpdateNotInRange.selector); - steward.updatePendlePriceCaps(priceCapUpdates); + steward.updatePendleDiscountRates(priceCapUpdates); - priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + priceCapUpdates[0] = IRiskSteward.DiscountRatePendleUpdate({ oracle: address(pendleAdapter), discountRate: ((currentDiscount * 89) / 100) // -11% relative decrease }); vm.expectRevert(IRiskSteward.UpdateNotInRange.selector); - steward.updatePendlePriceCaps(priceCapUpdates); + steward.updatePendleDiscountRates(priceCapUpdates); } function test_updatePendlePriceCap_keepCurrent_revert() public { - IRiskSteward.PriceCapPendleUpdate[] - memory priceCapUpdates = new IRiskSteward.PriceCapPendleUpdate[](1); + IRiskSteward.DiscountRatePendleUpdate[] + memory priceCapUpdates = new IRiskSteward.DiscountRatePendleUpdate[](1); - priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + priceCapUpdates[0] = IRiskSteward.DiscountRatePendleUpdate({ oracle: address(pendleAdapter), discountRate: EngineFlags.KEEP_CURRENT }); @@ -654,14 +654,14 @@ contract RiskSteward_Capo_Test is Test { // expect revert as price cap is out of range vm.expectRevert(); - steward.updatePendlePriceCaps(priceCapUpdates); + steward.updatePendleDiscountRates(priceCapUpdates); } function test_updatePendlePriceCap_toValueZeroNotAllowed() public { - IRiskSteward.PriceCapPendleUpdate[] - memory priceCapUpdates = new IRiskSteward.PriceCapPendleUpdate[](1); + IRiskSteward.DiscountRatePendleUpdate[] + memory priceCapUpdates = new IRiskSteward.DiscountRatePendleUpdate[](1); - priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + priceCapUpdates[0] = IRiskSteward.DiscountRatePendleUpdate({ oracle: address(pendleAdapter), discountRate: 0 }); @@ -669,7 +669,7 @@ contract RiskSteward_Capo_Test is Test { // expect revert as price cap is out of range vm.expectRevert(IRiskSteward.InvalidUpdateToZero.selector); - steward.updatePendlePriceCaps(priceCapUpdates); + steward.updatePendleDiscountRates(priceCapUpdates); } function test_updatePendlePriceCap_oracleRestricted() public { @@ -677,10 +677,10 @@ contract RiskSteward_Capo_Test is Test { steward.setAddressRestricted(address(pendleAdapter), true); uint256 currentDiscount = pendleAdapter.discountRatePerYear(); - IRiskSteward.PriceCapPendleUpdate[] - memory priceCapUpdates = new IRiskSteward.PriceCapPendleUpdate[](1); + IRiskSteward.DiscountRatePendleUpdate[] + memory priceCapUpdates = new IRiskSteward.DiscountRatePendleUpdate[](1); - priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + priceCapUpdates[0] = IRiskSteward.DiscountRatePendleUpdate({ oracle: address(pendleAdapter), discountRate: ((currentDiscount * 110) / 100) // +10% relative change }); @@ -688,20 +688,20 @@ contract RiskSteward_Capo_Test is Test { // expect revert as oracle is restricted vm.expectRevert(IRiskSteward.OracleIsRestricted.selector); - steward.updatePendlePriceCaps(priceCapUpdates); + steward.updatePendleDiscountRates(priceCapUpdates); } function test_updatePendlePriceCap_sameUpdates() public { uint256 initialDiscount = pendleAdapter.discountRatePerYear(); - IRiskSteward.PriceCapPendleUpdate[] - memory priceCapUpdates = new IRiskSteward.PriceCapPendleUpdate[](1); + IRiskSteward.DiscountRatePendleUpdate[] + memory priceCapUpdates = new IRiskSteward.DiscountRatePendleUpdate[](1); - priceCapUpdates[0] = IRiskSteward.PriceCapPendleUpdate({ + priceCapUpdates[0] = IRiskSteward.DiscountRatePendleUpdate({ oracle: address(pendleAdapter), discountRate: initialDiscount }); vm.prank(riskCouncil); - steward.updatePendlePriceCaps(priceCapUpdates); + steward.updatePendleDiscountRates(priceCapUpdates); uint256 afterDiscount = pendleAdapter.discountRatePerYear(); assertEq(initialDiscount, afterDiscount);