From ec33feb93ce9fbd7ef8b9079ba6369c5cf4ea71f Mon Sep 17 00:00:00 2001 From: "defijesus.eth" Date: Wed, 27 Sep 2023 02:53:31 +0100 Subject: [PATCH 1/8] payload and tests done --- .../AaveV3_Ethereum_GHOFunding_20230926.sol | 157 ++++++++++++++++++ .../AaveV3_Ethereum_GHOFunding_20230926.t.sol | 66 ++++++++ .../AaveV3_GHOFunding_20230926.s.sol | 31 ++++ .../GHOFunding.md | 32 ++++ 4 files changed, 286 insertions(+) create mode 100644 src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol create mode 100644 src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol create mode 100644 src/20230926_AaveV3_Eth_GHOFunding/AaveV3_GHOFunding_20230926.s.sol create mode 100644 src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md diff --git a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol new file mode 100644 index 00000000..64459995 --- /dev/null +++ b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IProposalGenericExecutor} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol'; +import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; +import {AaveV2Ethereum, AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethereum.sol'; +import {AaveSwapper} from 'aave-helpers/swaps/AaveSwapper.sol'; +import {AaveMisc} from 'aave-address-book/AaveMisc.sol'; + +interface aTokenV1 { + function redeem(uint256 _amount) external; +} + +/** + * @title GHO Funding + * @author TokenLogic + * - Snapshot: TODO + * - Discussion: https://governance.aave.com/t/arfc-treasury-management-gho-funding/14887 + */ +contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { + + struct Asset { + address underlying; + address aToken; + address oracle; + uint256 amount; + } + + function execute() external { + address milkman = 0x11C76AD590ABDFFCD980afEC9ad951B160F02797; + address priceChecker = 0xe80a1C615F75AFF7Ed8F08c9F21f9d00982D666c; + address ghoOracle = 0x3f12643D3f6f874d39C2a4c9f2Cd6f2DbAC877FC; + AaveSwapper swapper = AaveSwapper(AaveMisc.AAVE_SWAPPER_ETHEREUM); + // DAI v2 + Asset memory DAIv2 = Asset({ + underlying: AaveV2EthereumAssets.DAI_UNDERLYING, + aToken: AaveV2EthereumAssets.DAI_A_TOKEN, + oracle: 0xAed0c38402a5d19df6E4c03F4E2DceD6e29c1ee9, + amount: 49_900 * 1e18 + }); + + // BUSD v2 + Asset memory BUSDv2 = Asset({ + underlying: AaveV2EthereumAssets.BUSD_UNDERLYING, + aToken: AaveV2EthereumAssets.BUSD_A_TOKEN, + oracle: 0x833D8Eb16D306ed1FbB5D7A2E019e106B960965A, + amount: 69_800 * 1e18 + }); + + // TUSD v2 + Asset memory TUSDv2 = Asset({ + underlying: AaveV2EthereumAssets.TUSD_UNDERLYING, + aToken: AaveV2EthereumAssets.TUSD_A_TOKEN, + oracle: 0xec746eCF986E2927Abd291a2A1716c940100f8Ba, + amount: 75_800 * 1e18 + }); + + // BUSD v1 (v1 aToken addresses are not in the aave-address-book repo) + Asset memory BUSDv1 = Asset({ + underlying: AaveV2EthereumAssets.BUSD_UNDERLYING, + aToken: 0x6Ee0f7BB50a54AB5253dA0667B0Dc2ee526C30a8, + oracle: 0x833D8Eb16D306ed1FbB5D7A2E019e106B960965A, + amount: 381_700 * 1e18 + }); + + // DAI v3 + Asset memory DAIv3 = Asset({ + underlying: AaveV3EthereumAssets.DAI_UNDERLYING, + aToken: AaveV3EthereumAssets.DAI_A_TOKEN, + oracle: 0xAed0c38402a5d19df6E4c03F4E2DceD6e29c1ee9, + amount: 400_000 * 1e18 + }); + + // USDT v2 + Asset memory USDTv2 = Asset({ + underlying: AaveV2EthereumAssets.USDT_UNDERLYING, + aToken: AaveV2EthereumAssets.USDT_A_TOKEN, + oracle: 0x3E7d1eAB13ad0104d2750B8863b489D65364e32D, + amount: 622_800 * 1e6 + }); + + + // DAI v2 & v3 swap + AaveV3Ethereum.COLLECTOR.transfer(DAIv2.aToken, address(this), DAIv2.amount); + AaveV3Ethereum.COLLECTOR.transfer(DAIv3.aToken, address(this), DAIv3.amount); + uint256 swapperBalance = + AaveV2Ethereum.POOL.withdraw(DAIv2.underlying, DAIv2.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); + swapperBalance += + AaveV3Ethereum.POOL.withdraw(DAIv3.underlying, DAIv3.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); + + swapper.swap( + milkman, + priceChecker, + DAIv2.underlying, + AaveV3EthereumAssets.GHO_UNDERLYING, + DAIv2.oracle, + ghoOracle, + address(AaveV3Ethereum.COLLECTOR), + swapperBalance, + 50 + ); + + // BUSD v2 & v1 swap + AaveV3Ethereum.COLLECTOR.transfer(BUSDv2.aToken, address(this), BUSDv2.amount); + AaveV3Ethereum.COLLECTOR.transfer(BUSDv1.underlying, AaveMisc.AAVE_SWAPPER_ETHEREUM, BUSDv1.amount); + swapperBalance = + AaveV2Ethereum.POOL.withdraw(BUSDv2.underlying, BUSDv2.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); + swapperBalance += BUSDv1.amount; + + swapper.swap( + milkman, + priceChecker, + BUSDv2.underlying, + AaveV3EthereumAssets.GHO_UNDERLYING, + BUSDv2.oracle, + ghoOracle, + address(AaveV3Ethereum.COLLECTOR), + swapperBalance, + 50 + ); + + // TUSD v2 swap + AaveV3Ethereum.COLLECTOR.transfer(TUSDv2.aToken, address(this), TUSDv2.amount); + swapperBalance = + AaveV2Ethereum.POOL.withdraw(TUSDv2.underlying, TUSDv2.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); + + swapper.swap( + milkman, + priceChecker, + TUSDv2.underlying, + AaveV3EthereumAssets.GHO_UNDERLYING, + TUSDv2.oracle, + ghoOracle, + address(AaveV3Ethereum.COLLECTOR), + swapperBalance, + 50 + ); + + // USDT v2 swap + AaveV3Ethereum.COLLECTOR.transfer(USDTv2.aToken, address(this), USDTv2.amount); + swapperBalance = + AaveV2Ethereum.POOL.withdraw(USDTv2.underlying, USDTv2.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); + + swapper.swap( + milkman, + priceChecker, + USDTv2.underlying, + AaveV3EthereumAssets.GHO_UNDERLYING, + USDTv2.oracle, + ghoOracle, + address(AaveV3Ethereum.COLLECTOR), + swapperBalance, + 50 + ); + + } +} diff --git a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol new file mode 100644 index 00000000..d5e03a5d --- /dev/null +++ b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import 'forge-std/Test.sol'; +import {GovHelpers} from 'aave-helpers/GovHelpers.sol'; +import {AaveGovernanceV2} from 'aave-address-book/AaveGovernanceV2.sol'; +import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/ProtocolV3TestBase.sol'; +import {AaveV3_Ethereum_GHOFunding_20230926} from './AaveV3_Ethereum_GHOFunding_20230926.sol'; +import {AaveV2Ethereum, AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethereum.sol'; +import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; + +/** + * @dev Test for AaveV3_Ethereum_GHOFunding_20230926 + * command: make test-contract filter=AaveV3_Ethereum_GHOFunding_20230926 + */ +contract AaveV3_Ethereum_GHOFunding_20230926_Test is ProtocolV3TestBase { + AaveV3_Ethereum_GHOFunding_20230926 internal proposal; + + struct Swap { + address proxy; + address underlying; + uint256 amount; + } + + function setUp() public { + vm.createSelectFork(vm.rpcUrl('mainnet'), 18222915); + proposal = new AaveV3_Ethereum_GHOFunding_20230926(); + } + + function testProposalExecution() public { + Swap[4] memory swaps; + // milkman creates intermediary contract for each swap + // while swap is not executed the assets will be in these swap-specific proxy addresses instead of aaveSwapper + // proxy contracts addresses are deterministic, they could be derived via code. + // I simulated execution and copy pasted the address for simplicity + // see https://etherscan.io/address/0x11C76AD590ABDFFCD980afEC9ad951B160F02797#code#L878 + swaps[0] = Swap({ + proxy: 0x2414B7eDd549E62e8a5877b73D96C80bAbC30bca, + underlying: AaveV2EthereumAssets.DAI_UNDERLYING, + amount: (49_900 + 400_000) * 1e18 + }); + swaps[1] = Swap({ + proxy: 0x86487dad62c99A37d0052ed56BF1EafF2959294D, + underlying: AaveV2EthereumAssets.BUSD_UNDERLYING, + amount: (69_800 + 381_700) * 1e18 + }); + swaps[2] = Swap({ + proxy: 0x3Df592eae98c2b4f312ADE339C01BBE2C8444618, + underlying: AaveV2EthereumAssets.TUSD_UNDERLYING, + amount: 75_800 * 1e18 + }); + swaps[3] = Swap({ + proxy: 0x0eB322ac55dB67a5cA0810BA0eDae3501b1B7263, + underlying: AaveV2EthereumAssets.USDT_UNDERLYING, + amount: 622_800 * 1e6 + }); + + GovHelpers.executePayload(vm, address(proposal), AaveGovernanceV2.SHORT_EXECUTOR); + + for(uint i = 0; i < swaps.length; i++) { + uint256 proxyBalanceAfter = IERC20(swaps[i].underlying).balanceOf(swaps[i].proxy); + assertEq(proxyBalanceAfter, swaps[i].amount); + } + + } +} diff --git a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_GHOFunding_20230926.s.sol b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_GHOFunding_20230926.s.sol new file mode 100644 index 00000000..b74f7ba9 --- /dev/null +++ b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_GHOFunding_20230926.s.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {GovHelpers} from 'aave-helpers/GovHelpers.sol'; +import {EthereumScript} from 'aave-helpers/ScriptUtils.sol'; +import {AaveV3_Ethereum_GHOFunding_20230926} from './AaveV3_Ethereum_GHOFunding_20230926.sol'; + +/** + * @dev Deploy AaveV3_Ethereum_GHOFunding_20230926 + * command: make deploy-ledger contract=src/20230926_AaveV3_Eth_GHOFunding/AaveV3_GHOFunding_20230926.s.sol:DeployEthereum chain=mainnet + */ +contract DeployEthereum is EthereumScript { + function run() external broadcast { + new AaveV3_Ethereum_GHOFunding_20230926(); + } +} + +/** + * @dev Create Proposal + * command: make deploy-ledger contract=src/20230926_AaveV3_Eth_GHOFunding/AaveV3_GHOFunding_20230926.s.sol:CreateProposal chain=mainnet + */ +contract CreateProposal is EthereumScript { + function run() external broadcast { + GovHelpers.Payload[] memory payloads = new GovHelpers.Payload[](1); + payloads[0] = GovHelpers.buildMainnet(address(0)); // TODO + GovHelpers.createProposal( + payloads, + GovHelpers.ipfsHashFile(vm, 'src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md') + ); + } +} diff --git a/src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md b/src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md new file mode 100644 index 00000000..be4bfac4 --- /dev/null +++ b/src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md @@ -0,0 +1,32 @@ +--- +title: "GHO Funding" +author: "TokenLogic" +discussions: "https://governance.aave.com/t/arfc-treasury-management-gho-funding/14887" +--- + +## Simple Summary + +## Motivation + +## Specification +Using the Aave Swap Contract, convert the following asset holdings to GHO: + +* 49,900 aDAI v2 +* 69,800 aBUSD v2 +* 75,800 aTUSD v2 +* 381,700 aBUSD v1 +* 400,000 aEthDAI v3 +* 622,800 aUSDT v2 + +The GHO will be transferred to the [Aave Ethereum Treasury](https://etherscan.io/address/0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c). + +## References + +- Implementation: [Ethereum](https://github.com/bgd-labs/aave-proposals/blob/main/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol) +- Tests: [Ethereum](https://github.com/bgd-labs/aave-proposals/blob/main/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol) +- [Snapshot](TODO) +- [Discussion](https://governance.aave.com/t/arfc-treasury-management-gho-funding/14887) + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 7f7d5c08eb5deaf1b5da35729da6d014f131840b Mon Sep 17 00:00:00 2001 From: "defijesus.eth" Date: Wed, 27 Sep 2023 03:00:13 +0100 Subject: [PATCH 2/8] minor fix --- .../AaveV3_Ethereum_GHOFunding_20230926.sol | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol index 64459995..d187f0c4 100644 --- a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol +++ b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol @@ -29,8 +29,10 @@ contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { function execute() external { address milkman = 0x11C76AD590ABDFFCD980afEC9ad951B160F02797; address priceChecker = 0xe80a1C615F75AFF7Ed8F08c9F21f9d00982D666c; - address ghoOracle = 0x3f12643D3f6f874d39C2a4c9f2Cd6f2DbAC877FC; + address ghoOracle = 0x3f12643D3f6f874d39C2a4c9f2Cd6f2DbAC877FC; AaveSwapper swapper = AaveSwapper(AaveMisc.AAVE_SWAPPER_ETHEREUM); + + // DAI v2 Asset memory DAIv2 = Asset({ underlying: AaveV2EthereumAssets.DAI_UNDERLYING, @@ -55,13 +57,8 @@ contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { amount: 75_800 * 1e18 }); - // BUSD v1 (v1 aToken addresses are not in the aave-address-book repo) - Asset memory BUSDv1 = Asset({ - underlying: AaveV2EthereumAssets.BUSD_UNDERLYING, - aToken: 0x6Ee0f7BB50a54AB5253dA0667B0Dc2ee526C30a8, - oracle: 0x833D8Eb16D306ed1FbB5D7A2E019e106B960965A, - amount: 381_700 * 1e18 - }); + // BUSD + uint256 busdAmount = 381_700 * 1e18; // DAI v3 Asset memory DAIv3 = Asset({ @@ -102,10 +99,10 @@ contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { // BUSD v2 & v1 swap AaveV3Ethereum.COLLECTOR.transfer(BUSDv2.aToken, address(this), BUSDv2.amount); - AaveV3Ethereum.COLLECTOR.transfer(BUSDv1.underlying, AaveMisc.AAVE_SWAPPER_ETHEREUM, BUSDv1.amount); + AaveV3Ethereum.COLLECTOR.transfer(BUSDv2.underlying, AaveMisc.AAVE_SWAPPER_ETHEREUM, busdAmount); swapperBalance = AaveV2Ethereum.POOL.withdraw(BUSDv2.underlying, BUSDv2.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); - swapperBalance += BUSDv1.amount; + swapperBalance += busdAmount; swapper.swap( milkman, From efbd09805ec3dda5afb7e88ffa7fee45ba6e97dc Mon Sep 17 00:00:00 2001 From: "defijesus.eth" Date: Fri, 6 Oct 2023 02:54:02 +0100 Subject: [PATCH 3/8] ready for review --- .../AaveV3_Ethereum_GHOFunding_20230926.sol | 108 ++++++------------ .../AaveV3_Ethereum_GHOFunding_20230926.t.sol | 20 ++-- .../GHOFunding.md | 31 +++-- 3 files changed, 71 insertions(+), 88 deletions(-) diff --git a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol index d187f0c4..4ebfd7ac 100644 --- a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol +++ b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol @@ -6,6 +6,8 @@ import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethe import {AaveV2Ethereum, AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethereum.sol'; import {AaveSwapper} from 'aave-helpers/swaps/AaveSwapper.sol'; import {AaveMisc} from 'aave-address-book/AaveMisc.sol'; +import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; +import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol'; interface aTokenV1 { function redeem(uint256 _amount) external; @@ -27,18 +29,12 @@ contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { } function execute() external { - address milkman = 0x11C76AD590ABDFFCD980afEC9ad951B160F02797; - address priceChecker = 0xe80a1C615F75AFF7Ed8F08c9F21f9d00982D666c; - address ghoOracle = 0x3f12643D3f6f874d39C2a4c9f2Cd6f2DbAC877FC; - AaveSwapper swapper = AaveSwapper(AaveMisc.AAVE_SWAPPER_ETHEREUM); - - // DAI v2 Asset memory DAIv2 = Asset({ underlying: AaveV2EthereumAssets.DAI_UNDERLYING, aToken: AaveV2EthereumAssets.DAI_A_TOKEN, oracle: 0xAed0c38402a5d19df6E4c03F4E2DceD6e29c1ee9, - amount: 49_900 * 1e18 + amount: IERC20(AaveV2EthereumAssets.DAI_A_TOKEN).balanceOf(address(AaveV3Ethereum.COLLECTOR)) }); // BUSD v2 @@ -46,20 +42,9 @@ contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { underlying: AaveV2EthereumAssets.BUSD_UNDERLYING, aToken: AaveV2EthereumAssets.BUSD_A_TOKEN, oracle: 0x833D8Eb16D306ed1FbB5D7A2E019e106B960965A, - amount: 69_800 * 1e18 + amount: IERC20(AaveV2EthereumAssets.BUSD_A_TOKEN).balanceOf(address(AaveV3Ethereum.COLLECTOR)) }); - // TUSD v2 - Asset memory TUSDv2 = Asset({ - underlying: AaveV2EthereumAssets.TUSD_UNDERLYING, - aToken: AaveV2EthereumAssets.TUSD_A_TOKEN, - oracle: 0xec746eCF986E2927Abd291a2A1716c940100f8Ba, - amount: 75_800 * 1e18 - }); - - // BUSD - uint256 busdAmount = 381_700 * 1e18; - // DAI v3 Asset memory DAIv3 = Asset({ underlying: AaveV3EthereumAssets.DAI_UNDERLYING, @@ -73,82 +58,63 @@ contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { underlying: AaveV2EthereumAssets.USDT_UNDERLYING, aToken: AaveV2EthereumAssets.USDT_A_TOKEN, oracle: 0x3E7d1eAB13ad0104d2750B8863b489D65364e32D, - amount: 622_800 * 1e6 + amount: 1_100_000 * 1e6 + }); + + // USDT v3 + Asset memory USDTv3 = Asset({ + underlying: AaveV3EthereumAssets.USDT_UNDERLYING, + aToken: AaveV3EthereumAssets.USDT_A_TOKEN, + oracle: 0x3E7d1eAB13ad0104d2750B8863b489D65364e32D, + amount: 500_000 * 1e6 }); - // DAI v2 & v3 swap + ////// DAI v2 & v3 swap ////// AaveV3Ethereum.COLLECTOR.transfer(DAIv2.aToken, address(this), DAIv2.amount); AaveV3Ethereum.COLLECTOR.transfer(DAIv3.aToken, address(this), DAIv3.amount); uint256 swapperBalance = AaveV2Ethereum.POOL.withdraw(DAIv2.underlying, DAIv2.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); swapperBalance += AaveV3Ethereum.POOL.withdraw(DAIv3.underlying, DAIv3.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); + swapAsset(DAIv2, swapperBalance); - swapper.swap( - milkman, - priceChecker, - DAIv2.underlying, - AaveV3EthereumAssets.GHO_UNDERLYING, - DAIv2.oracle, - ghoOracle, - address(AaveV3Ethereum.COLLECTOR), - swapperBalance, - 50 - ); - - // BUSD v2 & v1 swap + ////// BUSD v2 & v1 swap ////// + // transfer max busd to payload + swapperBalance = IERC20(BUSDv2.underlying).balanceOf(address(AaveV3Ethereum.COLLECTOR)); + AaveV3Ethereum.COLLECTOR.transfer(BUSDv2.underlying, address (this), swapperBalance); + // transfer specific amount of busdv2 to payload AaveV3Ethereum.COLLECTOR.transfer(BUSDv2.aToken, address(this), BUSDv2.amount); - AaveV3Ethereum.COLLECTOR.transfer(BUSDv2.underlying, AaveMisc.AAVE_SWAPPER_ETHEREUM, busdAmount); - swapperBalance = - AaveV2Ethereum.POOL.withdraw(BUSDv2.underlying, BUSDv2.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); - swapperBalance += busdAmount; - - swapper.swap( - milkman, - priceChecker, - BUSDv2.underlying, - AaveV3EthereumAssets.GHO_UNDERLYING, - BUSDv2.oracle, - ghoOracle, - address(AaveV3Ethereum.COLLECTOR), - swapperBalance, - 50 - ); + swapperBalance += AaveV2Ethereum.POOL.withdraw(BUSDv2.underlying, BUSDv2.amount, address(this)); - // TUSD v2 swap - AaveV3Ethereum.COLLECTOR.transfer(TUSDv2.aToken, address(this), TUSDv2.amount); - swapperBalance = - AaveV2Ethereum.POOL.withdraw(TUSDv2.underlying, TUSDv2.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); - - swapper.swap( - milkman, - priceChecker, - TUSDv2.underlying, - AaveV3EthereumAssets.GHO_UNDERLYING, - TUSDv2.oracle, - ghoOracle, - address(AaveV3Ethereum.COLLECTOR), - swapperBalance, - 50 - ); + SafeERC20.safeTransfer(IERC20(BUSDv2.underlying), AaveMisc.AAVE_SWAPPER_ETHEREUM, swapperBalance); + swapAsset(BUSDv2, swapperBalance); - // USDT v2 swap + ////// USDT v2 & v3 swap ////// AaveV3Ethereum.COLLECTOR.transfer(USDTv2.aToken, address(this), USDTv2.amount); + AaveV3Ethereum.COLLECTOR.transfer(USDTv3.aToken, address(this), USDTv3.amount); swapperBalance = AaveV2Ethereum.POOL.withdraw(USDTv2.underlying, USDTv2.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); + swapperBalance += + AaveV3Ethereum.POOL.withdraw(USDTv3.underlying, USDTv3.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); + swapAsset(USDTv2, swapperBalance); + } + function swapAsset(Asset memory asset, uint256 amount) internal { + address milkman = 0x11C76AD590ABDFFCD980afEC9ad951B160F02797; + address priceChecker = 0xe80a1C615F75AFF7Ed8F08c9F21f9d00982D666c; + address ghoOracle = 0x3f12643D3f6f874d39C2a4c9f2Cd6f2DbAC877FC; + AaveSwapper swapper = AaveSwapper(AaveMisc.AAVE_SWAPPER_ETHEREUM); swapper.swap( milkman, priceChecker, - USDTv2.underlying, + asset.underlying, AaveV3EthereumAssets.GHO_UNDERLYING, - USDTv2.oracle, + asset.oracle, ghoOracle, address(AaveV3Ethereum.COLLECTOR), - swapperBalance, + amount, 50 ); - } } diff --git a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol index d5e03a5d..188deac3 100644 --- a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol +++ b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol @@ -23,12 +23,16 @@ contract AaveV3_Ethereum_GHOFunding_20230926_Test is ProtocolV3TestBase { } function setUp() public { - vm.createSelectFork(vm.rpcUrl('mainnet'), 18222915); + vm.createSelectFork(vm.rpcUrl('mainnet'), 18274396); proposal = new AaveV3_Ethereum_GHOFunding_20230926(); } function testProposalExecution() public { - Swap[4] memory swaps; + uint256 daiv2CollectorBalance = IERC20(AaveV2EthereumAssets.DAI_A_TOKEN).balanceOf(address(AaveV2Ethereum.COLLECTOR)); + uint256 busdv2CollectorBalance = IERC20(AaveV2EthereumAssets.BUSD_A_TOKEN).balanceOf(address(AaveV2Ethereum.COLLECTOR)); + uint256 busdCollectorBalance = IERC20(AaveV2EthereumAssets.BUSD_UNDERLYING).balanceOf(address(AaveV2Ethereum.COLLECTOR)); + // uint256 tusdv2CollectorBalance = 75_800 * 1e18; + Swap[3] memory swaps; // milkman creates intermediary contract for each swap // while swap is not executed the assets will be in these swap-specific proxy addresses instead of aaveSwapper // proxy contracts addresses are deterministic, they could be derived via code. @@ -37,22 +41,18 @@ contract AaveV3_Ethereum_GHOFunding_20230926_Test is ProtocolV3TestBase { swaps[0] = Swap({ proxy: 0x2414B7eDd549E62e8a5877b73D96C80bAbC30bca, underlying: AaveV2EthereumAssets.DAI_UNDERLYING, - amount: (49_900 + 400_000) * 1e18 + amount: (400_000 * 1e18) + daiv2CollectorBalance }); swaps[1] = Swap({ proxy: 0x86487dad62c99A37d0052ed56BF1EafF2959294D, underlying: AaveV2EthereumAssets.BUSD_UNDERLYING, - amount: (69_800 + 381_700) * 1e18 + amount: busdv2CollectorBalance + busdCollectorBalance }); + swaps[2] = Swap({ proxy: 0x3Df592eae98c2b4f312ADE339C01BBE2C8444618, - underlying: AaveV2EthereumAssets.TUSD_UNDERLYING, - amount: 75_800 * 1e18 - }); - swaps[3] = Swap({ - proxy: 0x0eB322ac55dB67a5cA0810BA0eDae3501b1B7263, underlying: AaveV2EthereumAssets.USDT_UNDERLYING, - amount: 622_800 * 1e6 + amount: 1_600_000 * 1e6 }); GovHelpers.executePayload(vm, address(proposal), AaveGovernanceV2.SHORT_EXECUTOR); diff --git a/src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md b/src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md index be4bfac4..5720c182 100644 --- a/src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md +++ b/src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md @@ -6,17 +6,30 @@ discussions: "https://governance.aave.com/t/arfc-treasury-management-gho-funding ## Simple Summary +This publication aims to acquire GHO from secondary markets to support the Aave DAO's short-term funding requirements. + ## Motivation +The primary objective of this publication is to shift Aave DAO's expenditure towards being nominated in GHO. The following outlines some potential use cases for GHO: + +* 328,000 GHO allowance over 6 months [Aave Grants Continuation Proposal](https://governance.aave.com/t/temp-check-updated-aave-grants-continuation-proposal/14951) +* 550,000 GHO over 3 months[Aave Events & Sponsorship](https://governance.aave.com/t/temp-check-aave-events-sponsorship-budget/14953) +* 75,000 GHO over 3 months [Expansion of “Orbit”](https://governance.aave.com/t/arfc-expansion-of-orbit-a-dao-funded-delegate-platform-initiative/14785) +* 406,000 GHO over 3 months [GHO Liquidity Committee](https://governance.aave.com/t/temp-check-treasury-management-create-and-fund-gho-liquidity-committee/14800) +* TBA Future ACI Funding Request (Renewal mid-October) + +Totaling 1,359,000 GHO plus future ACI budget. + +This proposal is expected to acquire approximately $1.6M from secondary markets based on current holdings in the Ethereum Treasury. + ## Specification Using the Aave Swap Contract, convert the following asset holdings to GHO: -* 49,900 aDAI v2 -* 69,800 aBUSD v2 -* 75,800 aTUSD v2 -* 381,700 aBUSD v1 -* 400,000 aEthDAI v3 -* 622,800 aUSDT v2 +* [aDAI v2](https://etherscan.io/token/0x028171bca77440897b824ca71d1c56cac55b68a3?a=0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c) +* [aBUSD v2](https://etherscan.io/token/0xa361718326c15715591c299427c62086f69923d9?a=0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c) +* [BUSD](https://etherscan.io/token/0x4fabb145d64652a948d72533023f6e7a623c7c53?a=0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c) +* [400,000 aEthDAI v3](https://etherscan.io/token/0x018008bfb33d285247a21d44e50697654f754e63?a=0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c) +* [400,000 aUSDT v2](https://etherscan.io/token/0x3ed3b47dd13ec9a98b44e6204a523e766b225811?a=0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c) The GHO will be transferred to the [Aave Ethereum Treasury](https://etherscan.io/address/0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c). @@ -24,9 +37,13 @@ The GHO will be transferred to the [Aave Ethereum Treasury](https://etherscan.io - Implementation: [Ethereum](https://github.com/bgd-labs/aave-proposals/blob/main/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol) - Tests: [Ethereum](https://github.com/bgd-labs/aave-proposals/blob/main/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol) -- [Snapshot](TODO) +- [Snapshot](https://snapshot.org/#/aave.eth/proposal/0xb094cdc806d407d0cf4ea00e595ae95b8c145f77b77cce165c463326cc757639) - [Discussion](https://governance.aave.com/t/arfc-treasury-management-gho-funding/14887) +# Disclosure + +TokenLogic receives no payment from Aave DAO or any external source for the creation of this proposal. TokenLogic is a delegate within the Aave ecosystem. + ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From e0f309d81253403df40256bf0331b3f4a5c9b543 Mon Sep 17 00:00:00 2001 From: "defijesus.eth" Date: Mon, 9 Oct 2023 17:12:43 +0100 Subject: [PATCH 4/8] ready for review again --- .../AaveV3_Ethereum_GHOFunding_20230926.sol | 74 +++++++++---------- .../AaveV3_Ethereum_GHOFunding_20230926.t.sol | 35 ++++++--- .../GHOFunding.md | 6 +- 3 files changed, 61 insertions(+), 54 deletions(-) diff --git a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol index 4ebfd7ac..40e2dd92 100644 --- a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol +++ b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol @@ -16,7 +16,7 @@ interface aTokenV1 { /** * @title GHO Funding * @author TokenLogic - * - Snapshot: TODO + * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0xb094cdc806d407d0cf4ea00e595ae95b8c145f77b77cce165c463326cc757639 * - Discussion: https://governance.aave.com/t/arfc-treasury-management-gho-funding/14887 */ contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { @@ -28,21 +28,18 @@ contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { uint256 amount; } + address public constant COLLECTOR = address(AaveV3Ethereum.COLLECTOR); + address public constant MILKMAN = 0x11C76AD590ABDFFCD980afEC9ad951B160F02797; + address public constant PRICE_CHECKER = 0xe80a1C615F75AFF7Ed8F08c9F21f9d00982D666c; + address public constant GHO_ORACLE = 0x3f12643D3f6f874d39C2a4c9f2Cd6f2DbAC877FC; + function execute() external { // DAI v2 Asset memory DAIv2 = Asset({ underlying: AaveV2EthereumAssets.DAI_UNDERLYING, aToken: AaveV2EthereumAssets.DAI_A_TOKEN, oracle: 0xAed0c38402a5d19df6E4c03F4E2DceD6e29c1ee9, - amount: IERC20(AaveV2EthereumAssets.DAI_A_TOKEN).balanceOf(address(AaveV3Ethereum.COLLECTOR)) - }); - - // BUSD v2 - Asset memory BUSDv2 = Asset({ - underlying: AaveV2EthereumAssets.BUSD_UNDERLYING, - aToken: AaveV2EthereumAssets.BUSD_A_TOKEN, - oracle: 0x833D8Eb16D306ed1FbB5D7A2E019e106B960965A, - amount: IERC20(AaveV2EthereumAssets.BUSD_A_TOKEN).balanceOf(address(AaveV3Ethereum.COLLECTOR)) + amount: IERC20(AaveV2EthereumAssets.DAI_A_TOKEN).balanceOf(COLLECTOR) }); // DAI v3 @@ -50,7 +47,7 @@ contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { underlying: AaveV3EthereumAssets.DAI_UNDERLYING, aToken: AaveV3EthereumAssets.DAI_A_TOKEN, oracle: 0xAed0c38402a5d19df6E4c03F4E2DceD6e29c1ee9, - amount: 400_000 * 1e18 + amount: 370_000 * 1e18 }); // USDT v2 @@ -58,15 +55,23 @@ contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { underlying: AaveV2EthereumAssets.USDT_UNDERLYING, aToken: AaveV2EthereumAssets.USDT_A_TOKEN, oracle: 0x3E7d1eAB13ad0104d2750B8863b489D65364e32D, - amount: 1_100_000 * 1e6 + amount: 370_000 * 1e6 }); - // USDT v3 - Asset memory USDTv3 = Asset({ - underlying: AaveV3EthereumAssets.USDT_UNDERLYING, - aToken: AaveV3EthereumAssets.USDT_A_TOKEN, - oracle: 0x3E7d1eAB13ad0104d2750B8863b489D65364e32D, - amount: 500_000 * 1e6 + // BUSD + Asset memory BUSD = Asset({ + underlying: AaveV2EthereumAssets.BUSD_UNDERLYING, + aToken: address(0), // not used + oracle: 0x833D8Eb16D306ed1FbB5D7A2E019e106B960965A, + amount: IERC20(AaveV2EthereumAssets.BUSD_UNDERLYING).balanceOf(COLLECTOR) + }); + + // TUSD v2 + Asset memory TUSD = Asset({ + underlying: AaveV2EthereumAssets.TUSD_UNDERLYING, + aToken: address(0), // not used + oracle: 0xec746eCF986E2927Abd291a2A1716c940100f8Ba, + amount: IERC20(AaveV2EthereumAssets.TUSD_UNDERLYING).balanceOf(COLLECTOR) }); @@ -79,40 +84,31 @@ contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { AaveV3Ethereum.POOL.withdraw(DAIv3.underlying, DAIv3.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); swapAsset(DAIv2, swapperBalance); - ////// BUSD v2 & v1 swap ////// - // transfer max busd to payload - swapperBalance = IERC20(BUSDv2.underlying).balanceOf(address(AaveV3Ethereum.COLLECTOR)); - AaveV3Ethereum.COLLECTOR.transfer(BUSDv2.underlying, address (this), swapperBalance); - // transfer specific amount of busdv2 to payload - AaveV3Ethereum.COLLECTOR.transfer(BUSDv2.aToken, address(this), BUSDv2.amount); - swapperBalance += AaveV2Ethereum.POOL.withdraw(BUSDv2.underlying, BUSDv2.amount, address(this)); - - SafeERC20.safeTransfer(IERC20(BUSDv2.underlying), AaveMisc.AAVE_SWAPPER_ETHEREUM, swapperBalance); - swapAsset(BUSDv2, swapperBalance); + ////// BUSD swap ////// + AaveV3Ethereum.COLLECTOR.transfer(BUSD.underlying, AaveMisc.AAVE_SWAPPER_ETHEREUM, BUSD.amount); + swapAsset(BUSD, BUSD.amount); + + ////// TUSD swap ////// + AaveV3Ethereum.COLLECTOR.transfer(TUSD.underlying, AaveMisc.AAVE_SWAPPER_ETHEREUM, TUSD.amount); + swapAsset(TUSD, TUSD.amount); - ////// USDT v2 & v3 swap ////// + ////// USDT v2 swap ////// AaveV3Ethereum.COLLECTOR.transfer(USDTv2.aToken, address(this), USDTv2.amount); - AaveV3Ethereum.COLLECTOR.transfer(USDTv3.aToken, address(this), USDTv3.amount); swapperBalance = AaveV2Ethereum.POOL.withdraw(USDTv2.underlying, USDTv2.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); - swapperBalance += - AaveV3Ethereum.POOL.withdraw(USDTv3.underlying, USDTv3.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); swapAsset(USDTv2, swapperBalance); } function swapAsset(Asset memory asset, uint256 amount) internal { - address milkman = 0x11C76AD590ABDFFCD980afEC9ad951B160F02797; - address priceChecker = 0xe80a1C615F75AFF7Ed8F08c9F21f9d00982D666c; - address ghoOracle = 0x3f12643D3f6f874d39C2a4c9f2Cd6f2DbAC877FC; AaveSwapper swapper = AaveSwapper(AaveMisc.AAVE_SWAPPER_ETHEREUM); swapper.swap( - milkman, - priceChecker, + MILKMAN, + PRICE_CHECKER, asset.underlying, AaveV3EthereumAssets.GHO_UNDERLYING, asset.oracle, - ghoOracle, - address(AaveV3Ethereum.COLLECTOR), + GHO_ORACLE, + COLLECTOR, amount, 50 ); diff --git a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol index 188deac3..b050bd25 100644 --- a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol +++ b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol @@ -6,6 +6,7 @@ import {GovHelpers} from 'aave-helpers/GovHelpers.sol'; import {AaveGovernanceV2} from 'aave-address-book/AaveGovernanceV2.sol'; import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/ProtocolV3TestBase.sol'; import {AaveV3_Ethereum_GHOFunding_20230926} from './AaveV3_Ethereum_GHOFunding_20230926.sol'; +import {AaveV2_Ethereum_TUSDOffboardingPlanPartII_20230925} from '../20230925_AaveV2_Eth_TUSDOffboardingPlanPartII/AaveV2_Ethereum_TUSDOffboardingPlanPartII_20230925.sol'; import {AaveV2Ethereum, AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethereum.sol'; import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; @@ -15,6 +16,7 @@ import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; */ contract AaveV3_Ethereum_GHOFunding_20230926_Test is ProtocolV3TestBase { AaveV3_Ethereum_GHOFunding_20230926 internal proposal; + AaveV2_Ethereum_TUSDOffboardingPlanPartII_20230925 internal pastProposal; struct Swap { address proxy; @@ -23,36 +25,45 @@ contract AaveV3_Ethereum_GHOFunding_20230926_Test is ProtocolV3TestBase { } function setUp() public { - vm.createSelectFork(vm.rpcUrl('mainnet'), 18274396); + vm.createSelectFork(vm.rpcUrl('mainnet'), 18313824); + pastProposal = new AaveV2_Ethereum_TUSDOffboardingPlanPartII_20230925(); proposal = new AaveV3_Ethereum_GHOFunding_20230926(); } function testProposalExecution() public { - uint256 daiv2CollectorBalance = IERC20(AaveV2EthereumAssets.DAI_A_TOKEN).balanceOf(address(AaveV2Ethereum.COLLECTOR)); - uint256 busdv2CollectorBalance = IERC20(AaveV2EthereumAssets.BUSD_A_TOKEN).balanceOf(address(AaveV2Ethereum.COLLECTOR)); - uint256 busdCollectorBalance = IERC20(AaveV2EthereumAssets.BUSD_UNDERLYING).balanceOf(address(AaveV2Ethereum.COLLECTOR)); - // uint256 tusdv2CollectorBalance = 75_800 * 1e18; - Swap[3] memory swaps; + address COLLECTOR = address(AaveV2Ethereum.COLLECTOR); + + // this prop redeems tusd and busd from aave v2, we need it to be executed before we execute ours. + GovHelpers.executePayload(vm, address(pastProposal), AaveGovernanceV2.SHORT_EXECUTOR); + + Swap[4] memory swaps; // milkman creates intermediary contract for each swap // while swap is not executed the assets will be in these swap-specific proxy addresses instead of aaveSwapper // proxy contracts addresses are deterministic, they could be derived via code. // I simulated execution and copy pasted the address for simplicity // see https://etherscan.io/address/0x11C76AD590ABDFFCD980afEC9ad951B160F02797#code#L878 swaps[0] = Swap({ - proxy: 0x2414B7eDd549E62e8a5877b73D96C80bAbC30bca, + proxy: 0x3Df592eae98c2b4f312ADE339C01BBE2C8444618, underlying: AaveV2EthereumAssets.DAI_UNDERLYING, - amount: (400_000 * 1e18) + daiv2CollectorBalance + amount: (370_000 * 1e18) + IERC20(AaveV2EthereumAssets.DAI_A_TOKEN).balanceOf(COLLECTOR) }); + swaps[1] = Swap({ - proxy: 0x86487dad62c99A37d0052ed56BF1EafF2959294D, + proxy: 0x0eB322ac55dB67a5cA0810BA0eDae3501b1B7263, underlying: AaveV2EthereumAssets.BUSD_UNDERLYING, - amount: busdv2CollectorBalance + busdCollectorBalance + amount: IERC20(AaveV2EthereumAssets.BUSD_UNDERLYING).balanceOf(COLLECTOR) }); swaps[2] = Swap({ - proxy: 0x3Df592eae98c2b4f312ADE339C01BBE2C8444618, + proxy: 0x8F2ca8bE5e06180d36117A8aE3f615837790d59B, + underlying: AaveV2EthereumAssets.TUSD_UNDERLYING, + amount: IERC20(AaveV2EthereumAssets.TUSD_UNDERLYING).balanceOf(COLLECTOR) + }); + + swaps[3] = Swap({ + proxy: 0xfEc76f65e943239E5A7CDC3CA6a89c26a0803FFd, underlying: AaveV2EthereumAssets.USDT_UNDERLYING, - amount: 1_600_000 * 1e6 + amount: 370_000 * 1e6 }); GovHelpers.executePayload(vm, address(proposal), AaveGovernanceV2.SHORT_EXECUTOR); diff --git a/src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md b/src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md index 5720c182..78a3d858 100644 --- a/src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md +++ b/src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md @@ -26,10 +26,10 @@ This proposal is expected to acquire approximately $1.6M from secondary markets Using the Aave Swap Contract, convert the following asset holdings to GHO: * [aDAI v2](https://etherscan.io/token/0x028171bca77440897b824ca71d1c56cac55b68a3?a=0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c) -* [aBUSD v2](https://etherscan.io/token/0xa361718326c15715591c299427c62086f69923d9?a=0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c) +* [TUSD](https://etherscan.io/address/0x0000000000085d4780B73119b644AE5ecd22b376?a=0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c) * [BUSD](https://etherscan.io/token/0x4fabb145d64652a948d72533023f6e7a623c7c53?a=0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c) -* [400,000 aEthDAI v3](https://etherscan.io/token/0x018008bfb33d285247a21d44e50697654f754e63?a=0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c) -* [400,000 aUSDT v2](https://etherscan.io/token/0x3ed3b47dd13ec9a98b44e6204a523e766b225811?a=0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c) +* [370,000 aEthDAI v3](https://etherscan.io/token/0x018008bfb33d285247a21d44e50697654f754e63?a=0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c) +* [370,000 aUSDT v2](https://etherscan.io/token/0x3ed3b47dd13ec9a98b44e6204a523e766b225811?a=0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c) The GHO will be transferred to the [Aave Ethereum Treasury](https://etherscan.io/address/0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c). From 084eb9ab543560b7dd1906047e6307aeeb671c25 Mon Sep 17 00:00:00 2001 From: "defijesus.eth" Date: Wed, 11 Oct 2023 16:40:18 +0100 Subject: [PATCH 5/8] fix all issues raised in review --- .../AaveV3_Ethereum_GHOFunding_20230926.sol | 12 ++++++------ .../AaveV3_Ethereum_GHOFunding_20230926.t.sol | 8 +------- src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md | 4 ++-- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol index 40e2dd92..50a6ed25 100644 --- a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol +++ b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol @@ -17,7 +17,7 @@ interface aTokenV1 { * @title GHO Funding * @author TokenLogic * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0xb094cdc806d407d0cf4ea00e595ae95b8c145f77b77cce165c463326cc757639 - * - Discussion: https://governance.aave.com/t/arfc-treasury-management-gho-funding/14887 + * - Discussion: https://governance.aave.com/t/arfc-treasury-management-gho-funding/14887/10 */ contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { @@ -78,11 +78,11 @@ contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { ////// DAI v2 & v3 swap ////// AaveV3Ethereum.COLLECTOR.transfer(DAIv2.aToken, address(this), DAIv2.amount); AaveV3Ethereum.COLLECTOR.transfer(DAIv3.aToken, address(this), DAIv3.amount); - uint256 swapperBalance = + uint256 daiAmount = AaveV2Ethereum.POOL.withdraw(DAIv2.underlying, DAIv2.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); - swapperBalance += + daiAmount += AaveV3Ethereum.POOL.withdraw(DAIv3.underlying, DAIv3.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); - swapAsset(DAIv2, swapperBalance); + swapAsset(DAIv2, daiAmount); ////// BUSD swap ////// AaveV3Ethereum.COLLECTOR.transfer(BUSD.underlying, AaveMisc.AAVE_SWAPPER_ETHEREUM, BUSD.amount); @@ -94,9 +94,9 @@ contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { ////// USDT v2 swap ////// AaveV3Ethereum.COLLECTOR.transfer(USDTv2.aToken, address(this), USDTv2.amount); - swapperBalance = + uint256 usdtAmount = AaveV2Ethereum.POOL.withdraw(USDTv2.underlying, USDTv2.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); - swapAsset(USDTv2, swapperBalance); + swapAsset(USDTv2, usdtAmount); } function swapAsset(Asset memory asset, uint256 amount) internal { diff --git a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol index b050bd25..458765be 100644 --- a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol +++ b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol @@ -6,7 +6,6 @@ import {GovHelpers} from 'aave-helpers/GovHelpers.sol'; import {AaveGovernanceV2} from 'aave-address-book/AaveGovernanceV2.sol'; import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/ProtocolV3TestBase.sol'; import {AaveV3_Ethereum_GHOFunding_20230926} from './AaveV3_Ethereum_GHOFunding_20230926.sol'; -import {AaveV2_Ethereum_TUSDOffboardingPlanPartII_20230925} from '../20230925_AaveV2_Eth_TUSDOffboardingPlanPartII/AaveV2_Ethereum_TUSDOffboardingPlanPartII_20230925.sol'; import {AaveV2Ethereum, AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethereum.sol'; import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; @@ -16,7 +15,6 @@ import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; */ contract AaveV3_Ethereum_GHOFunding_20230926_Test is ProtocolV3TestBase { AaveV3_Ethereum_GHOFunding_20230926 internal proposal; - AaveV2_Ethereum_TUSDOffboardingPlanPartII_20230925 internal pastProposal; struct Swap { address proxy; @@ -25,17 +23,13 @@ contract AaveV3_Ethereum_GHOFunding_20230926_Test is ProtocolV3TestBase { } function setUp() public { - vm.createSelectFork(vm.rpcUrl('mainnet'), 18313824); - pastProposal = new AaveV2_Ethereum_TUSDOffboardingPlanPartII_20230925(); + vm.createSelectFork(vm.rpcUrl('mainnet'), 18328137); proposal = new AaveV3_Ethereum_GHOFunding_20230926(); } function testProposalExecution() public { address COLLECTOR = address(AaveV2Ethereum.COLLECTOR); - // this prop redeems tusd and busd from aave v2, we need it to be executed before we execute ours. - GovHelpers.executePayload(vm, address(pastProposal), AaveGovernanceV2.SHORT_EXECUTOR); - Swap[4] memory swaps; // milkman creates intermediary contract for each swap // while swap is not executed the assets will be in these swap-specific proxy addresses instead of aaveSwapper diff --git a/src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md b/src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md index 78a3d858..5807e70b 100644 --- a/src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md +++ b/src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md @@ -1,7 +1,7 @@ --- title: "GHO Funding" author: "TokenLogic" -discussions: "https://governance.aave.com/t/arfc-treasury-management-gho-funding/14887" +discussions: "https://governance.aave.com/t/arfc-treasury-management-gho-funding/14887/10" --- ## Simple Summary @@ -38,7 +38,7 @@ The GHO will be transferred to the [Aave Ethereum Treasury](https://etherscan.io - Implementation: [Ethereum](https://github.com/bgd-labs/aave-proposals/blob/main/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol) - Tests: [Ethereum](https://github.com/bgd-labs/aave-proposals/blob/main/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol) - [Snapshot](https://snapshot.org/#/aave.eth/proposal/0xb094cdc806d407d0cf4ea00e595ae95b8c145f77b77cce165c463326cc757639) -- [Discussion](https://governance.aave.com/t/arfc-treasury-management-gho-funding/14887) +- [Discussion](https://governance.aave.com/t/arfc-treasury-management-gho-funding/14887/10) # Disclosure From 553296c81418e75388ce571058eb6082d4784c67 Mon Sep 17 00:00:00 2001 From: "defijesus.eth" Date: Thu, 12 Oct 2023 18:06:43 +0100 Subject: [PATCH 6/8] fix issue raised in review --- .../AaveV3_Ethereum_GHOFunding_20230926.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol index 50a6ed25..0907903e 100644 --- a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol +++ b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol @@ -79,9 +79,9 @@ contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { AaveV3Ethereum.COLLECTOR.transfer(DAIv2.aToken, address(this), DAIv2.amount); AaveV3Ethereum.COLLECTOR.transfer(DAIv3.aToken, address(this), DAIv3.amount); uint256 daiAmount = - AaveV2Ethereum.POOL.withdraw(DAIv2.underlying, DAIv2.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); + AaveV2Ethereum.POOL.withdraw(DAIv2.underlying, type(uint256).max, AaveMisc.AAVE_SWAPPER_ETHEREUM); daiAmount += - AaveV3Ethereum.POOL.withdraw(DAIv3.underlying, DAIv3.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); + AaveV3Ethereum.POOL.withdraw(DAIv3.underlying, type(uint256).max, AaveMisc.AAVE_SWAPPER_ETHEREUM); swapAsset(DAIv2, daiAmount); ////// BUSD swap ////// @@ -95,7 +95,7 @@ contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { ////// USDT v2 swap ////// AaveV3Ethereum.COLLECTOR.transfer(USDTv2.aToken, address(this), USDTv2.amount); uint256 usdtAmount = - AaveV2Ethereum.POOL.withdraw(USDTv2.underlying, USDTv2.amount, AaveMisc.AAVE_SWAPPER_ETHEREUM); + AaveV2Ethereum.POOL.withdraw(USDTv2.underlying, type(uint256).max, AaveMisc.AAVE_SWAPPER_ETHEREUM); swapAsset(USDTv2, usdtAmount); } From 0fafb3c1f0f4cc62688f91f0c643936c068ec63e Mon Sep 17 00:00:00 2001 From: "defijesus.eth" Date: Tue, 17 Oct 2023 00:59:07 +0100 Subject: [PATCH 7/8] remove unused import & interface use dai oracle address from aave-address-book --- .../AaveV3_Ethereum_GHOFunding_20230926.sol | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol index 0907903e..e73a4f31 100644 --- a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol +++ b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.sol @@ -7,11 +7,6 @@ import {AaveV2Ethereum, AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethe import {AaveSwapper} from 'aave-helpers/swaps/AaveSwapper.sol'; import {AaveMisc} from 'aave-address-book/AaveMisc.sol'; import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; -import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol'; - -interface aTokenV1 { - function redeem(uint256 _amount) external; -} /** * @title GHO Funding @@ -38,7 +33,7 @@ contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { Asset memory DAIv2 = Asset({ underlying: AaveV2EthereumAssets.DAI_UNDERLYING, aToken: AaveV2EthereumAssets.DAI_A_TOKEN, - oracle: 0xAed0c38402a5d19df6E4c03F4E2DceD6e29c1ee9, + oracle: AaveV3EthereumAssets.DAI_ORACLE, amount: IERC20(AaveV2EthereumAssets.DAI_A_TOKEN).balanceOf(COLLECTOR) }); @@ -46,7 +41,7 @@ contract AaveV3_Ethereum_GHOFunding_20230926 is IProposalGenericExecutor { Asset memory DAIv3 = Asset({ underlying: AaveV3EthereumAssets.DAI_UNDERLYING, aToken: AaveV3EthereumAssets.DAI_A_TOKEN, - oracle: 0xAed0c38402a5d19df6E4c03F4E2DceD6e29c1ee9, + oracle: AaveV3EthereumAssets.DAI_ORACLE, amount: 370_000 * 1e18 }); From 70615a24cdad94f7ce15a91f74d7d97f80dc44b8 Mon Sep 17 00:00:00 2001 From: "defijesus.eth" Date: Tue, 17 Oct 2023 01:08:14 +0100 Subject: [PATCH 8/8] deploy payload and update tests --- .../AaveV3_Ethereum_GHOFunding_20230926.t.sol | 12 ++++++------ .../AaveV3_GHOFunding_20230926.s.sol | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol index 458765be..aa88d6cd 100644 --- a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol +++ b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_Ethereum_GHOFunding_20230926.t.sol @@ -23,8 +23,8 @@ contract AaveV3_Ethereum_GHOFunding_20230926_Test is ProtocolV3TestBase { } function setUp() public { - vm.createSelectFork(vm.rpcUrl('mainnet'), 18328137); - proposal = new AaveV3_Ethereum_GHOFunding_20230926(); + vm.createSelectFork(vm.rpcUrl('mainnet'), 18366393); + proposal = AaveV3_Ethereum_GHOFunding_20230926(0x121fE3fC3f617ACE9730203d2E27177131C4315e); } function testProposalExecution() public { @@ -37,25 +37,25 @@ contract AaveV3_Ethereum_GHOFunding_20230926_Test is ProtocolV3TestBase { // I simulated execution and copy pasted the address for simplicity // see https://etherscan.io/address/0x11C76AD590ABDFFCD980afEC9ad951B160F02797#code#L878 swaps[0] = Swap({ - proxy: 0x3Df592eae98c2b4f312ADE339C01BBE2C8444618, + proxy: 0x0eB322ac55dB67a5cA0810BA0eDae3501b1B7263, underlying: AaveV2EthereumAssets.DAI_UNDERLYING, amount: (370_000 * 1e18) + IERC20(AaveV2EthereumAssets.DAI_A_TOKEN).balanceOf(COLLECTOR) }); swaps[1] = Swap({ - proxy: 0x0eB322ac55dB67a5cA0810BA0eDae3501b1B7263, + proxy: 0x8F2ca8bE5e06180d36117A8aE3f615837790d59B, underlying: AaveV2EthereumAssets.BUSD_UNDERLYING, amount: IERC20(AaveV2EthereumAssets.BUSD_UNDERLYING).balanceOf(COLLECTOR) }); swaps[2] = Swap({ - proxy: 0x8F2ca8bE5e06180d36117A8aE3f615837790d59B, + proxy: 0xfEc76f65e943239E5A7CDC3CA6a89c26a0803FFd, underlying: AaveV2EthereumAssets.TUSD_UNDERLYING, amount: IERC20(AaveV2EthereumAssets.TUSD_UNDERLYING).balanceOf(COLLECTOR) }); swaps[3] = Swap({ - proxy: 0xfEc76f65e943239E5A7CDC3CA6a89c26a0803FFd, + proxy: 0x08dAB5c1F3AD03b1f2432Ab41eb161A6DBA1f338, underlying: AaveV2EthereumAssets.USDT_UNDERLYING, amount: 370_000 * 1e6 }); diff --git a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_GHOFunding_20230926.s.sol b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_GHOFunding_20230926.s.sol index b74f7ba9..47ee5e9e 100644 --- a/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_GHOFunding_20230926.s.sol +++ b/src/20230926_AaveV3_Eth_GHOFunding/AaveV3_GHOFunding_20230926.s.sol @@ -22,7 +22,7 @@ contract DeployEthereum is EthereumScript { contract CreateProposal is EthereumScript { function run() external broadcast { GovHelpers.Payload[] memory payloads = new GovHelpers.Payload[](1); - payloads[0] = GovHelpers.buildMainnet(address(0)); // TODO + payloads[0] = GovHelpers.buildMainnet(0x121fE3fC3f617ACE9730203d2E27177131C4315e); GovHelpers.createProposal( payloads, GovHelpers.ipfsHashFile(vm, 'src/20230926_AaveV3_Eth_GHOFunding/GHOFunding.md')