generated from bgd-labs/bgd-forge-template
-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
StkGHO Initialization proposal (#170)
* Add proposal for Gho Incident Report 20231113 (#1) * chore: add payload and deploy script for update of GHO variable debt token * forge install: gho-core * chore: add gho-core to dependency * test: Add tests for update of gho variable token * test: Add tests for update of gho variable token * fix: add modifier in method of interface * fix: remove gho dependency from repo and fix test * fix: Remove unnecesary dependency * fix: Add latest details --------- Co-authored-by: miguelmtzinf <[email protected]> * fix: Make new impl constant (#3) * fix: Amend AIP text (#4) * fix: Make new impl constant * fix: Fix AIP text * test: Tweak default tests with borrow cap update (#5) * fix: lint issue (#6) * test: Add diffs from test running (#7) * fix: Add payload address (#8) * fix: Fix payload address in script (#9) * fix: Remove unneeded diff file (#10) * feat: added stkgho initialization proposal * feat: fixed proposal description * feat: removed submodule * feat: fixed deployment script * feat: replaced duration calculation * git commit remove submodule * feat: fixed payload build function * update proposal * sync branch * fix: variable name * fix: Fix AIP payload * fix: Fix tests * test: added further test on emission per day * refactor: removed unused constants * fix: catapulta commands * fix: Add fixes to payload * fix: Rebuild proposal with autogenerate tool --------- Co-authored-by: Parth Patel <[email protected]> Co-authored-by: miguelmtzinf <[email protected]> Co-authored-by: miguelmtz <[email protected]> Co-authored-by: Mark Hinschberger <[email protected]>
- Loading branch information
1 parent
95d84cd
commit 1982811
Showing
10 changed files
with
448 additions
and
7 deletions.
There are no files selected for viewing
Submodule aave-helpers
updated
30 files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
src/20240119_AaveV3Ethereum_StkGHOActivation/AaveV3Ethereum_StkGHOActivation_20240119.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 Aave Labs & ACI | ||
* - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x4bc99a842adab6cdd8c7d5c7a787ee4c0056be554fde0d008d53b45b3e795065 | ||
* - Discussion: https://governance.aave.com/t/arfc-upgrade-safety-module-with-stkgho/15635 | ||
*/ | ||
contract AaveV3Ethereum_StkGHOActivation_20240119 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 | ||
); | ||
} | ||
} |
97 changes: 97 additions & 0 deletions
97
src/20240119_AaveV3Ethereum_StkGHOActivation/AaveV3Ethereum_StkGHOActivation_20240119.t.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; | ||
|
||
import 'forge-std/Test.sol'; | ||
import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/ProtocolV3TestBase.sol'; | ||
import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; | ||
import {AaveSafetyModule} from 'aave-address-book/AaveSafetyModule.sol'; | ||
import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; | ||
import {IStakeToken} from './IStakeToken.sol'; | ||
import {AaveV3Ethereum_StkGHOActivation_20240119} from './AaveV3Ethereum_StkGHOActivation_20240119.sol'; | ||
|
||
/** | ||
* @dev Test for AaveV3Ethereum_StkGHOActivation_20240119 | ||
* command: make test-contract filter=AaveV3Ethereum_StkGHOActivation_20240119 | ||
*/ | ||
contract AaveV3Ethereum_StkGHOActivation_20240119_Test is ProtocolV3TestBase { | ||
AaveV3Ethereum_StkGHOActivation_20240119 internal proposal; | ||
|
||
function setUp() public { | ||
vm.createSelectFork(vm.rpcUrl('mainnet'), 19042382); | ||
proposal = new AaveV3Ethereum_StkGHOActivation_20240119(); | ||
} | ||
|
||
/** | ||
* @dev executes the generic test suite including e2e and config snapshots | ||
*/ | ||
function test_defaultProposalExecution() public { | ||
defaultTest('AaveV3Ethereum_StkGHOActivation_20240119', AaveV3Ethereum.POOL, address(proposal)); | ||
} | ||
|
||
function test_checkConfig() public { | ||
(uint128 emissionPerSecondBefore, , ) = IStakeToken(AaveSafetyModule.STK_GHO).assets( | ||
AaveV3EthereumAssets.GHO_UNDERLYING | ||
); | ||
|
||
executePayload(vm, address(proposal)); | ||
|
||
( | ||
uint128 emissionPerSecondAfter, | ||
uint128 lastUpdateTimestampAfter, // uint256 indexAfter | ||
|
||
) = IStakeToken(AaveSafetyModule.STK_GHO).assets(AaveSafetyModule.STK_GHO); | ||
|
||
// NOTE index is still 0 | ||
assertEq(emissionPerSecondBefore + emissionPerSecondAfter, proposal.AAVE_EMISSION_PER_SECOND()); | ||
assertEq(lastUpdateTimestampAfter, block.timestamp); | ||
} | ||
|
||
function test_checkAllowance() public { | ||
uint256 allowanceBefore = IERC20(AaveV3EthereumAssets.AAVE_UNDERLYING).allowance( | ||
MiscEthereum.ECOSYSTEM_RESERVE, | ||
AaveSafetyModule.STK_GHO | ||
); | ||
|
||
executePayload(vm, address(proposal)); | ||
|
||
uint256 allowanceAfter = IERC20(AaveV3EthereumAssets.AAVE_UNDERLYING).allowance( | ||
MiscEthereum.ECOSYSTEM_RESERVE, | ||
AaveSafetyModule.STK_GHO | ||
); | ||
|
||
assertEq( | ||
allowanceAfter - allowanceBefore, | ||
proposal.AAVE_EMISSION_PER_SECOND() * proposal.DISTRIBUTION_DURATION() | ||
); | ||
} | ||
|
||
function test_checkRewards() public { | ||
address prankAddress = 0xF5Fb27b912D987B5b6e02A1B1BE0C1F0740E2c6f; | ||
|
||
uint256 confidenceMargin = 1e6; // margin of error due to rounding | ||
uint256 rewardsPerDay = 50e18; | ||
|
||
executePayload(vm, address(proposal)); | ||
|
||
// impersonating address with AAVE balance | ||
vm.startPrank(prankAddress); | ||
IERC20(AaveV3EthereumAssets.GHO_UNDERLYING).approve(AaveSafetyModule.STK_GHO, 1e18); | ||
|
||
IStakeToken(AaveSafetyModule.STK_GHO).stake(prankAddress, 1e18); | ||
|
||
vm.warp(block.timestamp + 1 days); | ||
|
||
uint256 rewardsBalance = IStakeToken(AaveSafetyModule.STK_GHO).getTotalRewardsBalance( | ||
prankAddress | ||
); | ||
|
||
assertTrue( | ||
rewardsBalance >= (rewardsPerDay - confidenceMargin) && | ||
rewardsBalance <= (rewardsPerDay + confidenceMargin) | ||
); | ||
|
||
vm.stopPrank(); | ||
} | ||
} |
194 changes: 194 additions & 0 deletions
194
src/20240119_AaveV3Ethereum_StkGHOActivation/IStakeToken.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |
37 changes: 37 additions & 0 deletions
37
src/20240119_AaveV3Ethereum_StkGHOActivation/StkGHOActivation.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
--- | ||
title: "StkGHO Activation" | ||
author: "Aave Labs & ACI" | ||
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 [Snapshot 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 | ||
|
||
- Implementation: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240119_AaveV3Ethereum_StkGHOActivation/AaveV3Ethereum_StkGHOActivation_20240119.sol) | ||
- Tests: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240119_AaveV3Ethereum_StkGHOActivation/AaveV3Ethereum_StkGHOActivation_20240119.t.sol) | ||
- [Snapshot](https://snapshot.org/#/aave.eth/proposal/0x4bc99a842adab6cdd8c7d5c7a787ee4c0056be554fde0d008d53b45b3e795065) | ||
- [Discussion](https://governance.aave.com/t/arfc-upgrade-safety-module-with-stkgho/15635) | ||
- [StkGHO](https://etherscan.io/address/0x1a88Df1cFe15Af22B3c4c783D4e6F7F9e0C1885d) | ||
- [StakeToken Repository](https://github.com/bgd-labs/stake-token) | ||
|
||
## Disclaimer | ||
|
||
Aave Labs, and ACI receive no compensation beyond Aave protocol for the creation of this proposal. ACI is delegate within the Aave ecosystem. | ||
|
||
## Copyright | ||
|
||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). |
Oops, something went wrong.
1982811
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.
Foundry report
Build log
Test success 🌈