Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gho minter #554

Merged
merged 3 commits into from
Jan 6, 2025
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
## Reserve changes

### Reserves altered

#### GHO ([0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f](https://etherscan.io/address/0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f))

| description | value before | value after |
| --- | --- | --- |
| aTokenUnderlyingBalance | 6,108,315.1602 GHO [6108315160265916496775469] | 16,108,315.1602 GHO [16108315160265916496775469] |
| virtualBalance | 6,108,315.1602 GHO [6108315160265916496775469] | 16,108,315.1602 GHO [16108315160265916496775469] |


## Raw diff

```json
{
"reserves": {
"0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f": {
"aTokenUnderlyingBalance": {
"from": "6108315160265916496775469",
"to": "16108315160265916496775469"
},
"virtualBalance": {
"from": "6108315160265916496775469",
"to": "16108315160265916496775469"
}
}
}
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol';
import {AaveV3EthereumLido} from 'aave-address-book/AaveV3EthereumLido.sol';
import {IAccessControl} from 'openzeppelin-contracts/contracts/access/IAccessControl.sol';
import {IGhoBucketSteward} from '../interfaces/IGhoBucketSteward.sol';
import {IGhoToken} from '../interfaces/IGhoToken.sol';
import {IGhoDirectMinter} from './IGhoDirectMinter.sol';
import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol';

/**
* @title Deploy 10M GHO into Aave v3 Lido Instance
* @author karpatkey_TokenLogic & BGD Labs
* - Snapshot: https://snapshot.box/#/s:aave.eth/proposal/0x4af37d6b4a1c9029c7693c4bdfb646931a9815c4a56d9066ac1fbdbef7cd15e5
* - Discussion: https://governance.aave.com/t/arfc-mint-deploy-10m-gho-into-aave-v3-lido-instance/19700
*/
contract AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance_20241229 is
IProposalGenericExecutor
{
uint128 public constant GHO_MINT_AMOUNT = 10_000_000e18;

// https://etherscan.io/address/0x2cE01c87Fec1b71A9041c52CaED46Fc5f4807285
address public constant FACILITATOR = 0x2cE01c87Fec1b71A9041c52CaED46Fc5f4807285;

function execute() external {
IAccessControl(address(AaveV3EthereumLido.ACL_MANAGER)).grantRole(
AaveV3EthereumLido.ACL_MANAGER.RISK_ADMIN_ROLE(),
FACILITATOR
);
IGhoToken(AaveV3EthereumAssets.GHO_UNDERLYING).addFacilitator(
FACILITATOR,
'LidoGhoDirectMinter',
GHO_MINT_AMOUNT
);
IGhoDirectMinter(FACILITATOR).mintAndSupply(GHO_MINT_AMOUNT);

// Allow risk council to control the bucket capacity
address[] memory vaults = new address[](1);
vaults[0] = FACILITATOR;
// https://etherscan.io/address/0x46Aa1063e5265b43663E81329333B47c517A5409
IGhoBucketSteward(0x46Aa1063e5265b43663E81329333B47c517A5409).setControlledFacilitator(
vaults,
true
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol';
import {AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol';
import {AaveV3EthereumLido, AaveV3EthereumLidoAssets} from 'aave-address-book/AaveV3EthereumLido.sol';
import {IAccessControl} from 'openzeppelin-contracts/contracts/access/IAccessControl.sol';
import {IGhoBucketSteward} from '../interfaces/IGhoBucketSteward.sol';
import {IGhoToken} from '../interfaces/IGhoToken.sol';
import {IGhoDirectMinter} from './IGhoDirectMinter.sol';
import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol';

import {AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance_20241229} from './AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance_20241229.sol';

/**
* @dev Test for AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance_20241229
* command: FOUNDRY_PROFILE=mainnet forge test --match-path=src/20241229_AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance/AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance_20241229.t.sol -vv
*/
contract AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance_20241229_Test is ProtocolV3TestBase {
AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance_20241229 internal proposal;

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

/**
* @dev executes the generic test suite including e2e and config snapshots
*/
function test_defaultProposalExecution() public {
defaultTest(
'AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance_20241229',
AaveV3EthereumLido.POOL,
address(proposal)
);
}

function test_accessControl() public {
assertEq(
IAccessControl(address(AaveV3EthereumLido.ACL_MANAGER)).hasRole(
AaveV3EthereumLido.ACL_MANAGER.RISK_ADMIN_ROLE(),
proposal.FACILITATOR()
),
false
);

address[] memory facilitators = IGhoToken(AaveV3EthereumAssets.GHO_UNDERLYING)
.getFacilitatorsList();
uint256 facilitatorsLength = facilitators.length;

assertNotEq(proposal.FACILITATOR(), facilitators[facilitators.length - 1]);

executePayload(vm, address(proposal));

assertEq(
IAccessControl(address(AaveV3EthereumLido.ACL_MANAGER)).hasRole(
AaveV3EthereumLido.ACL_MANAGER.RISK_ADMIN_ROLE(),
proposal.FACILITATOR()
),
true
);

facilitators = IGhoToken(AaveV3EthereumAssets.GHO_UNDERLYING).getFacilitatorsList();

assertEq(proposal.FACILITATOR(), facilitators[facilitators.length - 1]);
assertEq(facilitators.length, facilitatorsLength + 1);
}

function test_supplyIncreases() public {
uint256 ghoBalanceBefore = IGhoToken(AaveV3EthereumAssets.GHO_UNDERLYING).balanceOf(
AaveV3EthereumLidoAssets.GHO_A_TOKEN
);

uint256 aGhoBalanceBefore = IERC20(AaveV3EthereumLidoAssets.GHO_A_TOKEN).balanceOf(
proposal.FACILITATOR()
);

executePayload(vm, address(proposal));

assertEq(
IGhoToken(AaveV3EthereumAssets.GHO_UNDERLYING).balanceOf(
AaveV3EthereumLidoAssets.GHO_A_TOKEN
),
ghoBalanceBefore + proposal.GHO_MINT_AMOUNT()
);

assertEq(
IERC20(AaveV3EthereumLidoAssets.GHO_A_TOKEN).balanceOf(proposal.FACILITATOR()),
aGhoBalanceBefore + proposal.GHO_MINT_AMOUNT()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: "Deploy 10M GHO into Aave v3 Lido Instance"
author: "karpatkey_TokenLogic & BGD Labs"
discussions: "https://governance.aave.com/t/arfc-mint-deploy-10m-gho-into-aave-v3-lido-instance/19700"
snapshot: "https://snapshot.box/#/s:aave.eth/proposal/0x4af37d6b4a1c9029c7693c4bdfb646931a9815c4a56d9066ac1fbdbef7cd15e5"
---

## Simple Summary

Following the addition of GHO to the Lido instance of Aave v3 on Ethereum, this publication proposes supporting GHO liquidity by minting 10M units of GHO and depositing into Aave Lido.

## Motivation

By providing liquidity on the Lido instance, the Aave DAO shall provide the initial bootstrapping liquidity in a very cost efficient manner and, in doing so, enhance the DAO's revenue generated from the Lido instance. GHO holders will be able to deposit GHO to earn the deposit yield whilst benefit from small than otherwise concentration risk within the reserve due to the DAO providing the bootstrapping liquidity.

With strong demand for GHO using wstETH as collateral resulting in 23.7% of GHO supply sourced from the Main market being backed by wstETH, this demonstrates that users actively seek to benefit from the capital efficiency of using an LST as collateral. Deploying additional GHO into the Lido instance is expected to further encourage this positive behavior, reinforcing the appeal of wstETH as a reliable, yield-bearing collateral for GHO.

## Specification

- Prior to proposal, GhoDirectMinter contract was deployed [here](https://etherscan.io/address/0x2cE01c87Fec1b71A9041c52CaED46Fc5f4807285)
- Grant RISK_ADMIN_ROLE to GhoDirectMinter referenced above
- Add GhoDirectMinter as a GHO token facilitator
- Mint 10M GHO and supply into Aave Lido
- Allow GhoBucketSteward to control GhoDirectMinter

## References

- Implementation: [AaveV3EthereumLido](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241229_AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance/AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance_20241229.sol)
- Tests: [AaveV3EthereumLido](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241229_AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance/AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance_20241229.t.sol)
- [Snapshot](https://snapshot.box/#/s:aave.eth/proposal/0x4af37d6b4a1c9029c7693c4bdfb646931a9815c4a56d9066ac1fbdbef7cd15e5)
- [Discussion](https://governance.aave.com/t/arfc-mint-deploy-10m-gho-into-aave-v3-lido-instance/19700)

## 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,60 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {GovV3Helpers, IPayloadsControllerCore, PayloadsControllerUtils} from 'aave-helpers/src/GovV3Helpers.sol';
import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol';
import {EthereumScript} from 'solidity-utils/contracts/utils/ScriptUtils.sol';
import {AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance_20241229} from './AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance_20241229.sol';

/**
* @dev Deploy Ethereum
* deploy-command: make deploy-ledger contract=src/20241229_AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance/Deploy10MGHOIntoAaveV3LidoInstance_20241229.s.sol:DeployEthereum chain=mainnet
* verify-command: FOUNDRY_PROFILE=mainnet npx catapulta-verify -b broadcast/Deploy10MGHOIntoAaveV3LidoInstance_20241229.s.sol/1/run-latest.json
*/
contract DeployEthereum is EthereumScript {
function run() external broadcast {
// deploy payloads
address payload0 = GovV3Helpers.deployDeterministic(
type(AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance_20241229).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/20241229_AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance/Deploy10MGHOIntoAaveV3LidoInstance_20241229.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(AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance_20241229).creationCode
);
payloads[0] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum);

// create proposal
vm.startBroadcast();
GovV3Helpers.createProposal(
vm,
payloads,
GovernanceV3Ethereum.VOTING_PORTAL_ETH_POL,
GovV3Helpers.ipfsHashFile(
vm,
'src/20241229_AaveV3EthereumLido_Deploy10MGHOIntoAaveV3LidoInstance/Deploy10MGHOIntoAaveV3LidoInstance.md'
)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

interface IGhoDirectMinter {
function mintAndSupply(uint256 amount) external;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {ConfigFile} from '../../generator/types';
export const config: ConfigFile = {
rootOptions: {
pools: ['AaveV3EthereumLido'],
title: 'Deploy 10M GHO into Aave v3 Lido Instance',
shortName: 'Deploy10MGHOIntoAaveV3LidoInstance',
date: '20241229',
author: 'karpatkey_TokenLogic & BGD Labs',
discussion:
'https://governance.aave.com/t/arfc-mint-deploy-10m-gho-into-aave-v3-lido-instance/19700',
snapshot:
'https://snapshot.box/#/s:aave.eth/proposal/0x4af37d6b4a1c9029c7693c4bdfb646931a9815c4a56d9066ac1fbdbef7cd15e5',
votingNetwork: 'POLYGON',
},
poolOptions: {AaveV3EthereumLido: {configs: {OTHERS: {}}, cache: {blockNumber: 21510730}}},
};
19 changes: 19 additions & 0 deletions src/interfaces/IGhoToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,27 @@ interface IGhoToken {
string label;
}

/**
* @notice Add the facilitator passed with the parameters to the facilitators list.
* @dev Only accounts with `FACILITATOR_MANAGER_ROLE` role can call this function
* @param facilitatorAddress The address of the facilitator to add
* @param facilitatorLabel A human readable identifier for the facilitator
* @param bucketCapacity The upward limit of GHO can be minted by the facilitator
*/
function addFacilitator(
address facilitatorAddress,
string calldata facilitatorLabel,
uint128 bucketCapacity
) external;

function balanceOf(address user) external returns (uint256);

/**
* @notice Returns the list of the addresses of the active facilitator
* @return The list of the facilitators addresses
*/
function getFacilitatorsList() external view returns (address[] memory);

/**
* @notice Set the bucket capacity of the facilitator.
* @dev Only accounts with `BUCKET_MANAGER_ROLE` role can call this function
Expand Down
Loading