Skip to content

Commit

Permalink
feat: gho stewards activation payload
Browse files Browse the repository at this point in the history
  • Loading branch information
brotherlymite committed Mar 26, 2024
1 parent c6cc796 commit b976c0b
Show file tree
Hide file tree
Showing 9 changed files with 350 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Raw diff

```json
{}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IProposalGenericExecutor} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol';
import {IGhoStewardV2} from './interfaces/IGhoStewardV2.sol';
import {IGhoToken} from './interfaces/IGho.sol';
import {IGsm} from './interfaces/IGsm.sol';
import {AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol';
import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol';

/**
* @title Activate Gho Stewards
* @author Aave Chan Initiative
* - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x29f63b24638ee822f88632572ca4b061774771c0cc6d0ae5ccdeb538177232cd
* - Discussion: https://governance.aave.com/t/arfc-gho-stewards/16466
*/
contract AaveV3Ethereum_ActivateGhoStewards_20240326 is IProposalGenericExecutor {
address public constant GHO_STEWARD = 0x8F2411a538381aae2b464499005F0211e867d84f;
address public constant GSM_USDC = 0x0d8eFfC11dF3F229AA1EA0509BC9DFa632A13578;
address public constant GSM_USDT = 0x686F8D21520f4ecEc7ba577be08354F4d1EB8262;

function execute() external {
// Give risk admin role to the steward
AaveV3Ethereum.ACL_MANAGER.addRiskAdmin(GHO_STEWARD);

// Give bucket manager role to the steward
IGhoToken(MiscEthereum.GHO_TOKEN).grantRole(
IGhoToken(MiscEthereum.GHO_TOKEN).BUCKET_MANAGER_ROLE(),
GHO_STEWARD
);

// Give configurator role on usdc, usdt gsm to the stewards
IGsm(GSM_USDC).grantRole(IGsm(GSM_USDC).CONFIGURATOR_ROLE(), GHO_STEWARD);
IGsm(GSM_USDT).grantRole(IGsm(GSM_USDT).CONFIGURATOR_ROLE(), GHO_STEWARD);

// Whitelist all the facilitators on the stewards, including: GhoAToken, GhoFlashMinter, GSM USDC, GSM USDT
IGhoStewardV2(GHO_STEWARD).setControlledFacilitator(
IGhoToken(MiscEthereum.GHO_TOKEN).getFacilitatorsList(),
true
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol';

import 'forge-std/Test.sol';
import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/ProtocolV3TestBase.sol';
import {AaveV3Ethereum_ActivateGhoStewards_20240326} from './AaveV3Ethereum_ActivateGhoStewards_20240326.sol';

/**
* @dev Test for AaveV3Ethereum_ActivateGhoStewards_20240326
* command: make test-contract filter=AaveV3Ethereum_ActivateGhoStewards_20240326
*/
contract AaveV3Ethereum_ActivateGhoStewards_20240326_Test is ProtocolV3TestBase {
AaveV3Ethereum_ActivateGhoStewards_20240326 internal proposal;

function setUp() public {
vm.createSelectFork(vm.rpcUrl('mainnet'), 19519644);
proposal = new AaveV3Ethereum_ActivateGhoStewards_20240326();
}

/**
* @dev executes the generic test suite including e2e and config snapshots
*/
function test_defaultProposalExecution() public {
defaultTest(
'AaveV3Ethereum_ActivateGhoStewards_20240326',
AaveV3Ethereum.POOL,
address(proposal)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
title: "Activate Gho Stewards"
author: "Aave Chan Initiative"
discussions: "https://governance.aave.com/t/arfc-gho-stewards/16466"
snapshot: "https://snapshot.org/#/aave.eth/proposal/0x29f63b24638ee822f88632572ca4b061774771c0cc6d0ae5ccdeb538177232cd"
---

## Simple Summary

## Motivation

## Specification

## References

- Implementation: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240326_AaveV3Ethereum_ActivateGhoStewards/AaveV3Ethereum_ActivateGhoStewards_20240326.sol)
- Tests: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240326_AaveV3Ethereum_ActivateGhoStewards/AaveV3Ethereum_ActivateGhoStewards_20240326.t.sol)
- [Snapshot](https://snapshot.org/#/aave.eth/proposal/0x29f63b24638ee822f88632572ca4b061774771c0cc6d0ae5ccdeb538177232cd)
- [Discussion](https://governance.aave.com/t/arfc-gho-stewards/16466)

## Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {GovV3Helpers, IPayloadsControllerCore, PayloadsControllerUtils} from 'aave-helpers/GovV3Helpers.sol';
import {EthereumScript} from 'aave-helpers/ScriptUtils.sol';
import {AaveV3Ethereum_ActivateGhoStewards_20240326} from './AaveV3Ethereum_ActivateGhoStewards_20240326.sol';

/**
* @dev Deploy Ethereum
* deploy-command: make deploy-ledger contract=src/20240326_AaveV3Ethereum_ActivateGhoStewards/ActivateGhoStewards_20240326.s.sol:DeployEthereum chain=mainnet
* verify-command: npx catapulta-verify -b broadcast/ActivateGhoStewards_20240326.s.sol/1/run-latest.json
*/
contract DeployEthereum is EthereumScript {
function run() external broadcast {
// deploy payloads
address payload0 = GovV3Helpers.deployDeterministic(
type(AaveV3Ethereum_ActivateGhoStewards_20240326).creationCode
);

// compose action
IPayloadsControllerCore.ExecutionAction[]
memory actions = new IPayloadsControllerCore.ExecutionAction[](1);
actions[0] = GovV3Helpers.buildAction(payload0);

// register action at payloadsController
GovV3Helpers.createPayload(actions);
}
}

/**
* @dev Create Proposal
* command: make deploy-ledger contract=src/20240326_AaveV3Ethereum_ActivateGhoStewards/ActivateGhoStewards_20240326.s.sol:CreateProposal chain=mainnet
*/
contract CreateProposal is EthereumScript {
function run() external {
// create payloads
PayloadsControllerUtils.Payload[] memory payloads = new PayloadsControllerUtils.Payload[](1);

// compose actions for validation
IPayloadsControllerCore.ExecutionAction[]
memory actionsEthereum = new IPayloadsControllerCore.ExecutionAction[](1);
actionsEthereum[0] = GovV3Helpers.buildAction(
type(AaveV3Ethereum_ActivateGhoStewards_20240326).creationCode
);
payloads[0] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum);

// create proposal
vm.startBroadcast();
GovV3Helpers.createProposal(
vm,
payloads,
GovV3Helpers.ipfsHashFile(
vm,
'src/20240326_AaveV3Ethereum_ActivateGhoStewards/ActivateGhoStewards.md'
)
);
}
}
14 changes: 14 additions & 0 deletions src/20240326_AaveV3Ethereum_ActivateGhoStewards/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {ConfigFile} from '../../generator/types';
export const config: ConfigFile = {
rootOptions: {
pools: ['AaveV3Ethereum'],
title: 'Activate Gho Stewards',
shortName: 'ActivateGhoStewards',
date: '20240326',
author: 'Aave Chan Initiative',
discussion: 'https://governance.aave.com/t/arfc-gho-stewards/16466',
snapshot:
'https://snapshot.org/#/aave.eth/proposal/0x29f63b24638ee822f88632572ca4b061774771c0cc6d0ae5ccdeb538177232cd',
},
poolOptions: {AaveV3Ethereum: {configs: {OTHERS: {}}, cache: {blockNumber: 19519644}}},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IAccessControl} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IAccessControl.sol';

interface IGhoToken is IAccessControl {
function BUCKET_MANAGER_ROLE() external pure returns (bytes32);

function getFacilitatorsList() external view returns (address[] memory);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

/**
* @title IGhoStewardV2
* @author Aave Labs
* @notice Defines the basic interface of the GhoStewardV2
*/
interface IGhoStewardV2 {
struct GhoDebounce {
uint40 ghoBorrowCapLastUpdate;
uint40 ghoBorrowRateLastUpdate;
}

struct GsmDebounce {
uint40 gsmExposureCapLastUpdated;
uint40 gsmFeeStrategyLastUpdated;
}

/**
* @notice Updates the bucket capacity of facilitator, only if:
* - respects `MINIMUM_DELAY`, the minimum time delay between updates
* - the update changes up to 100% upwards
* - the facilitator is controlled
* @dev Only callable by Risk Council
* @param facilitator The facilitator address
* @param newBucketCapacity The new facilitator bucket capacity
*/
function updateFacilitatorBucketCapacity(address facilitator, uint128 newBucketCapacity) external;

/**
* @notice Updates the GHO borrow cap, only if:
* - respects `MINIMUM_DELAY`, the minimum time delay between updates
* - the update changes up to 100% upwards
* @dev Only callable by Risk Council
* @param newBorrowCap The new borrow cap (in whole tokens)
*/
function updateGhoBorrowCap(uint256 newBorrowCap) external;

/**
* @notice Updates the borrow rate of GHO, only if:
* - respects `MINIMUM_DELAY`, the minimum time delay between updates
* - the update changes up to `GHO_BORROW_RATE_CHANGE_MAX` upwards or downwards
* - the update is lower than `GHO_BORROW_RATE_MAX`
* @dev Only callable by Risk Council
* @param newBorrowRate The new variable borrow rate (expressed in ray) (e.g. 0.0150e27 results in 1.50%)
*/
function updateGhoBorrowRate(uint256 newBorrowRate) external;

/**
* @notice Updates the exposure cap of the GSM, only if:
* - respects `MINIMUM_DELAY`, the minimum time delay between updates
* - the update changes up to 100% upwards
* @dev Only callable by Risk Council
* @param gsm The gsm address to update
* @param newExposureCap The new exposure cap (in underlying asset terms)
*/
function updateGsmExposureCap(address gsm, uint128 newExposureCap) external;

/**
* @notice Updates the fixed percent fees of the GSM, only if:
* - respects `MINIMUM_DELAY`, the minimum time delay between updates
* - the update changes up to `GSM_FEE_RATE_CHANGE_MAX` upwards (for both buy and sell individually);
* @dev Only callable by Risk Council
* @param gsm The gsm address to update
* @param buyFee The new buy fee (expressed in bps) (e.g. 0.0150e4 results in 1.50%)
* @param sellFee The new sell fee (expressed in bps) (e.g. 0.0150e4 results in 1.50%)
*/
function updateGsmBuySellFees(address gsm, uint256 buyFee, uint256 sellFee) external;

/**
* @notice Adds/Removes controlled facilitators
* @dev Only callable by owner
* @param facilitatorList A list of facilitators addresses to add to control
* @param approve True to add as controlled facilitators, false to remove
*/
function setControlledFacilitator(address[] memory facilitatorList, bool approve) external;

/**
* @notice Returns the maximum increase/decrease for GHO borrow rate updates.
* @return The maximum increase change for borrow rate updates in ray (e.g. 0.010e27 results in 1.00%)
*/
function GHO_BORROW_RATE_CHANGE_MAX() external view returns (uint256);

/**
* @notice Returns the maximum increase for GSM fee rates (buy or sell).
* @return The maximum increase change for GSM fee rates updates in bps (e.g. 0.010e4 results in 1.00%)
*/
function GSM_FEE_RATE_CHANGE_MAX() external view returns (uint256);

/**
* @notice Returns maximum value that can be assigned to GHO borrow rate.
* @return The maximum value that can be assigned to GHO borrow rate in ray (e.g. 0.01e27 results in 1.0%)
*/
function GHO_BORROW_RATE_MAX() external view returns (uint256);

/**
* @notice Returns the minimum delay that must be respected between parameters update.
* @return The minimum delay between parameter updates (in seconds)
*/
function MINIMUM_DELAY() external view returns (uint256);

/**
* @notice Returns the address of the Pool Addresses Provider of the Aave V3 Ethereum Pool
* @return The address of the PoolAddressesProvider of Aave V3 Ethereum Pool
*/
function POOL_ADDRESSES_PROVIDER() external view returns (address);

/**
* @notice Returns the address of the Gho Token
* @return The address of the GhoToken
*/
function GHO_TOKEN() external view returns (address);

/**
* @notice Returns the address of the fixed rate strategy factory
* @return The address of the FixedRateStrategyFactory
*/
function FIXED_RATE_STRATEGY_FACTORY() external view returns (address);

/**
* @notice Returns the address of the risk council
* @return The address of the RiskCouncil
*/
function RISK_COUNCIL() external view returns (address);

/**
* @notice Returns the list of controlled facilitators by this steward.
* @return An array of facilitator addresses
*/
function getControlledFacilitators() external view returns (address[] memory);

/**
* @notice Returns timestamp of the last update of GHO parameters
* @return The GhoDebounce struct describing the last update of GHO parameters
*/
function getGhoTimelocks() external view returns (GhoDebounce memory);

/**
* @notice Returns timestamp of the last update of Gsm parameters
* @param gsm The GSM address
* @return The GsmDebounce struct describing the last update of GSM parameters
*/
function getGsmTimelocks(address gsm) external view returns (GsmDebounce memory);

/**
* @notice Returns timestamp of the facilitators last bucket capacity update
* @param facilitator The facilitator address
* @return The unix time of the last bucket capacity (in seconds).
*/
function getFacilitatorBucketCapacityTimelock(address facilitator) external view returns (uint40);

/**
* @notice Returns the list of Fixed Fee Strategies for GSM
* @return An array of FixedFeeStrategy addresses
*/
function getGsmFeeStrategies() external view returns (address[] memory);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IAccessControl} from 'aave-v3-core/contracts/dependencies/openzeppelin/contracts/IAccessControl.sol';

interface IGsm is IAccessControl {
function CONFIGURATOR_ROLE() external pure returns (bytes32);
}

0 comments on commit b976c0b

Please sign in to comment.