Skip to content
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

Treasury Management - Aave Funding Update #43

Merged
merged 14 commits into from
Jan 11, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
title: "Aave Funding Updates"
efecarranza marked this conversation as resolved.
Show resolved Hide resolved
efecarranza marked this conversation as resolved.
Show resolved Hide resolved
author: "TokenLogic, efecarranza.eth"
discussions: "https://governance.aave.com/t/arfc-aave-funding-update/15194"
---

## Simple Summary

This AIP aims to consolidate Aave DAO's stablecoin holdings. It is divided into different parts that are detailed below. Part one is depositing DAI into aEthDAI, part two is migrating aDAI and aUSDT into aEthDAI and aEthUSDT, part three bridges assets from Polygon to Mainnet and part four swaps some holdings into GHO.
sendra marked this conversation as resolved.
Show resolved Hide resolved

## Motivation

This proposal intends to ensure the DAO is well capitalised. A separate DAO budget publication will be shared during Q4 2023.

The DAO has sufficient USDC, DAI and USDT deposited across the various instances of Aave Protocol to support existing streams and the AURA purchase 3.
efecarranza marked this conversation as resolved.
Show resolved Hide resolved

However, with the emergence of new service provider proposal expected, the DAO needs to adjust its stable coin holdings. This publication supports transferring additional funds from Polygon to Mainnet and acquiring GHO on the market to ensure the DAO is well capitalised for the next 6 months. It also aims to move assets from the old V2 to the newer V3 aToken.

## Specification

- Deposit 1M units of USDC from Treasury into Aave v3 (received from Polygon bridge)
- Deposit 350k units of USDT from Treasury into Aave v3 (received from Polygon bridge)
- Deposit 4000k units of USDT from Treasury into Aave v2 (received from Polygon bridge)
efecarranza marked this conversation as resolved.
Show resolved Hide resolved
- Deposit 500k units of DAI from Treasury into Aave v3 (received from Polygon bridge)

Swap the following asset holdings to GHO:

- 700k units of USDC held in Treasury (received from Polygon bridge)

efecarranza marked this conversation as resolved.
Show resolved Hide resolved
## References

- Implementation: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20231106_AaveV3Ethereum_AaveFundingUpdates/AaveV3Ethereum_AaveFundingUpdates_20231106.sol)
- Tests: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20231106_AaveV3Ethereum_AaveFundingUpdates/AaveV3Ethereum_AaveFundingUpdates_20231106.t.sol)
- [Snapshot](https://snapshot.org/#/aave.eth/proposal/0x099f88e1728760952be26fcb8fc99b26c29336e6a109820b391751b108399ee5)
- [Discussion](https://governance.aave.com/t/arfc-aave-funding-update/15194)

## Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// 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_AaveFundingUpdates_20231106} from './AaveV3Ethereum_AaveFundingUpdates_20231106.sol';

/**
* @dev Deploy Ethereum
* command: make deploy-ledger contract=src/20231106_AaveV3Ethereum_AaveFundingUpdates/AaveFundingUpdates_20231106.s.sol:DeployEthereum chain=mainnet
*/
contract DeployEthereum is EthereumScript {
function run() external broadcast {
// deploy payloads
AaveV3Ethereum_AaveFundingUpdates_20231106 payload0 = new AaveV3Ethereum_AaveFundingUpdates_20231106();

// compose action
IPayloadsControllerCore.ExecutionAction[]
memory actions = new IPayloadsControllerCore.ExecutionAction[](1);
actions[0] = GovV3Helpers.buildAction(address(payload0));

// register action at payloadsController
GovV3Helpers.createPayload(actions);
}
}

/**
* @dev Create Proposal
* command: make deploy-ledger contract=src/20231106_AaveV3Ethereum_AaveFundingUpdates/AaveFundingUpdates_20231106.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
sendra marked this conversation as resolved.
Show resolved Hide resolved
IPayloadsControllerCore.ExecutionAction[]
memory actionsEthereum = new IPayloadsControllerCore.ExecutionAction[](1);
actionsEthereum[0] = GovV3Helpers.buildAction(address(0));
payloads[0] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum);

// create proposal
vm.startBroadcast();
GovV3Helpers.createProposal2_5(
payloads,
GovV3Helpers.ipfsHashFile(
vm,
'src/20231106_AaveV3Ethereum_AaveFundingUpdates/AaveFundingUpdates.md'
)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol';
import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol';
import {AaveV2Ethereum, AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethereum.sol';
import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol';
import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol';
import {AaveSwapper} from 'aave-helpers/swaps/AaveSwapper.sol';
import {IProposalGenericExecutor} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol';

/**
* @title Aave Funding Updates
* @author efecarranza.eth
* - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x099f88e1728760952be26fcb8fc99b26c29336e6a109820b391751b108399ee5
* - Discussion: https://governance.aave.com/t/arfc-aave-funding-update/15194
*/
contract AaveV3Ethereum_AaveFundingUpdates_20231106 is IProposalGenericExecutor {
using SafeERC20 for IERC20;

AaveSwapper public constant SWAPPER = AaveSwapper(MiscEthereum.AAVE_SWAPPER);

uint256 public constant USDC_TO_SWAP = 700_000e6;
uint256 public constant USDC_TO_DEPOSIT = 1_000_000e6;
uint256 public constant USDT_TO_DEPOSIT_V3 = 350_000e6;
uint256 public constant USDT_TO_DEPOSIT_V2 = 400_000e6;
uint256 public constant DAI_TO_DEPOSIT = 500_000e18;

address public constant MILKMAN = 0x11C76AD590ABDFFCD980afEC9ad951B160F02797;
address public constant PRICE_CHECKER = 0xe80a1C615F75AFF7Ed8F08c9F21f9d00982D666c;

function execute() external {
// Deposit into V3

AaveV3Ethereum.COLLECTOR.transfer(
AaveV3EthereumAssets.USDC_UNDERLYING,
address(this),
USDC_TO_DEPOSIT
);
IERC20(AaveV3EthereumAssets.USDC_UNDERLYING).forceApprove(
address(AaveV3Ethereum.POOL),
USDC_TO_DEPOSIT
);
AaveV3Ethereum.POOL.deposit(
AaveV3EthereumAssets.USDC_UNDERLYING,
USDC_TO_DEPOSIT,
address(AaveV3Ethereum.COLLECTOR),
0
);

AaveV3Ethereum.COLLECTOR.transfer(
AaveV3EthereumAssets.USDT_UNDERLYING,
address(this),
USDT_TO_DEPOSIT_V2 + USDT_TO_DEPOSIT_V3
);
IERC20(AaveV3EthereumAssets.USDT_UNDERLYING).forceApprove(
address(AaveV3Ethereum.POOL),
USDT_TO_DEPOSIT_V3
);
AaveV3Ethereum.POOL.deposit(
sendra marked this conversation as resolved.
Show resolved Hide resolved
AaveV3EthereumAssets.USDT_UNDERLYING,
USDT_TO_DEPOSIT_V3,
address(AaveV3Ethereum.COLLECTOR),
0
);

AaveV3Ethereum.COLLECTOR.transfer(
AaveV3EthereumAssets.DAI_UNDERLYING,
address(this),
DAI_TO_DEPOSIT
);
IERC20(AaveV3EthereumAssets.DAI_UNDERLYING).forceApprove(
address(AaveV3Ethereum.POOL),
DAI_TO_DEPOSIT
);
AaveV3Ethereum.POOL.deposit(
AaveV3EthereumAssets.DAI_UNDERLYING,
DAI_TO_DEPOSIT,
address(AaveV3Ethereum.COLLECTOR),
0
);

// Swap USDC

SWAPPER.swap(
MILKMAN,
PRICE_CHECKER,
AaveV3EthereumAssets.USDC_UNDERLYING,
AaveV3EthereumAssets.GHO_UNDERLYING,
AaveV3EthereumAssets.USDC_ORACLE,
AaveV3EthereumAssets.GHO_ORACLE,
address(AaveV3Ethereum.COLLECTOR),
USDC_TO_SWAP,
100
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {GovHelpers} from 'aave-helpers/GovHelpers.sol';
import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol';
import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol';
import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol';
import {AaveV2Ethereum, AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethereum.sol';
import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol';
import {ProtocolV3TestBase} from 'aave-helpers/ProtocolV3TestBase.sol';
import {AaveV3Ethereum_AaveFundingUpdates_20231106} from './AaveV3Ethereum_AaveFundingUpdates_20231106.sol';

/**
* @dev Test for AaveV3Ethereum_AaveFundingUpdates_20231106
* command: make test-contract filter=AaveV3Ethereum_AaveFundingUpdates_20231106
*/
contract AaveV3Ethereum_AaveFundingUpdates_20231106_Test is ProtocolV3TestBase {
event SwapRequested(
address milkman,
address indexed fromToken,
address indexed toToken,
address fromOracle,
address toOracle,
uint256 amount,
address indexed recipient,
uint256 slippage
);

AaveV3Ethereum_AaveFundingUpdates_20231106 internal proposal;

function setUp() public {
vm.createSelectFork(vm.rpcUrl('mainnet'), 18516167); // TODO: Update block number post bridge
proposal = new AaveV3Ethereum_AaveFundingUpdates_20231106();
}

function test_execute() public {
uint256 balanceUsdcBefore = IERC20(AaveV3EthereumAssets.USDC_UNDERLYING).balanceOf(
address(AaveV3Ethereum.COLLECTOR)
);

uint256 balanceUsdtBefore = IERC20(AaveV3EthereumAssets.USDT_UNDERLYING).balanceOf(
address(AaveV3Ethereum.COLLECTOR)
);

uint256 balanceDaiBefore = IERC20(AaveV3EthereumAssets.DAI_UNDERLYING).balanceOf(
address(AaveV3Ethereum.COLLECTOR)
);

uint256 balanceAUsdcBefore = IERC20(AaveV3EthereumAssets.USDC_A_TOKEN).balanceOf(
address(AaveV3Ethereum.COLLECTOR)
);

uint256 balanceAUsdtBeforeV2 = IERC20(AaveV3EthereumAssets.USDT_A_TOKEN).balanceOf(
address(AaveV3Ethereum.COLLECTOR)
);

uint256 balanceAUsdtBefore = IERC20(AaveV3EthereumAssets.USDT_A_TOKEN).balanceOf(
address(AaveV3Ethereum.COLLECTOR)
);

uint256 balanceADaiBefore = IERC20(AaveV3EthereumAssets.DAI_A_TOKEN).balanceOf(
address(AaveV3Ethereum.COLLECTOR)
);

assertGt(balanceUsdcBefore, proposal.USDC_TO_DEPOSIT());

assertGt(balanceUsdtBefore, proposal.USDT_TO_DEPOSIT_V3());

assertGt(balanceDaiBefore, proposal.DAI_TO_DEPOSIT());

vm.expectEmit(true, true, true, true, MiscEthereum.AAVE_SWAPPER);
emit SwapRequested(
proposal.MILKMAN(),
AaveV3EthereumAssets.USDC_UNDERLYING,
AaveV3EthereumAssets.GHO_UNDERLYING,
AaveV3EthereumAssets.USDC_ORACLE,
AaveV3EthereumAssets.GHO_ORACLE,
proposal.USDC_TO_SWAP(),
address(AaveV3Ethereum.COLLECTOR),
100
);

GovHelpers.executePayload(vm, address(proposal), GovernanceV3Ethereum.EXECUTOR_LVL_1);

assertEq(
IERC20(AaveV3EthereumAssets.USDC_UNDERLYING).balanceOf(address(proposal.SWAPPER())),
0
);

assertEq(
IERC20(AaveV3EthereumAssets.USDC_UNDERLYING).balanceOf(address(AaveV3Ethereum.COLLECTOR)),
balanceUsdcBefore - proposal.USDC_TO_DEPOSIT() - proposal.USDC_TO_SWAP()
);

assertEq(
IERC20(AaveV3EthereumAssets.USDT_UNDERLYING).balanceOf(address(AaveV3Ethereum.COLLECTOR)),
balanceUsdtBefore - proposal.USDT_TO_DEPOSIT_V3() - proposal.USDT_TO_DEPOSIT_V2()
);

assertEq(
IERC20(AaveV3EthereumAssets.DAI_UNDERLYING).balanceOf(address(AaveV3Ethereum.COLLECTOR)),
balanceDaiBefore - proposal.DAI_TO_DEPOSIT()
);

assertGt(
IERC20(AaveV3EthereumAssets.USDC_A_TOKEN).balanceOf(address(AaveV3Ethereum.COLLECTOR)),
balanceAUsdcBefore
);

assertGt(
IERC20(AaveV2EthereumAssets.USDT_A_TOKEN).balanceOf(address(AaveV3Ethereum.COLLECTOR)),
balanceAUsdtBeforeV2
);

assertGt(
IERC20(AaveV3EthereumAssets.USDT_A_TOKEN).balanceOf(address(AaveV3Ethereum.COLLECTOR)),
balanceAUsdtBefore
);

assertGt(
IERC20(AaveV3EthereumAssets.DAI_A_TOKEN).balanceOf(address(AaveV3Ethereum.COLLECTOR)),
balanceADaiBefore
);
}
}
19 changes: 19 additions & 0 deletions src/20231106_AaveV3Ethereum_AaveFundingUpdates/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"rootOptions": {
"pools": ["AaveV3Ethereum"],
"title": "Aave Funding Updates",
"shortName": "AaveFundingUpdates",
"date": "20231106",
"author": "TokenLogic",
"discussion": "https://governance.aave.com/t/arfc-aave-funding-update/15194",
"snapshot": "https://snapshot.org/#/aave.eth/proposal/0x099f88e1728760952be26fcb8fc99b26c29336e6a109820b391751b108399ee5"
},
"poolOptions": {
"AaveV3Ethereum": {
"configs": {
"OTHERS": {}
},
"features": ["OTHERS"]
}
}
}