generated from bgd-labs/bgd-forge-template
-
Notifications
You must be signed in to change notification settings - Fork 32
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
feat: aAMPL second distribution #325
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
5 changes: 5 additions & 0 deletions
5
...bution_20240429_before_AaveV2Ethereum_AAMPLSecondDistribution_20240429_after.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,5 @@ | ||
## Raw diff | ||
|
||
```json | ||
{} | ||
``` |
57 changes: 57 additions & 0 deletions
57
src/20240429_AaveV2Ethereum_AAMPLSecondDistribution/AAMPLSecondDistribution.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,57 @@ | ||
--- | ||
title: "aAMPL Second Distribution" | ||
author: "BGD Labs (@bgdlabs)" | ||
discussions: "https://governance.aave.com/t/arfc-aampl-second-distribution/17464" | ||
snapshot: "https://snapshot.org/#/aave.eth/proposal/0x372ea60168390ca30be8890ae18ba3c1bb171428ad613a3c8c1a568721c1d65d" | ||
--- | ||
|
||
## Simple Summary | ||
|
||
A proposal for a follow-up distribution of 766'436 aUSDC (762'604 aUSDC + 3'832 aUSDC angle labs fee) from the Aave Collector to allow full withdrawals by aAMPL suppliers to Aave v2 Ethereum, consequence of the problem detected at the end of 2023. | ||
|
||
## Motivation | ||
|
||
In December 2023, a problem was detected on the AMPL custom reserve on Aave v2 Ethereum, causing an unexpected inflation of AMPL-related balances and supply, not following the intended design by the Ampleforth team. | ||
|
||
After further analysis and remediation strategy, the Aave governance approved and executed a proposal on April 17th to provide approximately 300’000 USDC for aAMPL holders to claim. This was designed as an initial and interim distribution, with the sole objective of providing liquidity for users affected as soon as possible. Meanwhile, the service providers of the Aave DAO and the Ampleforth team completed further analysis for a final distribution proposal; this one. | ||
|
||
## Specification | ||
|
||
To fully understand the problem at hand and the rationale of this distribution, we recommend mandatorily reading its specification on the [forum](https://governance.aave.com/t/ampl-problem-on-aave-v2-ethereum/15886/155), to make an informed decision. | ||
|
||
In summary, this proposal recommends making claimable 766'436 aUSDC (762'604 aUSDC + 3'832 aUSDC angle labs fee) from the Aave Ethereum Collector, in addition to the already distributed 300’000 USDC, making a total of approximately $1,066,436. | ||
|
||
Some key points output of the analysis are: | ||
|
||
- Decisions when doing the analysis have been made to favor aAMPL holders, whenever it was subjective generally, but always trying to maintain objectivity on the expected dynamics of AMPL on Aave. | ||
- Real returns of supplied AMPL on Aave have been recalculated from the freezing period until the expected execution time of the proposal (beginning of May 2024). This approach, compared to calculating from market inception, preserves four times more AMPL for users, maximizing welfare for AMPL suppliers. | ||
- The previous analysis resulted in identifying a claimable amount of 351,579 AMPL as of December 16th, 2023, after rectifying highly evident artificial inflation within the 764,303 aAMPL total supply. As a reference point, debt levels were observed to be at 42,847 AMPL during that period. | ||
- As further compensation for the time passed since December during which funds were not withdrawable, the latest on-chain rate is applicable on the 351’579 AMPL: 256% compounding for more than 4 months, which results in a total of 882’869 AMPL, or $1,057,677. | ||
Uniform 100% utilization from 16th December 2023 to the beginning of May 2024 is considered, disregarding the underlying rebases of AMPL. This also tries to heavily increase the amount received by aAMPL holders, as once again, debt levels are currently just 72K vAMPL, compared to the much greater compensation amount. | ||
- Pricing claims at $1.198 price per AMPL, despite the price falling below and negative rebases accruing on the aAMPL supply since. | ||
Any holding by the Aave Collector contract is not included in the compensation, to increase the amount received by other aAMPL holders. | ||
- Interest generated from the 300’000 available on 17th April to withdraw is discounted, as those funds are fully claimable by users. | ||
- The claim for the Mooniswap pool has been proxied with sub-claims for LPs on it. | ||
|
||
The Ampleforth team agreed to compensate 40% of the total after proposal execution, as stated on https://governance.aave.com/t/ampl-problem-on-aave-v2-ethereum/15886/128, which will be done after Aave fully approves this distribution. | ||
|
||
Regarding the technical details, the proposal will: | ||
|
||
- Transfer v3 aUSDC from the collector (766.436k including a 0.5% fee for angle labs) | ||
- Approve the full amount to [0x8BB4C975Ff3c250e0ceEA271728547f3802B36Fd](https://etherscan.io/address/0x8BB4C975Ff3c250e0ceEA271728547f3802B36Fd) which is the distribution creator by Angle Labs | ||
- Create a campaign to distribute funds to the affected users | ||
|
||
2 hours after proposal execution, users will be able to claim the aUSDC on https://app.merkl.xyz/ | ||
|
||
## References | ||
|
||
- Implementation: [AaveV2Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240429_AaveV2Ethereum_AAMPLSecondDistribution/AaveV2Ethereum_AAMPLSecondDistribution_20240429.sol) | ||
- Tests: [AaveV2Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240429_AaveV2Ethereum_AAMPLSecondDistribution/AaveV2Ethereum_AAMPLSecondDistribution_20240429.t.sol) | ||
- [Snapshot](https://snapshot.org/#/aave.eth/proposal/0x372ea60168390ca30be8890ae18ba3c1bb171428ad613a3c8c1a568721c1d65d) | ||
- [Discussion](https://governance.aave.com/t/arfc-aampl-second-distribution/17464) | ||
- [Distribution:IPFS](https://angle-blog.infura-ipfs.io/ipfs/QmTvv4u6MUb6cwThCi7tma1ZJ1XUe9mQmaGcHEmLZhazre) | ||
- [Distribution:formatted](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240429_AaveV2Ethereum_AAMPLSecondDistribution/distribution.pdf) | ||
|
||
## Copyright | ||
|
||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). |
58 changes: 58 additions & 0 deletions
58
src/20240429_AaveV2Ethereum_AAMPLSecondDistribution/AAMPLSecondDistribution_20240429.s.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,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 {AaveV2Ethereum_AAMPLSecondDistribution_20240429} from './AaveV2Ethereum_AAMPLSecondDistribution_20240429.sol'; | ||
|
||
/** | ||
* @dev Deploy Ethereum | ||
* deploy-command: make deploy-ledger contract=src/20240429_AaveV2Ethereum_AAMPLSecondDistribution/AAMPLSecondDistribution_20240429.s.sol:DeployEthereum chain=mainnet | ||
* verify-command: npx catapulta-verify -b broadcast/AAMPLSecondDistribution_20240429.s.sol/1/run-latest.json | ||
*/ | ||
contract DeployEthereum is EthereumScript { | ||
function run() external broadcast { | ||
// deploy payloads | ||
address payload0 = GovV3Helpers.deployDeterministic( | ||
type(AaveV2Ethereum_AAMPLSecondDistribution_20240429).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/20240429_AaveV2Ethereum_AAMPLSecondDistribution/AAMPLSecondDistribution_20240429.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(AaveV2Ethereum_AAMPLSecondDistribution_20240429).creationCode | ||
); | ||
payloads[0] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum); | ||
|
||
// create proposal | ||
vm.startBroadcast(); | ||
GovV3Helpers.createProposal( | ||
vm, | ||
payloads, | ||
GovV3Helpers.ipfsHashFile( | ||
vm, | ||
'src/20240429_AaveV2Ethereum_AAMPLSecondDistribution/AAMPLSecondDistribution.md' | ||
) | ||
); | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
...aveV2Ethereum_AAMPLSecondDistribution/AaveV2Ethereum_AAMPLSecondDistribution_20240429.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,53 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; | ||
import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; | ||
import {IProposalGenericExecutor} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol'; | ||
import {IDistributionCreator} from './interfaces/IDistributionCreator.sol'; | ||
import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol'; | ||
|
||
/** | ||
* @title aAMPL Second Distribution | ||
* @author BGD Labs (@bgdlabs) | ||
* - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x372ea60168390ca30be8890ae18ba3c1bb171428ad613a3c8c1a568721c1d65d | ||
* - Discussion: https://governance.aave.com/t/arfc-aampl-second-distribution/17464 | ||
*/ | ||
contract AaveV2Ethereum_AAMPLSecondDistribution_20240429 is IProposalGenericExecutor { | ||
using SafeERC20 for IERC20; | ||
|
||
IDistributionCreator public constant DISTRIBUTION_CREATOR = | ||
IDistributionCreator(0x8BB4C975Ff3c250e0ceEA271728547f3802B36Fd); | ||
address public constant REWARD_TOKEN = AaveV3EthereumAssets.USDC_A_TOKEN; | ||
uint256 public constant REWARD_AMOUNT_PLUS_FEES = 766_436_793678; | ||
string public constant FILE_URL = | ||
'https://angle-blog.infura-ipfs.io/ipfs/QmTvv4u6MUb6cwThCi7tma1ZJ1XUe9mQmaGcHEmLZhazre'; | ||
|
||
function execute() external { | ||
// 1. send funds to executor (0.5% fee for angle merkle distributor) | ||
AaveV3Ethereum.COLLECTOR.transfer( | ||
AaveV3EthereumAssets.USDC_A_TOKEN, | ||
address(this), | ||
REWARD_AMOUNT_PLUS_FEES + 1 // account for imprecision on transfer | ||
); | ||
|
||
uint256 aUSDCBalance = IERC20(AaveV3EthereumAssets.USDC_A_TOKEN).balanceOf(address(this)); | ||
|
||
// 2. approve to merkl | ||
IERC20(REWARD_TOKEN).forceApprove(address(DISTRIBUTION_CREATOR), aUSDCBalance); | ||
|
||
// 3. create campaign | ||
IDistributionCreator.CampaignParameters memory newCampaign = IDistributionCreator | ||
.CampaignParameters({ | ||
campaignId: '', | ||
creator: address(0), | ||
rewardToken: REWARD_TOKEN, | ||
amount: aUSDCBalance, | ||
campaignType: 4, | ||
startTimestamp: uint32(block.timestamp + 2 hours), | ||
duration: 1 hours, | ||
campaignData: abi.encode(FILE_URL, string(''), bytes('0x')) | ||
}); | ||
DISTRIBUTION_CREATOR.createCampaign(newCampaign); | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
...eV2Ethereum_AAMPLSecondDistribution/AaveV2Ethereum_AAMPLSecondDistribution_20240429.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,49 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import {AaveV2Ethereum} from 'aave-address-book/AaveV2Ethereum.sol'; | ||
import {AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; | ||
import {ProtocolV2TestBase} from 'aave-helpers/ProtocolV2TestBase.sol'; | ||
import {AaveV2Ethereum_AAMPLSecondDistribution_20240429, IDistributionCreator} from './AaveV2Ethereum_AAMPLSecondDistribution_20240429.sol'; | ||
import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; | ||
|
||
/** | ||
* @dev Test for AaveV2Ethereum_AAMPLSecondDistribution_20240429 | ||
* command: make test-contract filter=AaveV2Ethereum_AAMPLSecondDistribution_20240429 | ||
*/ | ||
contract AaveV2Ethereum_AAMPLSecondDistribution_20240429_Test is ProtocolV2TestBase { | ||
AaveV2Ethereum_AAMPLSecondDistribution_20240429 internal proposal; | ||
|
||
function setUp() public { | ||
vm.createSelectFork(vm.rpcUrl('mainnet'), 19761486); | ||
proposal = new AaveV2Ethereum_AAMPLSecondDistribution_20240429(); | ||
} | ||
|
||
/** | ||
* @dev executes the generic test suite including e2e and config snapshots | ||
*/ | ||
function test_defaultProposalExecution() public { | ||
defaultTest( | ||
'AaveV2Ethereum_AAMPLSecondDistribution_20240429', | ||
AaveV2Ethereum.POOL, | ||
address(proposal) | ||
); | ||
} | ||
|
||
function test_createCampaign() public { | ||
executePayload(vm, address(proposal)); | ||
|
||
IDistributionCreator.CampaignParameters memory campaign = proposal | ||
.DISTRIBUTION_CREATOR() | ||
.campaign(bytes32(0x04538a26c6088b568f6364ccc59b577ece656177c84076ab281dba3ea91576c7)); | ||
|
||
assertEq(campaign.creator, GovernanceV3Ethereum.EXECUTOR_LVL_1); | ||
assertEq(campaign.rewardToken, proposal.REWARD_TOKEN()); | ||
assertLt(campaign.amount, proposal.REWARD_AMOUNT_PLUS_FEES() + 1); | ||
assertEq(campaign.campaignType, 4); | ||
assertGt(campaign.startTimestamp, block.timestamp); | ||
assertEq(campaign.duration, 3600); | ||
(string memory url, , ) = abi.decode(campaign.campaignData, (string, string, bytes)); | ||
assertEq(url, proposal.FILE_URL()); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
src/20240429_AaveV2Ethereum_AAMPLSecondDistribution/config.ts
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,14 @@ | ||
import {ConfigFile} from '../../generator/types'; | ||
export const config: ConfigFile = { | ||
rootOptions: { | ||
pools: ['AaveV2Ethereum'], | ||
title: 'aAMPL Second Distribution', | ||
shortName: 'AAMPLSecondDistribution', | ||
date: '20240429', | ||
author: 'BGD Labs (@bgdlabs)', | ||
discussion: 'https://governance.aave.com/t/arfc-aampl-second-distribution/17464', | ||
snapshot: | ||
'https://snapshot.org/#/aave.eth/proposal/0x372ea60168390ca30be8890ae18ba3c1bb171428ad613a3c8c1a568721c1d65d', | ||
}, | ||
poolOptions: {AaveV2Ethereum: {configs: {}, cache: {blockNumber: 19760445}}}, | ||
}; |
Binary file not shown.
36 changes: 36 additions & 0 deletions
36
src/20240429_AaveV2Ethereum_AAMPLSecondDistribution/interfaces/IDistributionCreator.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,36 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
interface IDistributionCreator { | ||
struct CampaignParameters { | ||
// POPULATED ONCE CREATED | ||
|
||
// ID of the campaign. This can be left as a null bytes32 when creating campaigns | ||
// on Merkl. | ||
bytes32 campaignId; | ||
// CHOSEN BY CAMPAIGN CREATOR | ||
|
||
// Address of the campaign creator, if marked as address(0), it will be overriden with the | ||
// address of the `msg.sender` creating the campaign | ||
address creator; | ||
// Address of the token used as a reward | ||
address rewardToken; | ||
// Amount of `rewardToken` to distribute across all the epochs | ||
// Amount distributed per epoch is `amount/numEpoch` | ||
uint256 amount; | ||
// Type of campaign | ||
uint32 campaignType; | ||
// Timestamp at which the campaign should start | ||
uint32 startTimestamp; | ||
// Duration of the campaign in seconds. Has to be a multiple of EPOCH = 3600 | ||
uint32 duration; | ||
// Extra data to pass to specify the campaign | ||
bytes campaignData; | ||
} | ||
|
||
function campaign(bytes32 id) external view returns (CampaignParameters memory); | ||
|
||
function acceptConditions() external; | ||
|
||
function createCampaign(CampaignParameters memory newCampaign) external returns (bytes32); | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Amount here should be updated too