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 scripts/deploy/DeployCapInjector.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ library DeployStewardContracts {
priceCapConfig: IRiskSteward.PriceCapConfig({
priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 5_00}),
priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}),
discountRatePendle: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00})
discountRatePendle: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 5_00})
})
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol';
import {AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol';
import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol';
import {ICreate3Factory} from 'solidity-utils/contracts/create3/interfaces/ICreate3Factory.sol';
import {EdgeRiskStewardCollateral, IRiskSteward} from '../../src/contracts/EdgeRiskStewardCollateral.sol';
import {AaveStewardInjectorCollateral} from '../../src/contracts/AaveStewardInjectorCollateral.sol';
import {EdgeRiskStewardEMode, IRiskSteward} from '../../src/contracts/EdgeRiskStewardEMode.sol';
import {AaveStewardInjectorEMode} from '../../src/contracts/AaveStewardInjectorEMode.sol';

library DeployStewardContracts {
function _deployRiskStewards(
Expand All @@ -17,24 +17,29 @@ library DeployStewardContracts {
address governance
) internal returns (address) {
address riskSteward = address(
new EdgeRiskStewardCollateral(pool, configEngine, riskCouncil, governance, _getRiskConfig())
new EdgeRiskStewardEMode(pool, configEngine, riskCouncil, governance, _getRiskConfig())
);
return riskSteward;
}

function _deployCollateralStewardInjector(
function _deployEModeStewardInjector(
address create3Factory,
bytes32 salt,
address riskSteward,
address edgeRiskOracle,
address owner,
address guardian,
address[] memory whitelistedMarkets
uint8[] memory whitelistedEModes
) internal returns (address) {
address[] memory whitelistedMarkets = new address[](whitelistedEModes.length);
for (uint256 i = 0; i < whitelistedEModes.length; i++) {
whitelistedMarkets[i] = address(uint160(whitelistedEModes[i]));
}

address stewardInjector = ICreate3Factory(create3Factory).create(
salt,
abi.encodePacked(
type(AaveStewardInjectorCollateral).creationCode,
type(AaveStewardInjectorEMode).creationCode,
abi.encode(edgeRiskOracle, riskSteward, whitelistedMarkets, owner, guardian)
)
);
Expand Down Expand Up @@ -87,22 +92,22 @@ library DeployStewardContracts {
priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 5_00}),
priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}),
discountRatePendle: IRiskSteward.RiskParamConfig({
minDelay: 3 days,
maxPercentChange: 20_00
minDelay: 2 days,
maxPercentChange: 5_00
})
})
});
}
}

// make deploy-ledger contract=scripts/deploy/DeployCollateralInjector.s.sol:DeployEthereum chain=mainnet
// make deploy-ledger contract=scripts/deploy/DeployEModeInjector.s.sol:DeployEthereum chain=mainnet
contract DeployEthereum is EthereumScript {
address constant GUARDIAN = 0xff37939808EcF199A2D599ef91D699Fb13dab7F7;
address constant EDGE_RISK_ORACLE = address(0); // TODO

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

Expand All @@ -113,17 +118,17 @@ contract DeployEthereum is EthereumScript {
GovernanceV3Ethereum.EXECUTOR_LVL_1
);

address[] memory whitelistedMarkets = new address[](1);
whitelistedMarkets[0] = address(0); // TODO: add listed pendle PT asset
uint8[] memory whitelistedEModes = new uint8[](1);
whitelistedEModes[0] = 8;

DeployStewardContracts._deployCollateralStewardInjector(
DeployStewardContracts._deployEModeStewardInjector(
MiscEthereum.CREATE_3_FACTORY,
salt,
riskSteward,
EDGE_RISK_ORACLE,
GovernanceV3Ethereum.EXECUTOR_LVL_1,
GUARDIAN,
whitelistedMarkets
whitelistedEModes
);
vm.stopBroadcast();
}
Expand Down
2 changes: 1 addition & 1 deletion scripts/deploy/DeployRateInjector.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ library DeployStewardContracts {
priceCapConfig: IRiskSteward.PriceCapConfig({
priceCapLst: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 5_00}),
priceCapStable: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 50}),
discountRatePendle: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 20_00})
discountRatePendle: IRiskSteward.RiskParamConfig({minDelay: 1 days, maxPercentChange: 5_00})
})
});
}
Expand Down
4 changes: 2 additions & 2 deletions scripts/deploy/DeployStewards.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ library DeployRiskStewards {
}),
eModeConfig: IRiskSteward.EmodeConfig({
ltv: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}),
liquidationThreshold: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50}),
liquidationThreshold: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 10}),
liquidationBonus: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 50})
}),
rateConfig: IRiskSteward.RateConfig({
Expand All @@ -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}),
discountRatePendle: IRiskSteward.RiskParamConfig({minDelay: 3 days, maxPercentChange: 20_00})
discountRatePendle: IRiskSteward.RiskParamConfig({minDelay: 2 days, maxPercentChange: 5_00})
})
});
}
Expand Down
8 changes: 4 additions & 4 deletions src/contracts/AaveStewardInjectorBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ abstract contract AaveStewardInjectorBase is
/// @inheritdoc IAaveStewardInjectorBase
function removeMarkets(address[] calldata markets) external onlyOwner {
for (uint256 i = 0; i < markets.length; i++) {
_markets.remove(markets[i]);
emit MarketRemoved(markets[i]);
bool success = _markets.remove(markets[i]);
if (success) emit MarketRemoved(markets[i]);
}
}

Expand Down Expand Up @@ -211,8 +211,8 @@ abstract contract AaveStewardInjectorBase is
*/
function _addMarkets(address[] memory markets) internal {
for (uint256 i = 0; i < markets.length; i++) {
_markets.add(markets[i]);
emit MarketAdded(markets[i]);
bool success = _markets.add(markets[i]);
if (success) emit MarketAdded(markets[i]);
}
}

Expand Down
6 changes: 2 additions & 4 deletions src/contracts/AaveStewardInjectorCaps.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,9 @@ contract AaveStewardInjectorCaps is AaveStewardInjectorBase {
}

/// @inheritdoc AaveStewardInjectorBase
function _injectUpdate(
IRiskOracle.RiskParameterUpdate memory riskParams
) internal override {
function _injectUpdate(IRiskOracle.RiskParameterUpdate memory riskParams) internal override {
address underlyingAddress = IAToken(riskParams.market).UNDERLYING_ASSET_ADDRESS();
uint256 capValue = abi.decode(
uint256 capValue = abi.decode(
abi.encodePacked(new bytes(32 - riskParams.newValue.length), riskParams.newValue),
(uint256)
) / (10 ** IERC20Metadata(riskParams.market).decimals());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,26 @@ pragma solidity ^0.8.0;
import {IRiskOracle} from './dependencies/IRiskOracle.sol';
import {IRiskSteward} from '../interfaces/IRiskSteward.sol';
import {AaveStewardInjectorBase} from './AaveStewardInjectorBase.sol';
import {SafeCast} from 'openzeppelin-contracts/contracts/utils/math/SafeCast.sol';
import {IAaveV3ConfigEngine as IEngine} from 'aave-v3-origin/src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol';
import {EngineFlags} from 'aave-v3-origin/src/contracts/extensions/v3-config-engine/EngineFlags.sol';
import {IAToken} from 'aave-v3-origin/src/contracts/interfaces/IAToken.sol';

/**
* @title AaveStewardInjectorCollateral
* @title AaveStewardInjectorEMode
* @author BGD Labs
* @notice Aave chainlink automation-keeper-compatible contract to perform collateral update injection
* @notice Aave chainlink automation-keeper-compatible contract to perform EMode category update injection
* on risk steward using the edge risk oracle.
*/
contract AaveStewardInjectorCollateral is AaveStewardInjectorBase {
contract AaveStewardInjectorEMode is AaveStewardInjectorBase {
using SafeCast for uint160;

/// @notice Struct containing the eMode category update
struct EModeCategoryUpdate {
uint256 ltv;
uint256 liqThreshold;
uint256 liqBonus;
}

/**
* @param riskOracle address of the edge risk oracle contract.
* @param riskSteward address of the risk steward contract.
Expand All @@ -33,25 +42,24 @@ contract AaveStewardInjectorCollateral is AaveStewardInjectorBase {
/// @inheritdoc AaveStewardInjectorBase
function getUpdateTypes() public pure override returns (string[] memory updateTypes) {
updateTypes = new string[](1);
updateTypes[0] = 'CollateralUpdate';
updateTypes[0] = 'EModeCategoryUpdate_Core';
}

/// @inheritdoc AaveStewardInjectorBase
function _injectUpdate(
IRiskOracle.RiskParameterUpdate memory riskParams
) internal override {
address underlyingAddress = IAToken(riskParams.market).UNDERLYING_ASSET_ADDRESS();
(uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus) = abi.decode(riskParams.newValue, (uint256, uint256, uint256));

IEngine.CollateralUpdate[] memory collateralUpdate = new IEngine.CollateralUpdate[](1);
collateralUpdate[0] = IEngine.CollateralUpdate({
asset: underlyingAddress,
ltv: ltv,
liqThreshold: liquidationThreshold,
liqBonus: liquidationBonus,
debtCeiling: EngineFlags.KEEP_CURRENT,
liqProtocolFee: EngineFlags.KEEP_CURRENT
function _injectUpdate(IRiskOracle.RiskParameterUpdate memory riskParams) internal override {
EModeCategoryUpdate memory update = abi.decode(riskParams.newValue, (EModeCategoryUpdate));

// eMode category id is encoded in the market address
uint8 eModeId = uint160(riskParams.market).toUint8();

IEngine.EModeCategoryUpdate[] memory eModeUpdate = new IEngine.EModeCategoryUpdate[](1);
eModeUpdate[0] = IEngine.EModeCategoryUpdate({
eModeCategory: eModeId,
ltv: update.ltv,
liqThreshold: update.liqThreshold,
liqBonus: update.liqBonus,
label: EngineFlags.KEEP_CURRENT_STRING
});
IRiskSteward(RISK_STEWARD).updateCollateralSide(collateralUpdate);
IRiskSteward(RISK_STEWARD).updateEModeCategories(eModeUpdate);
}
}
4 changes: 1 addition & 3 deletions src/contracts/AaveStewardInjectorRates.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ contract AaveStewardInjectorRates is AaveStewardInjectorBase {
}

/// @inheritdoc AaveStewardInjectorBase
function _injectUpdate(
IRiskOracle.RiskParameterUpdate memory riskParams
) internal override {
function _injectUpdate(IRiskOracle.RiskParameterUpdate memory riskParams) internal override {
IEngine.RateStrategyUpdate[] memory rateUpdate = new IEngine.RateStrategyUpdate[](1);
rateUpdate[0].asset = riskParams.market;
rateUpdate[0].params = abi.decode(riskParams.newValue, (IEngine.InterestRateInputData));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ pragma solidity ^0.8.0;
import './RiskSteward.sol';

/**
* @title EdgeRiskStewardCollateral
* @title EdgeRiskStewardEMode
* @author BGD labs
* @notice Contract to manage the collateral params updates within configured bound on aave v3 pool.
* @notice Contract to manage the EMode category updates within configured bound on aave v3 pool.
* To be triggered by the Aave Steward Injector Contract in a automated way via the Edge Risk Oracle.
*/
contract EdgeRiskStewardCollateral is RiskSteward {
contract EdgeRiskStewardEMode is RiskSteward {
/**
* @param pool the aave pool to be controlled by the steward
* @param engine the config engine to be used by the steward
Expand Down Expand Up @@ -38,8 +38,8 @@ contract EdgeRiskStewardCollateral is RiskSteward {
}

/// @inheritdoc IRiskSteward
function updateEModeCategories(
IEngine.EModeCategoryUpdate[] calldata
function updateCollateralSide(
IEngine.CollateralUpdate[] calldata
) external virtual override onlyRiskCouncil {
revert UpdateNotAllowed();
}
Expand All @@ -64,19 +64,4 @@ contract EdgeRiskStewardCollateral is RiskSteward {
) external virtual override onlyRiskCouncil {
revert UpdateNotAllowed();
}

/**
* @notice method to validate the collaterals update
* @param collateralUpdates list containing the new collateral updates of the assets
* @dev custom overload to forbid debtCeiling change
*/
function _validateCollateralsUpdate(
IEngine.CollateralUpdate[] calldata collateralUpdates
) internal view override {
for (uint256 i = 0; i < collateralUpdates.length; i++) {
if (collateralUpdates[i].debtCeiling != EngineFlags.KEEP_CURRENT)
revert ParamChangeNotAllowed();
}
super._validateCollateralsUpdate(collateralUpdates);
}
}
Loading
Loading