Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 36 additions & 31 deletions src/contracts/treasury/Collector.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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;

/**
* @notice Current revision of the contract.
* @notice FUNDS_ADMIN role granted in ACL Manager
*/
uint256 public constant REVISION = 5;
bytes32 public constant FUNDS_ADMIN_ROLE =
0x75456b37135373dd0d9c06da636f8afc8a433394d71309d732eb6fb591fba90e;

/**
* @notice Address of the current ACL Manager.
*/
address public immutable ACL_MANAGER;

/**
* @notice Counter for new stream ids.
Expand All @@ -47,16 +57,18 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard {
*/
mapping(uint256 => Stream) private _streams;

/// @inheritdoc ICollector
address public constant ETH_MOCK_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
/**
* @notice [DEPRECATED] Use `isFundsAdmin()` to check address.
*/
address internal _fundsAdmin_deprecated;

/*** Modifiers ***/

/**
* @dev Throws if the caller is not the funds admin.
*/
modifier onlyFundsAdmin() {
require(msg.sender == _fundsAdmin, 'ONLY_BY_FUNDS_ADMIN');
modifier onlyFundsAdmins() {
require(_onlyFundsAdmins(), 'ONLY_BY_FUNDS_ADMIN');
_;
}

Expand All @@ -66,8 +78,8 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard {
*/
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'
_onlyFundsAdmins() || msg.sender == _streams[streamId].recipient,
'caller is not the funds admin nor the recipient of the stream'
);
_;
}
Expand All @@ -80,15 +92,18 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard {
_;
}

constructor(address aclManager) public {
require(aclManager != address(0), 'cannot be the zero-address');
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 ***/
Expand All @@ -99,8 +114,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
Expand Down Expand Up @@ -189,12 +204,12 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard {
/*** Public Effects & Interactions Functions ***/

/// @inheritdoc ICollector
function approve(IERC20 token, address recipient, uint256 amount) external onlyFundsAdmin {
function approve(IERC20 token, address recipient, uint256 amount) external onlyFundsAdmins {
token.safeApprove(recipient, amount);
}

/// @inheritdoc ICollector
function transfer(IERC20 token, address recipient, uint256 amount) external onlyFundsAdmin {
function transfer(IERC20 token, address recipient, uint256 amount) external onlyFundsAdmins {
require(recipient != address(0), 'INVALID_0X_RECIPIENT');

if (address(token) == ETH_MOCK_ADDRESS) {
Expand All @@ -204,18 +219,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 _onlyFundsAdmins() internal view returns (bool) {
return IAccessControl(ACL_MANAGER).hasRole(FUNDS_ADMIN_ROLE, msg.sender);
}

struct CreateStreamLocalVars {
Expand Down Expand Up @@ -243,7 +248,7 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard {
address tokenAddress,
uint256 startTime,
uint256 stopTime
) external onlyFundsAdmin returns (uint256) {
) external onlyFundsAdmins 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');
Expand Down
28 changes: 13 additions & 15 deletions src/contracts/treasury/ICollector.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ interface ICollector {
bool isEntity;
}

/** @notice Emitted when the funds admin changes
* @param fundsAdmin The new funds admin.
/** @notice Emitted during the switch of the ACL Manager contract address
* @param manager The new ACL Manager contract address.
**/
event NewFundsAdmin(address indexed fundsAdmin);
event NewACLManager(address indexed manager);

/** @notice Emitted when the new stream is created
* @param streamId The identifier of the stream.
Expand Down Expand Up @@ -70,16 +70,21 @@ interface ICollector {
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 [DEPRECATED] This function is no longer recommended for use.
* @dev Use `isFundsAdmin` instead to check if an address has the fundsAdmin role.
**/
function getFundsAdmin() external view returns (address);
// function getFundsAdmin() external view returns (address);

/**
* @notice Checks if address is funds admin
* @return bool If the address has the funds admin role
**/
function isFundsAdmin(address admin) external view returns (bool);

/**
* @notice Returns the available funds for the given stream id and address.
Expand All @@ -105,13 +110,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.
Expand Down
21 changes: 7 additions & 14 deletions src/deployments/contracts/procedures/AaveV3TreasuryProcedure.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,37 +20,30 @@ contract AaveV3TreasuryProcedure {
TreasuryReport memory treasuryReport;
bytes32 salt = collectorSalt;
address treasuryOwner = poolAdmin;
address aclManager;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems incomplete, you need to pass in the aclManager otherwise i guess deployment would revert.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Luigy-Lemon you can pass the aclManager from AaveV3PeripheryBatch contract as a function param to _deployAaveV3Treasury()


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, 0)
)
);
} 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)
)
);
}
Expand Down
Loading