From d203d4cbe65aa57c00ad9f75b77c6ac26ba49d34 Mon Sep 17 00:00:00 2001 From: Luigy-Lemon Date: Thu, 5 Dec 2024 10:35:33 +0000 Subject: [PATCH 1/5] feat: Collector revision-6 Upgrade. (#82) ### Context The Collector contract (Revision 5) has the limitation of only allowing one address to call its functions, the `_fundsAdmin`, which currently is the Governance Executor contract. To enable the possibility of the [FinanceSteward](https://governance.aave.com/t/arfc-aave-finance-steward/17570) contract to be allowed to call the Collector alongside the Executor, it is recommended to use the `ACL_MANAGER` to manage its access control. A new role is going to be created named `FUNDS_ADMIN` ### Changelog Collector * Initialize function changes to only populate the `nextStreamId` * Created constructor to setup the `ACL_MANAGER` contract address as immutable variable * deprecated `_fundsAdmin` variable * removed getter and setter functions for `_fundsAdmin` and relevant errors and events. * introduced new function to check if an address has the `FUNDS_ADMIN` role named `IsFundsAdmin` * New tests for the Collector --- src/contracts/treasury/Collector.sol | 85 ++-- src/contracts/treasury/ICollector.sol | 86 +++- .../procedures/AaveV3TreasuryProcedure.sol | 21 +- .../batches/AaveV3PeripheryBatch.sol | 3 + tests/deployments/AaveV3PermissionsTest.t.sol | 1 + tests/treasury/Collector.t.sol | 441 ++++++++++++++++++ 6 files changed, 564 insertions(+), 73 deletions(-) create mode 100644 tests/treasury/Collector.t.sol diff --git a/src/contracts/treasury/Collector.sol b/src/contracts/treasury/Collector.sol index daf6b7a3..5caebf45 100644 --- a/src/contracts/treasury/Collector.sol +++ b/src/contracts/treasury/Collector.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.0; import {ICollector} from './ICollector.sol'; +import {IAccessControl} from '../dependencies/openzeppelin/contracts/IAccessControl.sol'; import {ReentrancyGuard} from '../dependencies/openzeppelin/ReentrancyGuard.sol'; import {VersionedInitializable} from '../misc/aave-upgradeability/VersionedInitializable.sol'; import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; @@ -28,14 +29,23 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard { /*** Storage Properties ***/ /** - * @notice Address of the current funds admin. + * @notice Current revision of the contract. */ - address internal _fundsAdmin; + uint256 public constant REVISION = 6; + + /// @inheritdoc ICollector + address public constant ETH_MOCK_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; + + /// @inheritdoc ICollector + bytes32 public constant FUNDS_ADMIN_ROLE = 'FUNDS_ADMIN'; + + /// @inheritdoc ICollector + address public immutable ACL_MANAGER; /** - * @notice Current revision of the contract. + * @notice [DEPRECATED] Use `isFundsAdmin()` to check address. */ - uint256 public constant REVISION = 5; + address internal _fundsAdmin_deprecated; /** * @notice Counter for new stream ids. @@ -47,16 +57,15 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard { */ mapping(uint256 => Stream) private _streams; - /// @inheritdoc ICollector - address public constant ETH_MOCK_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; - /*** Modifiers ***/ /** - * @dev Throws if the caller is not the funds admin. + * @dev Throws if the caller does not have the FUNDS_ADMIN role */ modifier onlyFundsAdmin() { - require(msg.sender == _fundsAdmin, 'ONLY_BY_FUNDS_ADMIN'); + if (_onlyFundsAdmin() == false) { + revert OnlyFundsAdmin(); + } _; } @@ -65,10 +74,9 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard { * @param streamId The id of the stream to query. */ modifier onlyAdminOrRecipient(uint256 streamId) { - require( - msg.sender == _fundsAdmin || msg.sender == _streams[streamId].recipient, - 'caller is not the funds admin or the recipient of the stream' - ); + if (_onlyFundsAdmin() == false && msg.sender != _streams[streamId].recipient) { + revert OnlyFundsAdminOrRceipient(); + } _; } @@ -76,19 +84,22 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard { * @dev Throws if the provided id does not point to a valid stream. */ modifier streamExists(uint256 streamId) { - require(_streams[streamId].isEntity, 'stream does not exist'); + if (!_streams[streamId].isEntity) revert StreamDoesNotExist(); _; } + constructor(address aclManager) { + if (aclManager == address(0)) revert InvalidZeroAddress(); + ACL_MANAGER = aclManager; + } + /*** Contract Logic Starts Here */ /// @inheritdoc ICollector - function initialize(address fundsAdmin, uint256 nextStreamId) external initializer { + function initialize(uint256 nextStreamId) external virtual initializer { if (nextStreamId != 0) { _nextStreamId = nextStreamId; } - - _setFundsAdmin(fundsAdmin); } /*** View Functions ***/ @@ -99,8 +110,8 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard { } /// @inheritdoc ICollector - function getFundsAdmin() external view returns (address) { - return _fundsAdmin; + function isFundsAdmin(address admin) external view returns (bool) { + return IAccessControl(ACL_MANAGER).hasRole(FUNDS_ADMIN_ROLE, admin); } /// @inheritdoc ICollector @@ -195,7 +206,7 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard { /// @inheritdoc ICollector function transfer(IERC20 token, address recipient, uint256 amount) external onlyFundsAdmin { - require(recipient != address(0), 'INVALID_0X_RECIPIENT'); + if (recipient == address(0)) revert InvalidZeroAddress(); if (address(token) == ETH_MOCK_ADDRESS) { payable(recipient).sendValue(amount); @@ -204,18 +215,8 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard { } } - /// @inheritdoc ICollector - function setFundsAdmin(address admin) external onlyFundsAdmin { - _setFundsAdmin(admin); - } - - /** - * @dev Transfer the ownership of the funds administrator role. - * @param admin The address of the new funds administrator - */ - function _setFundsAdmin(address admin) internal { - _fundsAdmin = admin; - emit NewFundsAdmin(admin); + function _onlyFundsAdmin() internal view returns (bool) { + return IAccessControl(ACL_MANAGER).hasRole(FUNDS_ADMIN_ROLE, msg.sender); } struct CreateStreamLocalVars { @@ -244,21 +245,21 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard { uint256 startTime, uint256 stopTime ) external onlyFundsAdmin returns (uint256) { - require(recipient != address(0), 'stream to the zero address'); - require(recipient != address(this), 'stream to the contract itself'); - require(recipient != msg.sender, 'stream to the caller'); - require(deposit > 0, 'deposit is zero'); - require(startTime >= block.timestamp, 'start time before block.timestamp'); - require(stopTime > startTime, 'stop time before the start time'); + if (recipient == address(0)) revert InvalidZeroAddress(); + if (recipient == address(this)) revert InvalidRecipient(); + if (recipient == msg.sender) revert InvalidRecipient(); + if (deposit == 0) revert InvalidZeroAmount(); + if (startTime < block.timestamp) revert InvalidStartTime(); + if (stopTime <= startTime) revert InvalidStopTime(); CreateStreamLocalVars memory vars; vars.duration = stopTime - startTime; /* Without this, the rate per second would be zero. */ - require(deposit >= vars.duration, 'deposit smaller than time delta'); + if (deposit < vars.duration) revert DepositSmallerTimeDelta(); /* This condition avoids dealing with remainders */ - require(deposit % vars.duration == 0, 'deposit not multiple of time delta'); + if (deposit % vars.duration > 0) revert DepositNotMultipleTimeDelta(); vars.ratePerSecond = deposit / vars.duration; @@ -302,11 +303,11 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard { uint256 streamId, uint256 amount ) external nonReentrant streamExists(streamId) onlyAdminOrRecipient(streamId) returns (bool) { - require(amount > 0, 'amount is zero'); + if (amount == 0) revert InvalidZeroAmount(); Stream memory stream = _streams[streamId]; uint256 balance = balanceOf(streamId, stream.recipient); - require(balance >= amount, 'amount exceeds the available balance'); + if (balance < amount) revert BalanceExceeded(); _streams[streamId].remainingBalance = stream.remainingBalance - amount; diff --git a/src/contracts/treasury/ICollector.sol b/src/contracts/treasury/ICollector.sol index 94103d48..79035e54 100644 --- a/src/contracts/treasury/ICollector.sol +++ b/src/contracts/treasury/ICollector.sol @@ -16,10 +16,60 @@ interface ICollector { bool isEntity; } - /** @notice Emitted when the funds admin changes - * @param fundsAdmin The new funds admin. - **/ - event NewFundsAdmin(address indexed fundsAdmin); + /** + * @dev Withdraw amount exceeds available balance + */ + error BalanceExceeded(); + + /** + * @dev Deposit smaller than time delta + */ + error DepositSmallerTimeDelta(); + + /** + * @dev Deposit not multiple of time delta + */ + error DepositNotMultipleTimeDelta(); + + /** + * @dev Recipient cannot be the contract itself or msg.sender + */ + error InvalidRecipient(); + + /** + * @dev Start time cannot be before block.timestamp + */ + error InvalidStartTime(); + + /** + * @dev Stop time must be greater than startTime + */ + error InvalidStopTime(); + + /** + * @dev Provided address cannot be the zero-address + */ + error InvalidZeroAddress(); + + /** + * @dev Amount cannot be zero + */ + error InvalidZeroAmount(); + + /** + * @dev Only caller with FUNDS_ADMIN role can call + */ + error OnlyFundsAdmin(); + + /** + * @dev Only caller with FUNDS_ADMIN role or stream recipient can call + */ + error OnlyFundsAdminOrRceipient(); + + /** + * @dev The provided ID does not belong to an existing stream + */ + error StreamDoesNotExist(); /** @notice Emitted when the new stream is created * @param streamId The identifier of the stream. @@ -64,29 +114,38 @@ interface ICollector { uint256 recipientBalance ); + /** + * @notice FUNDS_ADMIN role granted by ACL Manager + **/ + function FUNDS_ADMIN_ROLE() external view returns (bytes32); + + /** + * @notice Address of the current ACL Manager. + **/ + function ACL_MANAGER() external view returns (address); + /** @notice Returns the mock ETH reference address * @return address The address **/ function ETH_MOCK_ADDRESS() external pure returns (address); /** @notice Initializes the contracts - * @param fundsAdmin Funds admin address * @param nextStreamId StreamId to set, applied if greater than 0 **/ - function initialize(address fundsAdmin, uint256 nextStreamId) external; + function initialize(uint256 nextStreamId) external; /** - * @notice Return the funds admin, only entity to be able to interact with this contract (controller of reserve) - * @return address The address of the funds admin + * @notice Checks if address is funds admin + * @return bool If the address has the funds admin role **/ - function getFundsAdmin() external view returns (address); + function isFundsAdmin(address admin) external view returns (bool); /** * @notice Returns the available funds for the given stream id and address. * @param streamId The id of the stream for which to query the balance. * @param who The address for which to query the balance. * @notice Returns the total funds allocated to `who` as uint256. - */ + **/ function balanceOf(uint256 streamId, address who) external view returns (uint256 balance); /** @@ -105,13 +164,6 @@ interface ICollector { **/ function transfer(IERC20 token, address recipient, uint256 amount) external; - /** - * @dev Transfer the ownership of the funds administrator role. - This function should only be callable by the current funds administrator. - * @param admin The address of the new funds administrator - */ - function setFundsAdmin(address admin) external; - /** * @notice Creates a new stream funded by this contracts itself and paid towards `recipient`. * @param recipient The address towards which the money is streamed. diff --git a/src/deployments/contracts/procedures/AaveV3TreasuryProcedure.sol b/src/deployments/contracts/procedures/AaveV3TreasuryProcedure.sol index 76f6650b..c18b3cda 100644 --- a/src/deployments/contracts/procedures/AaveV3TreasuryProcedure.sol +++ b/src/deployments/contracts/procedures/AaveV3TreasuryProcedure.sol @@ -15,6 +15,7 @@ contract AaveV3TreasuryProcedure { function _deployAaveV3Treasury( address poolAdmin, address deployedProxyAdmin, + address aclManager, bytes32 collectorSalt ) internal returns (TreasuryReport memory) { TreasuryReport memory treasuryReport; @@ -22,35 +23,27 @@ contract AaveV3TreasuryProcedure { address treasuryOwner = poolAdmin; if (salt != '') { - Collector treasuryImplementation = new Collector{salt: salt}(); - treasuryImplementation.initialize(address(0), 0); + Collector treasuryImplementation = new Collector{salt: salt}(aclManager); + treasuryImplementation.initialize(0); treasuryReport.treasuryImplementation = address(treasuryImplementation); treasuryReport.treasury = address( new TransparentUpgradeableProxy{salt: salt}( treasuryReport.treasuryImplementation, ProxyAdmin(deployedProxyAdmin), - abi.encodeWithSelector( - treasuryImplementation.initialize.selector, - address(treasuryOwner), - 0 - ) + abi.encodeWithSelector(treasuryImplementation.initialize.selector, 100_000) ) ); } else { - Collector treasuryImplementation = new Collector(); - treasuryImplementation.initialize(address(0), 0); + Collector treasuryImplementation = new Collector(aclManager); + treasuryImplementation.initialize(0); treasuryReport.treasuryImplementation = address(treasuryImplementation); treasuryReport.treasury = address( new TransparentUpgradeableProxy( treasuryReport.treasuryImplementation, ProxyAdmin(deployedProxyAdmin), - abi.encodeWithSelector( - treasuryImplementation.initialize.selector, - address(treasuryOwner), - 100_000 - ) + abi.encodeWithSelector(treasuryImplementation.initialize.selector, 100_000) ) ); } diff --git a/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol b/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol index ce332dfe..5e418319 100644 --- a/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol +++ b/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol @@ -31,10 +31,13 @@ contract AaveV3PeripheryBatch is _report.aaveOracle = _deployAaveOracle(config.oracleDecimals, poolAddressesProvider); + address aclManager = address(1); // temp-to-run-tests + if (config.treasury == address(0)) { TreasuryReport memory treasuryReport = _deployAaveV3Treasury( poolAdmin, _report.proxyAdmin, + aclManager, config.salt ); diff --git a/tests/deployments/AaveV3PermissionsTest.t.sol b/tests/deployments/AaveV3PermissionsTest.t.sol index 170c8022..903cdb9a 100644 --- a/tests/deployments/AaveV3PermissionsTest.t.sol +++ b/tests/deployments/AaveV3PermissionsTest.t.sol @@ -305,6 +305,7 @@ contract AaveV3PermissionsTest is BatchTestProcedures { report.proxyAdmin, 'Treasury proxy admin does not match with report.proxyAdmin' ); + assertEq(ICollector(report.treasury).ACL_MANAGER(), report.aclManager); } { address proxyAdminOwner = Ownable(report.proxyAdmin).owner(); diff --git a/tests/treasury/Collector.t.sol b/tests/treasury/Collector.t.sol new file mode 100644 index 00000000..f0bff08a --- /dev/null +++ b/tests/treasury/Collector.t.sol @@ -0,0 +1,441 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.0; + +import {Test} from 'forge-std/Test.sol'; +import {StdUtils} from 'forge-std/StdUtils.sol'; + +import {IERC20} from 'src/contracts/dependencies/openzeppelin/contracts/IERC20.sol'; +import {IAccessControl} from 'src/contracts/dependencies/openzeppelin/contracts/IAccessControl.sol'; +import {ACLManager} from 'src/contracts/protocol/configuration/ACLManager.sol'; +import {PoolAddressesProvider} from 'src/contracts/protocol/configuration/PoolAddressesProvider.sol'; +import {Collector} from 'src/contracts/treasury/Collector.sol'; +import {ICollector} from 'src/contracts/treasury/ICollector.sol'; + +contract CollectorTest is StdUtils, Test { + Collector public collector; + + address public EXECUTOR_LVL_1; + address public ACL_ADMIN; + address public RECIPIENT_STREAM_1; + address public FUNDS_ADMIN; + address public OWNER; + + IERC20 tokenA; + IERC20 tokenB; + + uint256 public streamStartTime; + uint256 public streamStopTime; + uint256 public nextStreamID; + + event StreamIdChanged(uint256 indexed streamId); + event CreateStream( + uint256 indexed streamId, + address indexed sender, + address indexed recipient, + uint256 deposit, + address tokenAddress, + uint256 startTime, + uint256 stopTime + ); + event CancelStream( + uint256 indexed streamId, + address indexed sender, + address indexed recipient, + uint256 senderBalance, + uint256 recipientBalance + ); + event WithdrawFromStream(uint256 indexed streamId, address indexed recipient, uint256 amount); + + function setUp() public { + EXECUTOR_LVL_1 = makeAddr('governance'); + FUNDS_ADMIN = makeAddr('funds-admin'); + OWNER = makeAddr('owner'); + RECIPIENT_STREAM_1 = makeAddr('recipient'); + + PoolAddressesProvider provider = new PoolAddressesProvider('aave', OWNER); + vm.prank(OWNER); + provider.setACLAdmin(EXECUTOR_LVL_1); + + ACLManager aclManager = new ACLManager(provider); + + tokenA = IERC20(address(deployMockERC20('Token A', 'TK_A', 18))); + tokenB = IERC20(address(deployMockERC20('Token B', 'TK_B', 6))); + + streamStartTime = block.timestamp + 10; + streamStopTime = block.timestamp + 70; + nextStreamID = 0; + + collector = new Collector(address(aclManager)); + collector.initialize(nextStreamID); + + deal(address(tokenA), address(collector), 100 ether); + + vm.startPrank(EXECUTOR_LVL_1); + IAccessControl(address(aclManager)).grantRole(collector.FUNDS_ADMIN_ROLE(), FUNDS_ADMIN); + IAccessControl(address(aclManager)).grantRole(collector.FUNDS_ADMIN_ROLE(), EXECUTOR_LVL_1); + vm.stopPrank(); + } + + function testApprove() public { + vm.prank(FUNDS_ADMIN); + collector.approve(tokenA, address(42), 1 ether); + + uint256 allowance = tokenA.allowance(address(collector), address(42)); + + assertEq(allowance, 1 ether); + } + + function testApproveWhenNotFundsAdmin() public { + vm.expectRevert(ICollector.OnlyFundsAdmin.selector); + collector.approve(tokenA, address(0), 1 ether); + } + + function testTransfer() public { + vm.prank(FUNDS_ADMIN); + collector.transfer(tokenA, address(112), 1 ether); + + uint256 balance = tokenA.balanceOf(address(112)); + + assertEq(balance, 1 ether); + } + + function testTransferWhenNotFundsAdmin() public { + vm.expectRevert(ICollector.OnlyFundsAdmin.selector); + + collector.transfer(tokenA, address(112), 1 ether); + } +} + +contract StreamsTest is CollectorTest { + function testGetNextStreamId() public view { + uint256 streamId = collector.getNextStreamId(); + assertEq(streamId, nextStreamID); + } + + function testGetNotExistingStream() public { + vm.expectRevert(ICollector.StreamDoesNotExist.selector); + collector.getStream(nextStreamID + 1); + } + + // create stream + function testCreateStream() public { + vm.expectEmit(true, true, true, true); + emit CreateStream( + nextStreamID, + address(collector), + RECIPIENT_STREAM_1, + 6 ether, + address(tokenA), + streamStartTime, + streamStopTime + ); + + vm.startPrank(FUNDS_ADMIN); + uint256 streamId = createStream(); + + assertEq(streamId, nextStreamID); + + ( + address sender, + address recipient, + uint256 deposit, + address tokenAddress, + uint256 startTime, + uint256 stopTime, + uint256 remainingBalance, + + ) = collector.getStream(streamId); + + assertEq(sender, address(collector)); + assertEq(recipient, RECIPIENT_STREAM_1); + assertEq(deposit, 6 ether); + assertEq(tokenAddress, address(tokenA)); + assertEq(startTime, streamStartTime); + assertEq(stopTime, streamStopTime); + assertEq(remainingBalance, 6 ether); + } + + function testGetStream() public { + vm.prank(FUNDS_ADMIN); + uint256 streamId = createStream(); + (, , , , uint256 startTime, , , ) = collector.getStream(streamId); + assertEq(startTime, streamStartTime); + } + + function testCreateStreamWhenNotFundsAdmin() public { + vm.expectRevert(ICollector.OnlyFundsAdmin.selector); + + collector.createStream( + RECIPIENT_STREAM_1, + 6 ether, + address(tokenA), + streamStartTime, + streamStopTime + ); + } + + function testCreateStreamWhenRecipientIsZero() public { + vm.expectRevert(ICollector.InvalidZeroAddress.selector); + + vm.prank(FUNDS_ADMIN); + collector.createStream(address(0), 6 ether, address(tokenA), streamStartTime, streamStopTime); + } + + function testCreateStreamWhenRecipientIsCollector() public { + vm.expectRevert(ICollector.InvalidRecipient.selector); + + vm.prank(FUNDS_ADMIN); + collector.createStream( + address(collector), + 6 ether, + address(tokenA), + streamStartTime, + streamStopTime + ); + } + + function testCreateStreamWhenRecipientIsTheCaller() public { + vm.expectRevert(ICollector.InvalidRecipient.selector); + + vm.prank(FUNDS_ADMIN); + collector.createStream(FUNDS_ADMIN, 6 ether, address(tokenA), streamStartTime, streamStopTime); + } + + function testCreateStreamWhenDepositIsZero() public { + vm.expectRevert(ICollector.InvalidZeroAmount.selector); + + vm.prank(FUNDS_ADMIN); + collector.createStream( + RECIPIENT_STREAM_1, + 0 ether, + address(tokenA), + streamStartTime, + streamStopTime + ); + } + + function testCreateStreamWhenStartTimeInThePast() public { + vm.warp(block.timestamp + 100); + + vm.expectRevert(ICollector.InvalidStartTime.selector); + + vm.prank(FUNDS_ADMIN); + collector.createStream( + RECIPIENT_STREAM_1, + 6 ether, + address(tokenA), + block.timestamp - 10, + streamStopTime + ); + } + + function testCreateStreamWhenStopTimeBeforeStart() public { + vm.expectRevert(ICollector.InvalidStopTime.selector); + + vm.prank(FUNDS_ADMIN); + collector.createStream( + RECIPIENT_STREAM_1, + 6 ether, + address(tokenA), + block.timestamp + 70, + block.timestamp + 10 + ); + } + + // withdraw from stream + function testWithdrawFromStream() public { + vm.startPrank(FUNDS_ADMIN); + // Arrange + uint256 streamId = createStream(); + vm.stopPrank(); + + vm.warp(block.timestamp + 20); + + uint256 balanceRecipientBefore = tokenA.balanceOf(RECIPIENT_STREAM_1); + uint256 balanceRecipientStreamBefore = collector.balanceOf(streamId, RECIPIENT_STREAM_1); + uint256 balanceCollectorBefore = tokenA.balanceOf(address(collector)); + uint256 balanceCollectorStreamBefore = collector.balanceOf(streamId, address(collector)); + + vm.expectEmit(true, true, true, true); + emit WithdrawFromStream(streamId, RECIPIENT_STREAM_1, 1 ether); + + vm.prank(RECIPIENT_STREAM_1); + // Act + collector.withdrawFromStream(streamId, 1 ether); + + // Assert + uint256 balanceRecipientAfter = tokenA.balanceOf(RECIPIENT_STREAM_1); + uint256 balanceRecipientStreamAfter = collector.balanceOf(streamId, RECIPIENT_STREAM_1); + uint256 balanceCollectorAfter = tokenA.balanceOf(address(collector)); + uint256 balanceCollectorStreamAfter = collector.balanceOf(streamId, address(collector)); + + assertEq(balanceRecipientAfter, balanceRecipientBefore + 1 ether); + assertEq(balanceRecipientStreamAfter, balanceRecipientStreamBefore - 1 ether); + assertEq(balanceCollectorAfter, balanceCollectorBefore - 1 ether); + assertEq(balanceCollectorStreamAfter, balanceCollectorStreamBefore); + } + + function testWithdrawFromStreamFinishesSuccessfully() public { + vm.startPrank(FUNDS_ADMIN); + // Arrange + uint256 streamId = createStream(); + vm.stopPrank(); + + vm.warp(block.timestamp + 70); + + uint256 balanceRecipientBefore = tokenA.balanceOf(RECIPIENT_STREAM_1); + uint256 balanceCollectorBefore = tokenA.balanceOf(address(collector)); + + vm.expectEmit(true, true, true, true); + emit WithdrawFromStream(streamId, RECIPIENT_STREAM_1, 6 ether); + + vm.prank(RECIPIENT_STREAM_1); + // Act + collector.withdrawFromStream(streamId, 6 ether); + + // Assert + uint256 balanceRecipientAfter = tokenA.balanceOf(RECIPIENT_STREAM_1); + uint256 balanceCollectorAfter = tokenA.balanceOf(address(collector)); + + assertEq(balanceRecipientAfter, balanceRecipientBefore + 6 ether); + assertEq(balanceCollectorAfter, balanceCollectorBefore - 6 ether); + + vm.expectRevert(ICollector.StreamDoesNotExist.selector); + collector.getStream(streamId); + } + + function testWithdrawFromStreamWhenStreamNotExists() public { + vm.expectRevert(ICollector.StreamDoesNotExist.selector); + + collector.withdrawFromStream(nextStreamID, 1 ether); + } + + function testWithdrawFromStreamWhenNotAdminOrRecipient() public { + vm.prank(FUNDS_ADMIN); + uint256 streamId = createStream(); + + vm.expectRevert(ICollector.OnlyFundsAdminOrRceipient.selector); + collector.withdrawFromStream(streamId, 1 ether); + } + + function testWithdrawFromStreamWhenAmountIsZero() public { + vm.startPrank(FUNDS_ADMIN); + uint256 streamId = createStream(); + + vm.expectRevert(ICollector.InvalidZeroAmount.selector); + + collector.withdrawFromStream(streamId, 0 ether); + } + + function testWithdrawFromStreamWhenAmountExceedsBalance() public { + vm.prank(FUNDS_ADMIN); + uint256 streamId = collector.createStream( + RECIPIENT_STREAM_1, + 6 ether, + address(tokenA), + streamStartTime, + streamStopTime + ); + + vm.warp(block.timestamp + 20); + vm.expectRevert(ICollector.BalanceExceeded.selector); + + vm.prank(FUNDS_ADMIN); + collector.withdrawFromStream(streamId, 2 ether); + } + + // cancel stream + function testCancelStreamByFundsAdmin() public { + vm.prank(FUNDS_ADMIN); + // Arrange + uint256 streamId = createStream(); + uint256 balanceRecipientBefore = tokenA.balanceOf(RECIPIENT_STREAM_1); + + vm.expectEmit(true, true, true, true); + emit CancelStream(streamId, address(collector), RECIPIENT_STREAM_1, 6 ether, 0); + + vm.prank(FUNDS_ADMIN); + // Act + collector.cancelStream(streamId); + + // Assert + uint256 balanceRecipientAfter = tokenA.balanceOf(RECIPIENT_STREAM_1); + assertEq(balanceRecipientAfter, balanceRecipientBefore); + + vm.expectRevert(ICollector.StreamDoesNotExist.selector); + collector.getStream(streamId); + } + + function testCancelStreamByRecipient() public { + vm.prank(FUNDS_ADMIN); + // Arrange + uint256 streamId = createStream(); + uint256 balanceRecipientBefore = tokenA.balanceOf(RECIPIENT_STREAM_1); + + vm.warp(block.timestamp + 20); + + vm.expectEmit(true, true, true, true); + emit CancelStream(streamId, address(collector), RECIPIENT_STREAM_1, 5 ether, 1 ether); + + vm.prank(RECIPIENT_STREAM_1); + // Act + collector.cancelStream(streamId); + + // Assert + uint256 balanceRecipientAfter = tokenA.balanceOf(RECIPIENT_STREAM_1); + assertEq(balanceRecipientAfter, balanceRecipientBefore + 1 ether); + + vm.expectRevert(ICollector.StreamDoesNotExist.selector); + collector.getStream(streamId); + } + + function testCancelStreamWhenStreamNotExists() public { + vm.expectRevert(ICollector.StreamDoesNotExist.selector); + + collector.cancelStream(nextStreamID); + } + + function testCancelStreamWhenNotAdminOrRecipient() public { + vm.prank(FUNDS_ADMIN); + uint256 streamId = createStream(); + + vm.expectRevert(ICollector.OnlyFundsAdminOrRceipient.selector); + vm.prank(makeAddr('random')); + + collector.cancelStream(streamId); + } + + function createStream() private returns (uint256) { + return + collector.createStream( + RECIPIENT_STREAM_1, + 6 ether, + address(tokenA), + streamStartTime, + streamStopTime + ); + } +} + +contract GetRevision is CollectorTest { + function test_successful() public view { + assertEq(collector.REVISION(), 6); + } +} + +contract FundsAdminRoleBytesTest is CollectorTest { + function test_successful() public view { + assertEq(collector.FUNDS_ADMIN_ROLE(), 'FUNDS_ADMIN'); + } +} + +contract IsFundsAdminTest is CollectorTest { + function test_isNotFundsAdmin() public { + assertFalse(collector.isFundsAdmin(makeAddr('not-funds-admin'))); + } + + function test_isFundsAdmin() public view { + assertTrue(collector.isFundsAdmin(FUNDS_ADMIN)); + assertTrue(collector.isFundsAdmin(EXECUTOR_LVL_1)); + } +} From 6b79da1d0f72d4308bd69ed6c5645ed867b0911f Mon Sep 17 00:00:00 2001 From: Lukas Date: Thu, 5 Dec 2024 11:53:22 +0100 Subject: [PATCH 2/5] fix: remove deprecated funds admin --- src/contracts/treasury/Collector.sol | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/contracts/treasury/Collector.sol b/src/contracts/treasury/Collector.sol index 5caebf45..81098269 100644 --- a/src/contracts/treasury/Collector.sol +++ b/src/contracts/treasury/Collector.sol @@ -42,11 +42,6 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard { /// @inheritdoc ICollector address public immutable ACL_MANAGER; - /** - * @notice [DEPRECATED] Use `isFundsAdmin()` to check address. - */ - address internal _fundsAdmin_deprecated; - /** * @notice Counter for new stream ids. */ From ac9fd331dc1677dc0874c96e6eec2debe8b5dbd0 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Thu, 5 Dec 2024 19:37:12 +0530 Subject: [PATCH 3/5] feat: migrate treasury deployment from peripheryBatch to setupBatch --- .../procedures/AaveV3SetupProcedure.sol | 81 ++++++++++++++++++- .../procedures/AaveV3TreasuryProcedure.sol | 53 ------------ .../interfaces/IMarketReportTypes.sol | 6 +- .../AaveV3BatchOrchestration.sol | 15 ++-- .../batches/AaveV3PeripheryBatch.sol | 29 ------- .../batches/AaveV3SetupBatch.sol | 6 +- tests/deployments/AaveV3BatchTests.t.sol | 5 +- tests/deployments/DeploymentsGasLimits.t.sol | 5 +- tests/utils/BatchTestProcedures.sol | 3 +- 9 files changed, 103 insertions(+), 100 deletions(-) delete mode 100644 src/deployments/contracts/procedures/AaveV3TreasuryProcedure.sol diff --git a/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol b/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol index 8e6357fe..a01288c2 100644 --- a/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol +++ b/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol @@ -10,6 +10,10 @@ import {PoolAddressesProvider} from '../../../contracts/protocol/configuration/P import {PoolAddressesProviderRegistry} from '../../../contracts/protocol/configuration/PoolAddressesProviderRegistry.sol'; import {IEmissionManager} from '../../../contracts/rewards/interfaces/IEmissionManager.sol'; import {IRewardsController} from '../../../contracts/rewards/interfaces/IRewardsController.sol'; +import {Collector} from '../../../contracts/treasury/Collector.sol'; +import {ProxyAdmin} from 'solidity-utils/contracts/transparent-proxy/ProxyAdmin.sol'; +import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; +import {RevenueSplitter} from '../../../contracts/treasury/RevenueSplitter.sol'; contract AaveV3SetupProcedure { error MarketOwnerMustBeSet(); @@ -27,6 +31,15 @@ contract AaveV3SetupProcedure { address priceOracleSentinel; } + struct TreasuryInput { + address treasuryProxy; + address treasuryPartner; + uint16 treasurySplitPercent; + address proxyAdmin; + address aclManager; + bytes32 salt; + } + function _initialDeployment( address providerRegistry, address marketOwner, @@ -54,7 +67,8 @@ contract AaveV3SetupProcedure { address protocolDataProvider, address aaveOracle, address rewardsControllerImplementation, - address priceOracleSentinel + address priceOracleSentinel, + address proxyAdmin ) internal returns (SetupReport memory) { _validateMarketSetup(roles); @@ -80,6 +94,17 @@ contract AaveV3SetupProcedure { config.flashLoanPremiumToProtocol ); + (report.treasuryProxy, report.treasuryImplementation, report.revenueSplitter) = _setupTreasury( + TreasuryInput({ + treasuryProxy: config.treasury, + treasuryPartner: config.treasuryPartner, + treasurySplitPercent: config.treasurySplitPercent, + proxyAdmin: proxyAdmin, + aclManager: report.aclManager, + salt: config.salt + }) + ); + _transferMarketOwnership(roles, initialReport); return report; @@ -183,6 +208,60 @@ contract AaveV3SetupProcedure { return aclManager; } + function _deployAaveV3Treasury( + address deployedProxyAdmin, + address aclManager, + bytes32 salt + ) internal returns (address treasuryProxy, address treasuryImplementation) { + if (salt != '') { + treasuryImplementation = address(new Collector{salt: salt}(aclManager)); + Collector(treasuryImplementation).initialize(0); + + treasuryProxy = address( + new TransparentUpgradeableProxy{salt: salt}( + treasuryImplementation, + ProxyAdmin(deployedProxyAdmin), + abi.encodeWithSelector(Collector.initialize.selector, 100_000) + ) + ); + } else { + treasuryImplementation = address(new Collector(aclManager)); + Collector(treasuryImplementation).initialize(0); + + treasuryProxy = address( + new TransparentUpgradeableProxy( + treasuryImplementation, + ProxyAdmin(deployedProxyAdmin), + abi.encodeWithSelector(Collector.initialize.selector, 100_000) + ) + ); + } + } + + function _setupTreasury( + TreasuryInput memory input + ) internal returns (address treasuryProxy, address treasuryImplementation, address revenueSplitter) { + if (input.treasuryProxy == address(0)) { + (treasuryProxy, treasuryImplementation) = _deployAaveV3Treasury( + input.proxyAdmin, + input.aclManager, + input.salt + ); + } else { + treasuryProxy = input.treasuryProxy; + } + + if ( + input.treasuryPartner != address(0) && + input.treasurySplitPercent > 0 && + input.treasurySplitPercent < 100_00 + ) { + revenueSplitter = address( + new RevenueSplitter(treasuryProxy, input.treasuryPartner, input.treasurySplitPercent) + ); + } + } + function _configureFlashloanParams( ACLManager manager, address poolConfiguratorProxy, diff --git a/src/deployments/contracts/procedures/AaveV3TreasuryProcedure.sol b/src/deployments/contracts/procedures/AaveV3TreasuryProcedure.sol deleted file mode 100644 index c18b3cda..00000000 --- a/src/deployments/contracts/procedures/AaveV3TreasuryProcedure.sol +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; - -import {ProxyAdmin} from 'solidity-utils/contracts/transparent-proxy/ProxyAdmin.sol'; -import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; -import {Collector} from '../../../contracts/treasury/Collector.sol'; -import '../../interfaces/IMarketReportTypes.sol'; - -contract AaveV3TreasuryProcedure { - struct TreasuryReport { - address treasuryImplementation; - address treasury; - } - - function _deployAaveV3Treasury( - address poolAdmin, - address deployedProxyAdmin, - address aclManager, - bytes32 collectorSalt - ) internal returns (TreasuryReport memory) { - TreasuryReport memory treasuryReport; - bytes32 salt = collectorSalt; - address treasuryOwner = poolAdmin; - - if (salt != '') { - Collector treasuryImplementation = new Collector{salt: salt}(aclManager); - treasuryImplementation.initialize(0); - treasuryReport.treasuryImplementation = address(treasuryImplementation); - - treasuryReport.treasury = address( - new TransparentUpgradeableProxy{salt: salt}( - treasuryReport.treasuryImplementation, - ProxyAdmin(deployedProxyAdmin), - abi.encodeWithSelector(treasuryImplementation.initialize.selector, 100_000) - ) - ); - } else { - Collector treasuryImplementation = new Collector(aclManager); - treasuryImplementation.initialize(0); - treasuryReport.treasuryImplementation = address(treasuryImplementation); - - treasuryReport.treasury = address( - new TransparentUpgradeableProxy( - treasuryReport.treasuryImplementation, - ProxyAdmin(deployedProxyAdmin), - abi.encodeWithSelector(treasuryImplementation.initialize.selector, 100_000) - ) - ); - } - - return treasuryReport; - } -} diff --git a/src/deployments/interfaces/IMarketReportTypes.sol b/src/deployments/interfaces/IMarketReportTypes.sol index afa6a2e2..66515004 100644 --- a/src/deployments/interfaces/IMarketReportTypes.sol +++ b/src/deployments/interfaces/IMarketReportTypes.sol @@ -168,16 +168,16 @@ struct SetupReport { address poolConfiguratorProxy; address rewardsControllerProxy; address aclManager; + address treasuryProxy; + address treasuryImplementation; + address revenueSplitter; } struct PeripheryReport { address aaveOracle; address proxyAdmin; - address treasury; - address treasuryImplementation; address emissionManager; address rewardsControllerImplementation; - address revenueSplitter; } struct ParaswapReport { diff --git a/src/deployments/projects/aave-v3-batched/AaveV3BatchOrchestration.sol b/src/deployments/projects/aave-v3-batched/AaveV3BatchOrchestration.sol index 1ef2ee87..019b9d35 100644 --- a/src/deployments/projects/aave-v3-batched/AaveV3BatchOrchestration.sol +++ b/src/deployments/projects/aave-v3-batched/AaveV3BatchOrchestration.sol @@ -70,7 +70,8 @@ library AaveV3BatchOrchestration { gettersReport1.protocolDataProvider, peripheryReport.aaveOracle, peripheryReport.rewardsControllerImplementation, - miscReport.priceOracleSentinel + miscReport.priceOracleSentinel, + peripheryReport.proxyAdmin ); ParaswapReport memory paraswapReport = _deployParaswapAdapters( @@ -169,9 +170,9 @@ library AaveV3BatchOrchestration { PeripheryReport memory peripheryReport, AaveV3TokensBatch.TokensReport memory tokensReport ) internal returns (ConfigEngineReport memory) { - address treasury = peripheryReport.treasury; - if (peripheryReport.revenueSplitter != address(0)) { - treasury = peripheryReport.revenueSplitter; + address treasury = setupReport.treasuryProxy; + if (setupReport.revenueSplitter != address(0)) { + treasury = setupReport.revenueSplitter; } AaveV3HelpersBatchOne helpersBatchOne = new AaveV3HelpersBatchOne( @@ -310,9 +311,9 @@ library AaveV3BatchOrchestration { report.paraSwapLiquiditySwapAdapter = paraswapReport.paraSwapLiquiditySwapAdapter; report.paraSwapRepayAdapter = paraswapReport.paraSwapRepayAdapter; report.paraSwapWithdrawSwapAdapter = paraswapReport.paraSwapWithdrawSwapAdapter; - report.treasuryImplementation = peripheryReport.treasuryImplementation; + report.treasuryImplementation = setupReport.treasuryImplementation; report.proxyAdmin = peripheryReport.proxyAdmin; - report.treasury = peripheryReport.treasury; + report.treasury = setupReport.treasuryProxy; report.poolProxy = setupReport.poolProxy; report.poolConfiguratorProxy = setupReport.poolConfiguratorProxy; report.rewardsControllerProxy = setupReport.rewardsControllerProxy; @@ -326,7 +327,7 @@ library AaveV3BatchOrchestration { report.staticATokenFactoryProxy = staticATokenReport.staticATokenFactoryProxy; report.staticATokenImplementation = staticATokenReport.staticATokenImplementation; report.transparentProxyFactory = staticATokenReport.transparentProxyFactory; - report.revenueSplitter = peripheryReport.revenueSplitter; + report.revenueSplitter = setupReport.revenueSplitter; return report; } diff --git a/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol b/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol index 5e418319..4d701b2e 100644 --- a/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol +++ b/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol @@ -1,17 +1,14 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import {AaveV3TreasuryProcedure} from '../../../contracts/procedures/AaveV3TreasuryProcedure.sol'; import {AaveV3OracleProcedure} from '../../../contracts/procedures/AaveV3OracleProcedure.sol'; import {AaveV3IncentiveProcedure} from '../../../contracts/procedures/AaveV3IncentiveProcedure.sol'; import {AaveV3DefaultRateStrategyProcedure} from '../../../contracts/procedures/AaveV3DefaultRateStrategyProcedure.sol'; import {Ownable} from '../../../../contracts/dependencies/openzeppelin/contracts/Ownable.sol'; import '../../../interfaces/IMarketReportTypes.sol'; import {IRewardsController} from '../../../../contracts/rewards/interfaces/IRewardsController.sol'; -import {RevenueSplitter} from '../../../../contracts/treasury/RevenueSplitter.sol'; contract AaveV3PeripheryBatch is - AaveV3TreasuryProcedure, AaveV3OracleProcedure, AaveV3IncentiveProcedure { @@ -31,32 +28,6 @@ contract AaveV3PeripheryBatch is _report.aaveOracle = _deployAaveOracle(config.oracleDecimals, poolAddressesProvider); - address aclManager = address(1); // temp-to-run-tests - - if (config.treasury == address(0)) { - TreasuryReport memory treasuryReport = _deployAaveV3Treasury( - poolAdmin, - _report.proxyAdmin, - aclManager, - config.salt - ); - - _report.treasury = treasuryReport.treasury; - _report.treasuryImplementation = treasuryReport.treasuryImplementation; - } else { - _report.treasury = config.treasury; - } - - if ( - config.treasuryPartner != address(0) && - config.treasurySplitPercent > 0 && - config.treasurySplitPercent < 100_00 - ) { - _report.revenueSplitter = address( - new RevenueSplitter(_report.treasury, config.treasuryPartner, config.treasurySplitPercent) - ); - } - if (config.incentivesProxy == address(0)) { (_report.emissionManager, _report.rewardsControllerImplementation) = _deployIncentives( setupBatch diff --git a/src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol b/src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol index abed9a61..7444b402 100644 --- a/src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol +++ b/src/deployments/projects/aave-v3-batched/batches/AaveV3SetupBatch.sol @@ -33,7 +33,8 @@ contract AaveV3SetupBatch is MarketReportStorage, AaveV3SetupProcedure, Ownable address protocolDataProvider, address aaveOracle, address rewardsControllerImplementation, - address priceOracleSentinel + address priceOracleSentinel, + address proxyAdmin ) external onlyOwner returns (SetupReport memory) { _setupReport = _setupAaveV3Market( roles, @@ -44,7 +45,8 @@ contract AaveV3SetupBatch is MarketReportStorage, AaveV3SetupProcedure, Ownable protocolDataProvider, aaveOracle, rewardsControllerImplementation, - priceOracleSentinel + priceOracleSentinel, + proxyAdmin ); return _setupReport; diff --git a/tests/deployments/AaveV3BatchTests.t.sol b/tests/deployments/AaveV3BatchTests.t.sol index 2252b7ce..cb10edc4 100644 --- a/tests/deployments/AaveV3BatchTests.t.sol +++ b/tests/deployments/AaveV3BatchTests.t.sol @@ -175,7 +175,8 @@ contract AaveV3BatchTests is BatchTestProcedures { gettersReportOne.protocolDataProvider, peripheryReportOne.aaveOracle, peripheryReportOne.rewardsControllerImplementation, - miscReport.priceOracleSentinel + miscReport.priceOracleSentinel, + peripheryReportOne.proxyAdmin ); } @@ -190,7 +191,7 @@ contract AaveV3BatchTests is BatchTestProcedures { miscReport.defaultInterestRateStrategy, peripheryReportOne.aaveOracle, setupReportTwo.rewardsControllerProxy, - peripheryReportOne.treasury, + setupReportTwo.treasuryProxy, tokensReport.aToken, tokensReport.variableDebtToken ); diff --git a/tests/deployments/DeploymentsGasLimits.t.sol b/tests/deployments/DeploymentsGasLimits.t.sol index 98e2da92..71173b0d 100644 --- a/tests/deployments/DeploymentsGasLimits.t.sol +++ b/tests/deployments/DeploymentsGasLimits.t.sol @@ -160,7 +160,8 @@ contract DeploymentsGasLimits is BatchTestProcedures { gettersReportOne.protocolDataProvider, peripheryReportOne.aaveOracle, peripheryReportOne.rewardsControllerImplementation, - miscReport.priceOracleSentinel + miscReport.priceOracleSentinel, + peripheryReportOne.proxyAdmin ); } @@ -175,7 +176,7 @@ contract DeploymentsGasLimits is BatchTestProcedures { miscReport.defaultInterestRateStrategy, peripheryReportOne.aaveOracle, setupReportTwo.rewardsControllerProxy, - peripheryReportOne.treasury, + setupReportTwo.treasuryProxy, tokensReport.aToken, tokensReport.variableDebtToken ); diff --git a/tests/utils/BatchTestProcedures.sol b/tests/utils/BatchTestProcedures.sol index edbda935..59961056 100644 --- a/tests/utils/BatchTestProcedures.sol +++ b/tests/utils/BatchTestProcedures.sol @@ -141,7 +141,8 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput gettersReport1.protocolDataProvider, peripheryReport.aaveOracle, peripheryReport.rewardsControllerImplementation, - miscReport.priceOracleSentinel + miscReport.priceOracleSentinel, + peripheryReport.proxyAdmin ); paraswapReport = AaveV3BatchOrchestration._deployParaswapAdapters( From c3aa25280dabc0e120ffff239e302062fa32bc98 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Thu, 5 Dec 2024 19:42:28 +0530 Subject: [PATCH 4/5] chore: fix lint --- .../contracts/procedures/AaveV3SetupProcedure.sol | 5 ++++- .../aave-v3-batched/batches/AaveV3PeripheryBatch.sol | 5 +---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol b/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol index a01288c2..cfe1b15a 100644 --- a/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol +++ b/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol @@ -240,7 +240,10 @@ contract AaveV3SetupProcedure { function _setupTreasury( TreasuryInput memory input - ) internal returns (address treasuryProxy, address treasuryImplementation, address revenueSplitter) { + ) + internal + returns (address treasuryProxy, address treasuryImplementation, address revenueSplitter) + { if (input.treasuryProxy == address(0)) { (treasuryProxy, treasuryImplementation) = _deployAaveV3Treasury( input.proxyAdmin, diff --git a/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol b/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol index 4d701b2e..5648ef84 100644 --- a/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol +++ b/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol @@ -8,10 +8,7 @@ import {Ownable} from '../../../../contracts/dependencies/openzeppelin/contracts import '../../../interfaces/IMarketReportTypes.sol'; import {IRewardsController} from '../../../../contracts/rewards/interfaces/IRewardsController.sol'; -contract AaveV3PeripheryBatch is - AaveV3OracleProcedure, - AaveV3IncentiveProcedure -{ +contract AaveV3PeripheryBatch is AaveV3OracleProcedure, AaveV3IncentiveProcedure { PeripheryReport internal _report; constructor( From 76ab7a2f462f7c01e98b9b3de502eda66fb61e61 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Thu, 5 Dec 2024 19:49:44 +0530 Subject: [PATCH 5/5] chore: fix old struct --- .../procedures/AaveV3SetupProcedure.sol | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol b/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol index cfe1b15a..9e818950 100644 --- a/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol +++ b/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol @@ -73,17 +73,17 @@ contract AaveV3SetupProcedure { _validateMarketSetup(roles); SetupReport memory report = _setupPoolAddressesProvider( - AddressProviderInput( - initialReport, - poolImplementation, - poolConfiguratorImplementation, - protocolDataProvider, - roles.poolAdmin, - aaveOracle, - config.incentivesProxy, - rewardsControllerImplementation, - priceOracleSentinel - ) + AddressProviderInput({ + initialReport: initialReport, + poolImplementation: poolImplementation, + poolConfiguratorImplementation: poolConfiguratorImplementation, + protocolDataProvider: protocolDataProvider, + poolAdmin: roles.poolAdmin, + aaveOracle: aaveOracle, + rewardsControllerProxy: config.incentivesProxy, + rewardsControllerImplementation: rewardsControllerImplementation, + priceOracleSentinel: priceOracleSentinel + }) ); report.aclManager = _setupACL(