diff --git a/src/20240306_AaveV3Ethereum_MeritApprovals/AaveV3Ethereum_MeritApprovals_20240306.sol b/src/20240306_AaveV3Ethereum_MeritApprovals/AaveV3Ethereum_MeritApprovals_20240306.sol new file mode 100644 index 000000000..3a7d4ac7a --- /dev/null +++ b/src/20240306_AaveV3Ethereum_MeritApprovals/AaveV3Ethereum_MeritApprovals_20240306.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; +import {IProposalGenericExecutor} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol'; + +/** + * @title Merit Approvals + * @author karpatkey_TokenLogic_ACI + * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0xc80da83fadfe4f8a4c56e1643895cb7e9b1af1d9dcd374f1b41ded5c95b42f68 + * - Discussion: https://governance.aave.com/t/arfc-merit-a-new-aave-alignment-user-reward-system/16646 + */ +contract AaveV3Ethereum_MeritApprovals_20240306 is IProposalGenericExecutor { + uint256 public constant GHO_ALLOWANCE = 2_900_000 ether; + uint256 public constant WETH_V3_ALLOWANCE = 600 ether; + address public constant MERIT_WALLET = 0xdeadD8aB03075b7FBA81864202a2f59EE25B312b; + + function execute() external { + AaveV3Ethereum.COLLECTOR.approve( + AaveV3EthereumAssets.GHO_UNDERLYING, + MERIT_WALLET, + GHO_ALLOWANCE + ); + AaveV3Ethereum.COLLECTOR.approve( + AaveV3EthereumAssets.WETH_A_TOKEN, + MERIT_WALLET, + WETH_V3_ALLOWANCE + ); + } +} diff --git a/src/20240306_AaveV3Ethereum_MeritApprovals/AaveV3Ethereum_MeritApprovals_20240306.t.sol b/src/20240306_AaveV3Ethereum_MeritApprovals/AaveV3Ethereum_MeritApprovals_20240306.t.sol new file mode 100644 index 000000000..fb4966b4a --- /dev/null +++ b/src/20240306_AaveV3Ethereum_MeritApprovals/AaveV3Ethereum_MeritApprovals_20240306.t.sol @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; +import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; +import {ProtocolV3TestBase} from 'aave-helpers/ProtocolV3TestBase.sol'; + +import {AaveV3Ethereum_MeritApprovals_20240306} from './AaveV3Ethereum_MeritApprovals_20240306.sol'; + +/** + * @dev Test for AaveV3Ethereum_MeritApprovals_20240306 + * command: make test-contract filter=AaveV3Ethereum_MeritApprovals_20240306 + */ +contract AaveV3Ethereum_MeritApprovals_20240306_Test is ProtocolV3TestBase { + AaveV3Ethereum_MeritApprovals_20240306 internal proposal; + + function setUp() public { + vm.createSelectFork(vm.rpcUrl('mainnet'), 19377425); + proposal = new AaveV3Ethereum_MeritApprovals_20240306(); + } + + /** + * @dev executes the generic test suite including e2e and config snapshots + */ + function test_defaultProposalExecution() public { + assertEq( + IERC20(AaveV3EthereumAssets.GHO_UNDERLYING).allowance( + address(AaveV3Ethereum.COLLECTOR), + proposal.MERIT_WALLET() + ), + 0 + ); + assertEq( + IERC20(AaveV3EthereumAssets.WETH_A_TOKEN).allowance( + address(AaveV3Ethereum.COLLECTOR), + proposal.MERIT_WALLET() + ), + 0 + ); + + executePayload(vm, address(proposal)); + + assertEq( + IERC20(AaveV3EthereumAssets.GHO_UNDERLYING).allowance( + address(AaveV3Ethereum.COLLECTOR), + proposal.MERIT_WALLET() + ), + proposal.GHO_ALLOWANCE() + ); + assertEq( + IERC20(AaveV3EthereumAssets.WETH_A_TOKEN).allowance( + address(AaveV3Ethereum.COLLECTOR), + proposal.MERIT_WALLET() + ), + proposal.WETH_V3_ALLOWANCE() + ); + + vm.startPrank(proposal.MERIT_WALLET()); + IERC20(AaveV3EthereumAssets.GHO_UNDERLYING).transferFrom( + address(AaveV3Ethereum.COLLECTOR), + proposal.MERIT_WALLET(), + 2_000_000 ether + ); + IERC20(AaveV3EthereumAssets.WETH_A_TOKEN).transferFrom( + address(AaveV3Ethereum.COLLECTOR), + proposal.MERIT_WALLET(), + 500 ether + ); + } +} diff --git a/src/20240306_AaveV3Ethereum_MeritApprovals/MeritApprovals.md b/src/20240306_AaveV3Ethereum_MeritApprovals/MeritApprovals.md new file mode 100644 index 000000000..03f6df03d --- /dev/null +++ b/src/20240306_AaveV3Ethereum_MeritApprovals/MeritApprovals.md @@ -0,0 +1,32 @@ +--- +title: "Merit Approvals" +author: "karpatkey_TokenLogic_ACI" +discussions: "https://governance.aave.com/t/arfc-merit-a-new-aave-alignment-user-reward-system/16646" +snapshot: "https://snapshot.org/#/aave.eth/proposal/0xc80da83fadfe4f8a4c56e1643895cb7e9b1af1d9dcd374f1b41ded5c95b42f68" +--- + +## Simple Summary + +“Merit” proposes a merkle-tree-based periodic airdrop system, designed to reward Aave-aligned user behaviors and enhance protocol competitiveness, with a defined budget for the initial 90-day period. + +## Motivation + +Addressing the competitive DeFi landscape, “Merit” seeks to elevate Aave’s appeal and efficiency through a rewarding mechanism that prioritizes DAO-beneficial actions, distinguishing Aave from competitors employing artificial incentive methods. + +## Specification + +Merit SAFE: [0xdeadD8aB03075b7FBA81864202a2f59EE25B312b](https://etherscan.io/address/0xdeadD8aB03075b7FBA81864202a2f59EE25B312b) + +- Approve 2.9M GHO +- Approve 600 aEthWETH + +## References + +- Implementation: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240306_AaveV3Ethereum_MeritApprovals/AaveV3Ethereum_MeritApprovals_20240306.sol) +- Tests: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240306_AaveV3Ethereum_MeritApprovals/AaveV3Ethereum_MeritApprovals_20240306.t.sol) +- [Snapshot](https://snapshot.org/#/aave.eth/proposal/0xc80da83fadfe4f8a4c56e1643895cb7e9b1af1d9dcd374f1b41ded5c95b42f68) +- [Discussion](https://governance.aave.com/t/arfc-merit-a-new-aave-alignment-user-reward-system/16646) + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/src/20240306_AaveV3Ethereum_MeritApprovals/MeritApprovals_20240306.s.sol b/src/20240306_AaveV3Ethereum_MeritApprovals/MeritApprovals_20240306.s.sol new file mode 100644 index 000000000..37bfbf0f6 --- /dev/null +++ b/src/20240306_AaveV3Ethereum_MeritApprovals/MeritApprovals_20240306.s.sol @@ -0,0 +1,55 @@ +// 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_MeritApprovals_20240306} from './AaveV3Ethereum_MeritApprovals_20240306.sol'; + +/** + * @dev Deploy Ethereum + * deploy-command: make deploy-ledger contract=src/20240306_AaveV3Ethereum_MeritApprovals/MeritApprovals_20240306.s.sol:DeployEthereum chain=mainnet + * verify-command: npx catapulta-verify -b broadcast/MeritApprovals_20240306.s.sol/1/run-latest.json + */ +contract DeployEthereum is EthereumScript { + function run() external broadcast { + // deploy payloads + address payload0 = GovV3Helpers.deployDeterministic( + type(AaveV3Ethereum_MeritApprovals_20240306).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/20240306_AaveV3Ethereum_MeritApprovals/MeritApprovals_20240306.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_MeritApprovals_20240306).creationCode + ); + payloads[0] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum); + + // create proposal + vm.startBroadcast(); + GovV3Helpers.createProposal( + vm, + payloads, + GovV3Helpers.ipfsHashFile(vm, 'src/20240306_AaveV3Ethereum_MeritApprovals/MeritApprovals.md') + ); + } +} diff --git a/src/20240306_AaveV3Ethereum_MeritApprovals/config.ts b/src/20240306_AaveV3Ethereum_MeritApprovals/config.ts new file mode 100644 index 000000000..63f5f9508 --- /dev/null +++ b/src/20240306_AaveV3Ethereum_MeritApprovals/config.ts @@ -0,0 +1,15 @@ +import {ConfigFile} from '../../generator/types'; +export const config: ConfigFile = { + rootOptions: { + pools: ['AaveV3Ethereum'], + title: 'Merit Approvals', + shortName: 'MeritApprovals', + date: '20240306', + author: 'karpatkey_TokenLogic_ACI', + discussion: + 'https://governance.aave.com/t/arfc-merit-a-new-aave-alignment-user-reward-system/16646', + snapshot: + 'https://snapshot.org/#/aave.eth/proposal/0xc80da83fadfe4f8a4c56e1643895cb7e9b1af1d9dcd374f1b41ded5c95b42f68', + }, + poolOptions: {AaveV3Ethereum: {configs: {OTHERS: {}}, cache: {blockNumber: 19377425}}}, +};