Skip to content

Commit

Permalink
Merge branch 'bgd-labs:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Marc Zeller authored Feb 1, 2024
2 parents 69d76fa + 4e25eb9 commit 7c9e6f2
Show file tree
Hide file tree
Showing 8 changed files with 527 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AaveGovernanceV2} from 'aave-address-book/AaveGovernanceV2.sol';
import {IProposalGenericExecutor} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol';

interface IExecutor {
function queueTransaction(
address target,
uint256 value,
string memory signature,
bytes memory data,
uint256 executionTime,
bool withDelegatecall
) external returns (bytes32);

function executeTransaction(
address target,
uint256 value,
string memory signature,
bytes memory data,
uint256 executionTime,
bool withDelegatecall
) external payable returns (bytes memory);

function getDelay() external view returns (uint256);
}

/**
* @title Migration of remaining gov v2 executor controlled systems Part1
* - migrating paraswap positive slippage
* - migrating arc permissions
* @author BGD Labs @bgdlabs
* - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x4fd357741900bfe62a863d1e3ec84fbf79bfebd5bdda3f66eee75b8845274b6d
* - Discussion: https://governance.aave.com/t/bgd-technical-maintenance-proposals/15274/17
*/
contract AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_20240130 is IProposalGenericExecutor {
address public immutable MAINNET_PAYLOAD;
address public immutable POLYGON_PAYLOAD;

uint256 public immutable EXECUTION_TIME;

constructor(address mainnetPayload, address polygonPayload, uint256 executionTime) {
MAINNET_PAYLOAD = mainnetPayload;
POLYGON_PAYLOAD = polygonPayload;
EXECUTION_TIME = executionTime;
}

function execute() external {
// mainnet payload
IExecutor(AaveGovernanceV2.SHORT_EXECUTOR).queueTransaction(
MAINNET_PAYLOAD,
0,
'execute()',
'',
EXECUTION_TIME,
true
);
// l2 payload
IExecutor(AaveGovernanceV2.SHORT_EXECUTOR).queueTransaction(
address(AaveGovernanceV2.CROSSCHAIN_FORWARDER_POLYGON),
0,
'execute(address)',
abi.encode(POLYGON_PAYLOAD),
EXECUTION_TIME,
true
);
}
}

/**
* @title Migration of remaining gov v2 executor controlled systems Part2
* - migrating paraswap positive slippage
* - migrating arc permissions
* @author BGD Labs @bgdlabs
* - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x4fd357741900bfe62a863d1e3ec84fbf79bfebd5bdda3f66eee75b8845274b6d
* - Discussion: https://governance.aave.com/t/bgd-technical-maintenance-proposals/15274/17
*/
contract AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_Part2_20240130 is
IProposalGenericExecutor
{
// referencing part1 as timing must be identical for the queue hash to match the executionHash
AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_20240130 immutable PART1;

constructor(AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_20240130 part1) {
PART1 = part1;
}

function execute() external {
// analog to first payload, but using executeTransaction
IExecutor(AaveGovernanceV2.SHORT_EXECUTOR).executeTransaction(
PART1.MAINNET_PAYLOAD(),
0,
'execute()',
'',
PART1.EXECUTION_TIME(),
true
);

IExecutor(AaveGovernanceV2.SHORT_EXECUTOR).executeTransaction(
address(AaveGovernanceV2.CROSSCHAIN_FORWARDER_POLYGON),
0,
'execute(address)',
abi.encode(PART1.POLYGON_PAYLOAD()),
PART1.EXECUTION_TIME(),
true
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AaveV2Ethereum, AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethereum.sol';
import {AaveV3Polygon, AaveV3PolygonAssets} from 'aave-address-book/AaveV3Polygon.sol';
import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol';

import 'forge-std/Test.sol';
import {GovHelpers} from 'aave-helpers/GovHelpers.sol';
import {AaveGovernanceV2} from 'aave-address-book/AaveGovernanceV2.sol';
import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol';
import {ProtocolV2TestBase, ReserveConfig} from 'aave-helpers/ProtocolV2TestBase.sol';
import {AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_20240130, IExecutor, AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_Part2_20240130} from './AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_20240130.sol';
import {PayloadsToDeploy} from './MigrationOfRemainingGovV2Permissions_20240130.s.sol';
import {MainnetPayload, IAaveArcTimelock} from './MainnetPayload.sol';
import {PolygonPayload} from './PolygonPayload.sol';

/**
* @dev Test for AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_20240130
* command: make test-contract filter=AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_20240130
*/
contract AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_20240130_Test is ProtocolV2TestBase {
AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_20240130 internal proposal;
AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_Part2_20240130 internal proposalPart2;

function setUp() public {
vm.createSelectFork(vm.rpcUrl('mainnet'), 19119958);
proposal = AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_20240130(
PayloadsToDeploy.part1(address(new MainnetPayload()), address(0))
);
proposalPart2 = AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_Part2_20240130(
PayloadsToDeploy.part2(address(proposal))
);
}

/**
* @dev executes the generic test suite including e2e and config snapshots
*/
function test_defaultProposalExecution() public {
uint256 wETHBalance = IERC20(AaveV2EthereumAssets.WETH_UNDERLYING).balanceOf(
address(AaveV2Ethereum.COLLECTOR)
);
assert(proposal.EXECUTION_TIME() == block.timestamp + 7 days);
vm.warp(proposal.EXECUTION_TIME() - 2 days);
executePayload(vm, address(proposal));
vm.warp(proposal.EXECUTION_TIME());
executePayload(vm, address(proposalPart2));
uint256 wETHBalanceAfter = IERC20(AaveV2EthereumAssets.WETH_UNDERLYING).balanceOf(
address(AaveV2Ethereum.COLLECTOR)
);
assertGt(wETHBalanceAfter, wETHBalance);

_testArc();
}

function _testArc() internal {
// execute payload on arc timelock
uint256 currentActionId = IAaveArcTimelock(AaveGovernanceV2.ARC_TIMELOCK).getActionsSetCount();

skip(3 days + 10);
IAaveArcTimelock(AaveGovernanceV2.ARC_TIMELOCK).execute(currentActionId - 1);

assertEq(
IAaveArcTimelock(AaveGovernanceV2.ARC_TIMELOCK).getEthereumGovernanceExecutor(),
GovernanceV3Ethereum.EXECUTOR_LVL_1
);

rewind(3 days + 10);
}
}

/**
* @dev Test for AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_20240130
* command: make test-contract filter=AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_20240130_Polygon
*/
contract AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_20240130_Polygon_Test is
ProtocolV2TestBase
{
PolygonPayload proposal;

function setUp() public {
vm.createSelectFork(vm.rpcUrl('polygon'), 52961125);
proposal = new PolygonPayload();
}

/**
* @dev executes the generic test suite including e2e and config snapshots
*/
function test_defaultProposalExecution() public {
uint256 wMATICBalance = IERC20(AaveV3PolygonAssets.WMATIC_UNDERLYING).balanceOf(
address(AaveV3Polygon.COLLECTOR)
);
GovHelpers.executePayload(vm, address(proposal), AaveGovernanceV2.POLYGON_BRIDGE_EXECUTOR);
uint256 wMATICBalanceAfter = IERC20(AaveV3PolygonAssets.WMATIC_UNDERLYING).balanceOf(
address(AaveV3Polygon.COLLECTOR)
);
assertGt(wMATICBalanceAfter, wMATICBalance);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AaveV2Ethereum} from 'aave-address-book/AaveV2Ethereum.sol';
import {AaveGovernanceV2} from 'aave-address-book/AaveGovernanceV2.sol';
import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol';
import {IProposalGenericExecutor} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol';
import {ParaswapClaim, ParaswapClaimer} from './ParaswapClaim.sol';

interface IAaveArcTimelock {
function queue(
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas,
bool[] memory withDelegatecalls
) external;

function getActionsSetCount() external view returns (uint256);

function execute(uint256 actionsSetId) external;

function getEthereumGovernanceExecutor() external view returns (address);
}

/**
* @title MainnetPayload
* @author BGD Labs @bgdlabs
* @notice Aave governance payload to claim rewards accrued as positive slippage on paraswap to the ethereum collector.
* @notice Also migrates aave arc permissions from old governance v2 short executor, to the governance v3 executor.
*/
contract MainnetPayload is IProposalGenericExecutor, ParaswapClaim {
function execute() external override {
// paraswap
address[] memory tokens = AaveV2Ethereum.POOL.getReservesList();
claim(
ParaswapClaimer.ETHEREUM,
AaveGovernanceV2.SHORT_EXECUTOR,
address(AaveV2Ethereum.COLLECTOR),
tokens
);

// arc
address[] memory targets = new address[](1);
targets[0] = AaveGovernanceV2.ARC_TIMELOCK;
uint256[] memory values = new uint256[](1);
values[0] = 0;
string[] memory signatures = new string[](1);
signatures[0] = 'updateEthereumGovernanceExecutor(address)';
bytes[] memory calldatas = new bytes[](1);
calldatas[0] = abi.encode(GovernanceV3Ethereum.EXECUTOR_LVL_1);
bool[] memory withDelegatecalls = new bool[](1);
withDelegatecalls[0] = true;

// create payload for arc timelock
IAaveArcTimelock(AaveGovernanceV2.ARC_TIMELOCK).queue(
targets,
values,
signatures,
calldatas,
withDelegatecalls
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
title: "Migration of remaining Gov v2 permissions & DAO's Paraswap positive slippage"
author: "BGD Labs @bgdlabs"
discussions: "https://governance.aave.com/t/bgd-technical-maintenance-proposals/15274/17"
snapshot: "https://snapshot.org/#/aave.eth/proposal/0x4fd357741900bfe62a863d1e3ec84fbf79bfebd5bdda3f66eee75b8845274b6d"
---

## Simple Summary

Migrate Aave Arc pool permissions & Paraswap positive slippage funds allocated to the old governance v2 Short Executor.

## Motivation

In November 2022 a permissionless contract was [introduced](https://governance.aave.com/t/bgd-aave-paraswap-fee-claimer/10671) to collect positive slippage from Paraswap swaps to the Aave Collector, gained on features like collateral swap, debt swap or repay with collateral. While this system is well and active since [then](https://dashboard.paraswap.io/public/dashboard/5b6dae52-b39e-4c49-a670-e0f0c0aebee5?partner=aave) there are some funds (~100k) pending to claim from the previous system which still need [migration](https://governance.aave.com/t/bgd-aave-paraswap-fee-claimer/10671/3).

Additionally, when Governance v3 was introduced, some permissions for the deprecated Aave Arc pool were not migrated to the new governance system. For proper hygiene and permissions alignment, this should still be done.

Approving this proposal will also authorize the guardians on `optimism`, `arbitrum`, `avalanche` and `fantom` to claim the pending paraswap positive slippage to the respective network collector.

## Specification

On Ethereum & Polygon the proposal calls:

- `pspclaimer.batchWithdrawAllERC20(assets, collector)` to claim pending rewards to the collector

On Ethereum the proposal also queues a call to:

- `arcTimelock.updateEthereumGovernanceExecutor(GovernanceV3Ethereum.EXECUTOR_LVL_1)`

## References

- Implementation: [AaveV2Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/6a5856de61049e47f43a3cb4f05f74400b493427/src/20240130_AaveV2Ethereum_MigrationOfRemainingGovV2Permissions/AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_20240130.sol)
- Tests: [AaveV2Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/6a5856de61049e47f43a3cb4f05f74400b493427/src/20240130_AaveV2Ethereum_MigrationOfRemainingGovV2Permissions/AaveV2Ethereum_MigrationOfRemainingGovV2Permissions_20240130.t.sol)
- [Snapshot](https://snapshot.org/#/aave.eth/proposal/0x4fd357741900bfe62a863d1e3ec84fbf79bfebd5bdda3f66eee75b8845274b6d)
- [Discussion](https://governance.aave.com/t/bgd-technical-maintenance-proposals/15274/17)

## Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
Loading

0 comments on commit 7c9e6f2

Please sign in to comment.