-
Notifications
You must be signed in to change notification settings - Fork 29
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
StkGHO Initialization proposal #170
Changes from 17 commits
24a3f7d
4aa6143
27dd485
2f242a6
4812d01
43a7687
4c79bb9
76cd4b6
120f564
4d6a3d9
4cb8573
6c5ee89
1b99bd8
c3d48cd
7938a2d
575b445
b777395
79f2011
1062d67
fd43d71
6d58d1f
0ac9c62
35a12a3
5df6a3e
121b4f4
d1e97c6
8e940eb
33fac26
c50ff04
1f79a77
f8490ca
45d813c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
pragma solidity ^0.8.10; | ||
|
||
interface IStakeToken { | ||
event Approval(address indexed owner, address indexed spender, uint256 value); | ||
event AssetConfigUpdated(address indexed asset, uint256 emission); | ||
event AssetIndexUpdated(address indexed asset, uint256 index); | ||
event Cooldown(address indexed user, uint256 amount); | ||
event CooldownSecondsChanged(uint256 cooldownSeconds); | ||
event DistributionEndChanged(uint256 endTimestamp); | ||
event EIP712DomainChanged(); | ||
event ExchangeRateChanged(uint216 exchangeRate); | ||
event FundsReturned(uint256 amount); | ||
event Initialized(uint64 version); | ||
event MaxSlashablePercentageChanged(uint256 newPercentage); | ||
event PendingAdminChanged(address indexed newPendingAdmin, uint256 role); | ||
event Redeem(address indexed from, address indexed to, uint256 assets, uint256 shares); | ||
event RewardsAccrued(address user, uint256 amount); | ||
event RewardsClaimed(address indexed from, address indexed to, uint256 amount); | ||
event RoleClaimed(address indexed newAdmin, uint256 role); | ||
event Slashed(address indexed destination, uint256 amount); | ||
event SlashingExitWindowDurationChanged(uint256 windowSeconds); | ||
event SlashingSettled(); | ||
event Staked(address indexed from, address indexed to, uint256 assets, uint256 shares); | ||
event Transfer(address indexed from, address indexed to, uint256 value); | ||
event UserIndexUpdated(address indexed user, address indexed asset, uint256 index); | ||
|
||
struct AssetConfigInput { | ||
uint128 emissionPerSecond; | ||
uint256 totalStaked; | ||
address underlyingAsset; | ||
} | ||
|
||
function CLAIM_HELPER_ROLE() external view returns (uint256); | ||
|
||
function COOLDOWN_ADMIN_ROLE() external view returns (uint256); | ||
|
||
function DOMAIN_SEPARATOR() external view returns (bytes32); | ||
|
||
function EMISSION_MANAGER() external view returns (address); | ||
|
||
function EXCHANGE_RATE_UNIT() external view returns (uint256); | ||
|
||
function INITIAL_EXCHANGE_RATE() external view returns (uint216); | ||
|
||
function LOWER_BOUND() external view returns (uint256); | ||
|
||
function PRECISION() external view returns (uint8); | ||
|
||
function REWARDS_VAULT() external view returns (address); | ||
|
||
function REWARD_TOKEN() external view returns (address); | ||
|
||
function SLASH_ADMIN_ROLE() external view returns (uint256); | ||
|
||
function STAKED_TOKEN() external view returns (address); | ||
|
||
function UNSTAKE_WINDOW() external view returns (uint256); | ||
|
||
function allowance(address owner, address spender) external view returns (uint256); | ||
|
||
function approve(address spender, uint256 value) external returns (bool); | ||
|
||
function assets( | ||
address | ||
) external view returns (uint128 emissionPerSecond, uint128 lastUpdateTimestamp, uint256 index); | ||
|
||
function balanceOf(address account) external view returns (uint256); | ||
|
||
function claimRewards(address to, uint256 amount) external; | ||
|
||
function claimRewardsAndRedeem(address to, uint256 claimAmount, uint256 redeemAmount) external; | ||
|
||
function claimRewardsAndRedeemOnBehalf( | ||
address from, | ||
address to, | ||
uint256 claimAmount, | ||
uint256 redeemAmount | ||
) external; | ||
|
||
function claimRewardsOnBehalf( | ||
address from, | ||
address to, | ||
uint256 amount | ||
) external returns (uint256); | ||
|
||
function claimRoleAdmin(uint256 role) external; | ||
|
||
function configureAssets(AssetConfigInput[] memory assetsConfigInput) external; | ||
|
||
function cooldown() external; | ||
|
||
function cooldownOnBehalfOf(address from) external; | ||
|
||
function decimals() external view returns (uint8); | ||
|
||
function distributionEnd() external view returns (uint256); | ||
|
||
function eip712Domain() | ||
external | ||
view | ||
returns ( | ||
bytes1 fields, | ||
string memory name, | ||
string memory version, | ||
uint256 chainId, | ||
address verifyingContract, | ||
bytes32 salt, | ||
uint256[] memory extensions | ||
); | ||
|
||
function getAdmin(uint256 role) external view returns (address); | ||
|
||
function getCooldownSeconds() external view returns (uint256); | ||
|
||
function getExchangeRate() external view returns (uint216); | ||
|
||
function getMaxSlashablePercentage() external view returns (uint256); | ||
|
||
function getPendingAdmin(uint256 role) external view returns (address); | ||
|
||
function getTotalRewardsBalance(address staker) external view returns (uint256); | ||
|
||
function getUserAssetData(address user, address asset) external view returns (uint256); | ||
|
||
function inPostSlashingPeriod() external view returns (bool); | ||
|
||
function initialize( | ||
string memory name, | ||
string memory symbol, | ||
address slashingAdmin, | ||
address cooldownPauseAdmin, | ||
address claimHelper, | ||
uint256 maxSlashablePercentage, | ||
uint256 cooldownSeconds | ||
) external; | ||
|
||
function name() external view returns (string memory); | ||
|
||
function nonces(address owner) external view returns (uint256); | ||
|
||
function permit( | ||
address owner, | ||
address spender, | ||
uint256 value, | ||
uint256 deadline, | ||
uint8 v, | ||
bytes32 r, | ||
bytes32 s | ||
) external; | ||
|
||
function previewRedeem(uint256 shares) external view returns (uint256); | ||
|
||
function previewStake(uint256 assets) external view returns (uint256); | ||
|
||
function redeem(address to, uint256 amount) external; | ||
|
||
function redeemOnBehalf(address from, address to, uint256 amount) external; | ||
|
||
function returnFunds(uint256 amount) external; | ||
|
||
function setCooldownSeconds(uint256 cooldownSeconds) external; | ||
|
||
function setDistributionEnd(uint256 newDistributionEnd) external; | ||
|
||
function setMaxSlashablePercentage(uint256 percentage) external; | ||
|
||
function setPendingAdmin(uint256 role, address newPendingAdmin) external; | ||
|
||
function settleSlashing() external; | ||
|
||
function slash(address destination, uint256 amount) external returns (uint256); | ||
|
||
function stake(address to, uint256 amount) external; | ||
|
||
function stakeWithPermit( | ||
uint256 amount, | ||
uint256 deadline, | ||
uint8 v, | ||
bytes32 r, | ||
bytes32 s | ||
) external; | ||
|
||
function stakerRewardsToClaim(address) external view returns (uint256); | ||
|
||
function stakersCooldowns(address) external view returns (uint40 timestamp, uint216 amount); | ||
|
||
function symbol() external view returns (string memory); | ||
|
||
function totalSupply() external view returns (uint256); | ||
|
||
function transfer(address to, uint256 value) external returns (bool); | ||
|
||
function transferFrom(address from, address to, uint256 value) external returns (bool); | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,33 @@ | ||||||||||
--- | ||||||||||
title: "GHO Safety Module Initialization" | ||||||||||
author: "Aave_BGDLabs_ACI" | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
discussions: "https://governance.aave.com/t/arfc-upgrade-safety-module-with-stkgho/15635" | ||||||||||
--- | ||||||||||
|
||||||||||
## Simple Summary | ||||||||||
|
||||||||||
This AIP activates the new GHO based Safety module by initiating the emission schedule approved by the community during the vote | ||||||||||
https://snapshot.org/#/aave.eth/proposal/0x4bc99a842adab6cdd8c7d5c7a787ee4c0056be554fde0d008d53b45b3e795065 | ||||||||||
|
||||||||||
## Motivation | ||||||||||
|
||||||||||
The GHO Safety Module will fortify the Aave Protocol’s resilience by adding a stablecoin asset, which is inherently less volatile than AAVE. This strategic move diversifies the Safety Module’s capacity to absorb shocks from various risk vectors in case of shortfall events. | ||||||||||
|
||||||||||
## Specification | ||||||||||
|
||||||||||
The GHO Safety module will be activated with the following parameters: | ||||||||||
|
||||||||||
Base emission: 50 AAVE/day | ||||||||||
Duration: Three months | ||||||||||
|
||||||||||
## References | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here links should be included. Some default ones should have been auto-generated though. |
||||||||||
|
||||||||||
[TBD] | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @The-3D wanna add the simulated payload address? |
||||||||||
|
||||||||||
## Disclaimer | ||||||||||
|
||||||||||
Aave Labs, BGD Labs and ACI receive no compensation beyond Aave protocol for the creation of this proposal. BGD Labs and ACI are both delegates within the Aave ecosystem. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No point on mentioning BGD Labs here, and we are not really delegates There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
|
||||||||||
## 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,54 @@ | ||
// 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 {StkGHO_Activation_20240118} from './StkGHO_Activation_20240118.sol'; | ||
import {AaveSafetyModule} from 'aave-address-book/AaveSafetyModule.sol'; | ||
|
||
/** | ||
* @dev Deploy Ethereum | ||
* deploy-command: make deploy-ledger contract=src/20240118_StkGHO_Activation/StkGHO_Activation_20240118.s.sol:DeployEthereum chain=mainnet | ||
* verify-command: npx catapulta-verify -b broadcast/20240118_StkGHO_Activation.s.sol/137/run-latest.json | ||
*/ | ||
contract DeployEthereum is EthereumScript { | ||
function run() external broadcast { | ||
// deploy payloads | ||
address payload0 = GovV3Helpers.deployDeterministic( | ||
type(StkGHO_Activation_20240118).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/20240118_StkGHO_Activation/StkGHO_Activation_20240118.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(StkGHO_Activation_20240118).creationCode); | ||
payloads[0] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum); | ||
|
||
// create proposal | ||
vm.startBroadcast(); | ||
GovV3Helpers.createProposal( | ||
vm, | ||
payloads, | ||
GovV3Helpers.ipfsHashFile(vm, 'src/StkGHO_Activation_20240118/StkGHOActivation.md') | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,41 @@ | ||||||
// SPDX-License-Identifier: MIT | ||||||
pragma solidity ^0.8.0; | ||||||
|
||||||
import {IProposalGenericExecutor} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol'; | ||||||
import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; | ||||||
import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; | ||||||
import {AaveSafetyModule} from 'aave-address-book/AaveSafetyModule.sol'; | ||||||
import {IStakeToken} from './IStakeToken.sol'; | ||||||
|
||||||
/** | ||||||
* @title StkGHO Activation | ||||||
* @author the3d.eth | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
* - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x4bc99a842adab6cdd8c7d5c7a787ee4c0056be554fde0d008d53b45b3e795065 | ||||||
* - Discussion: https://governance.aave.com/t/arfc-upgrade-safety-module-with-stkgho/15635 | ||||||
*/ | ||||||
contract StkGHO_Activation_20240118 is IProposalGenericExecutor { | ||||||
uint128 public constant AAVE_EMISSION_PER_SECOND = uint128(50e18) / 1 days; // 50 AAVE per day | ||||||
uint256 public constant DISTRIBUTION_DURATION = 90 days; // 3 months | ||||||
|
||||||
function execute() external { | ||||||
// Configure distribution | ||||||
IStakeToken(AaveSafetyModule.STK_GHO).setDistributionEnd( | ||||||
block.timestamp + DISTRIBUTION_DURATION | ||||||
); | ||||||
IStakeToken.AssetConfigInput[] memory enableConfigs = new IStakeToken.AssetConfigInput[](1); | ||||||
enableConfigs[0] = IStakeToken.AssetConfigInput({ | ||||||
emissionPerSecond: AAVE_EMISSION_PER_SECOND, | ||||||
totalStaked: 0, // it's overwritten internally | ||||||
underlyingAsset: AaveSafetyModule.STK_GHO | ||||||
}); | ||||||
IStakeToken(AaveSafetyModule.STK_GHO).configureAssets(enableConfigs); | ||||||
|
||||||
// Allowance to pull funds from Ecosystem Reserve | ||||||
MiscEthereum.AAVE_ECOSYSTEM_RESERVE_CONTROLLER.approve( | ||||||
MiscEthereum.ECOSYSTEM_RESERVE, | ||||||
AaveV3EthereumAssets.AAVE_UNDERLYING, | ||||||
AaveSafetyModule.STK_GHO, | ||||||
AAVE_EMISSION_PER_SECOND * DISTRIBUTION_DURATION | ||||||
); | ||||||
} | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to other proposals we review, we are not to be included here. Usually who implements the proposal and who creates it are included (Aave Lab & ACI).