Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Some assets/oracles can also be restricted on the RiskStewards by calling the `s

With the introduction of Edge Risk Oracles by Chaos Labs, which leverages advanced off-chain infrastructure to deliver real-time risk updates to the Aave protocol via the Risk Oracle, the risk updates for the Aave protocol can be automated in a constrained manner. This can be done by combining the Edge Risk Oracle with the Aave Risk Steward, using a middleware contract `AaveStewardsInjector`.

The Aave Risk Steward contract used for automated updates (called now [EdgeRiskSteward](./src/contracts/EdgeRiskSteward.sol)), has been slightly modified to only allow Interest Rates Updates on the protocol initially as a matter of extra security considerations.
The Aave Risk Steward contract used for automated updates (called now [EdgeRiskStewardRates](./src/contracts/EdgeRiskStewardRates.sol)), has been slightly modified to only allow Interest Rates Updates on the protocol initially as a matter of extra security considerations.

The following is a simple diagram of how the system works as a whole:

Expand Down
3 changes: 1 addition & 2 deletions scripts/RiskStewardsBase.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,7 @@ abstract contract RiskStewardsBase is ProtocolV3TestBase {
vm.warp(block.timestamp + uint256(maxTimelock) + 1);
}

if (generateDiffReport)
createConfigurationSnapshot(pre, POOL, true, true, false, false);
if (generateDiffReport) createConfigurationSnapshot(pre, POOL, true, true, false, false);

if (capUpdates.length != 0) {
callDatas[txCount] = abi.encodeWithSelector(IRiskSteward.updateCaps.selector, capUpdates);
Expand Down
124 changes: 124 additions & 0 deletions scripts/deploy/DeployCapInjector.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import 'solidity-utils/contracts/utils/ScriptUtils.sol';
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 {AaveStewardInjectorCaps} from '../../src/contracts/AaveStewardInjectorCaps.sol';

library DeployStewardContracts {
address constant EDGE_RISK_ORACLE = 0x861eeAdB55E41f161F31Acb1BFD4c70E3a964Aed;

function _deployRiskStewards(
address poolDataProvider,
address configEngine,
address riskCouncil,
address governance
) internal returns (address) {
address riskSteward = address(
new EdgeRiskStewardCaps(
IPoolDataProvider(poolDataProvider),
IEngine(configEngine),
riskCouncil,
_getRiskConfig()
)
);
IOwnable(riskSteward).transferOwnership(governance);
return riskSteward;
}

function _deployCapsStewardInjector(
bytes32 salt,
address riskSteward,
address owner,
address guardian,
address[] memory whitelistedMarkets
) internal returns (address) {
address stewardInjector = ICreate3Factory(MiscArbitrum.CREATE_3_FACTORY).create(
salt,
abi.encodePacked(
type(AaveStewardInjectorCaps).creationCode,
abi.encode(EDGE_RISK_ORACLE, riskSteward, msg.sender, guardian)
)
);
AaveStewardInjectorCaps(stewardInjector).addMarkets(whitelistedMarkets);
AaveStewardInjectorCaps(stewardInjector).transferOwnership(owner);
return stewardInjector;
}

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
}),
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
}),
variableRateSlope1: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}),
variableRateSlope2: IRiskSteward.RiskParamConfig({
minDelay: 3 days,
maxPercentChange: 5_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})
});
}
}

// make deploy-ledger contract=scripts/deploy/DeployCapInjector.s.sol:DeployArbitrum chain=arbitrum
contract DeployArbitrum is ArbitrumScript {
address constant GUARDIAN = 0x87dFb794364f2B117C8dbaE29EA622938b3Ce465;

function run() external {
vm.startBroadcast();
bytes32 salt = 'CapsStewardInjector';
address predictedStewardsInjector = ICreate3Factory(MiscArbitrum.CREATE_3_FACTORY)
.predictAddress(msg.sender, salt);

address riskSteward = DeployStewardContracts._deployRiskStewards(
address(AaveV3Arbitrum.AAVE_PROTOCOL_DATA_PROVIDER),
AaveV3Arbitrum.CONFIG_ENGINE,
predictedStewardsInjector,
GovernanceV3Arbitrum.EXECUTOR_LVL_1
);

address[] memory whitelistedMarkets = new address[](15);
whitelistedMarkets[0] = AaveV3ArbitrumAssets.WETH_A_TOKEN;
whitelistedMarkets[1] = AaveV3ArbitrumAssets.USDC_A_TOKEN;
whitelistedMarkets[2] = AaveV3ArbitrumAssets.USDT_A_TOKEN;
whitelistedMarkets[3] = AaveV3ArbitrumAssets.WBTC_A_TOKEN;
whitelistedMarkets[4] = AaveV3ArbitrumAssets.DAI_A_TOKEN;
whitelistedMarkets[5] = AaveV3ArbitrumAssets.weETH_A_TOKEN;
whitelistedMarkets[6] = AaveV3ArbitrumAssets.ARB_A_TOKEN;
whitelistedMarkets[7] = AaveV3ArbitrumAssets.USDCn_A_TOKEN;
whitelistedMarkets[8] = AaveV3ArbitrumAssets.GHO_A_TOKEN;
whitelistedMarkets[9] = AaveV3ArbitrumAssets.LINK_A_TOKEN;
whitelistedMarkets[10] = AaveV3ArbitrumAssets.wstETH_A_TOKEN;
whitelistedMarkets[11] = AaveV3ArbitrumAssets.LUSD_A_TOKEN;
whitelistedMarkets[12] = AaveV3ArbitrumAssets.FRAX_A_TOKEN;
whitelistedMarkets[13] = AaveV3ArbitrumAssets.rETH_A_TOKEN;
whitelistedMarkets[14] = AaveV3ArbitrumAssets.AAVE_A_TOKEN;

DeployStewardContracts._deployCapsStewardInjector(
salt,
riskSteward,
GovernanceV3Arbitrum.EXECUTOR_LVL_1,
GUARDIAN,
whitelistedMarkets
);
vm.stopBroadcast();
}
}
90 changes: 0 additions & 90 deletions scripts/deploy/DeployInjector.s.sol

This file was deleted.

105 changes: 105 additions & 0 deletions scripts/deploy/DeployRateInjector.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import 'solidity-utils/contracts/utils/ScriptUtils.sol';
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 {AaveStewardInjectorRates} from '../../src/contracts/AaveStewardInjectorRates.sol';

library DeployStewardContracts {
address constant EDGE_RISK_ORACLE = 0x7ABB46C690C52E919687D19ebF89C81A6136C1F2;

function _deployRiskStewards(
address poolDataProvider,
address configEngine,
address riskCouncil,
address governance
) internal returns (address) {
address riskSteward = address(
new EdgeRiskStewardRates(
IPoolDataProvider(poolDataProvider),
IEngine(configEngine),
riskCouncil,
_getRiskConfig()
)
);
IOwnable(riskSteward).transferOwnership(governance);
return riskSteward;
}

function _deployRatesStewardInjector(
bytes32 salt,
address riskSteward,
address owner,
address guardian,
address whitelistedAsset
) internal returns (address) {
address stewardInjector = ICreate3Factory(MiscEthereum.CREATE_3_FACTORY).create(
salt,
abi.encodePacked(
type(AaveStewardInjectorRates).creationCode,
abi.encode(EDGE_RISK_ORACLE, riskSteward, owner, guardian, whitelistedAsset)
)
);
return stewardInjector;
}

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
}),
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
}),
variableRateSlope1: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}),
variableRateSlope2: IRiskSteward.RiskParamConfig({
minDelay: 1 days,
maxPercentChange: 5_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})
});
}
}

// make deploy-ledger contract=scripts/deploy/DeployRateInjector.s.sol:DeployEthereumLido chain=mainnet
contract DeployEthereumLido is EthereumScript {
address constant GUARDIAN = 0xff37939808EcF199A2D599ef91D699Fb13dab7F7;

function run() external {
vm.startBroadcast();
bytes32 salt = 'StewardInjector';
address predictedStewardsInjector = ICreate3Factory(MiscEthereum.CREATE_3_FACTORY)
.predictAddress(msg.sender, salt);

address riskSteward = DeployStewardContracts._deployRiskStewards(
address(AaveV3EthereumLido.AAVE_PROTOCOL_DATA_PROVIDER),
AaveV3EthereumLido.CONFIG_ENGINE,
predictedStewardsInjector,
GovernanceV3Ethereum.EXECUTOR_LVL_1
);

DeployStewardContracts._deployRatesStewardInjector(
salt,
riskSteward,
GovernanceV3Ethereum.EXECUTOR_LVL_1,
GUARDIAN,
AaveV3EthereumLidoAssets.WETH_UNDERLYING
);
vm.stopBroadcast();
}
}
Loading
Loading