Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
47 changes: 34 additions & 13 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 Down Expand Up @@ -35,7 +36,7 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard {
/**
* @notice Current revision of the contract.
*/
uint256 public constant REVISION = 5;
uint256 public constant REVISION = 6;

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

/**
* @notice Address of the current ACL Manager.
*/
address internal _aclManager;

/// @inheritdoc ICollector
address public constant ETH_MOCK_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

/**
* @notice FUNDS_ADMIN role granted in ACL Manager
*/
bytes32 public constant FUNDS_ADMIN_ROLE = keccak256('FUNDS_ADMIN');

/*** Modifiers ***/

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

Expand All @@ -66,8 +77,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 @@ -83,12 +94,12 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard {
/*** Contract Logic Starts Here */

/// @inheritdoc ICollector
function initialize(address fundsAdmin, uint256 nextStreamId) external initializer {
function initialize(address aclManager, uint256 nextStreamId) external initializer {
if (nextStreamId != 0) {
_nextStreamId = nextStreamId;
}

_setFundsAdmin(fundsAdmin);
_setACLManager(aclManager);
}

/*** View Functions ***/
Expand All @@ -103,6 +114,11 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard {
return _fundsAdmin;
}

/// @inheritdoc ICollector
function isFundsAdmin(address admin) external view returns (bool) {
return IAccessControl(_aclManager).hasRole(FUNDS_ADMIN_ROLE, admin);
}

/// @inheritdoc ICollector
function getNextStreamId() external view returns (uint256) {
return _nextStreamId;
Expand Down Expand Up @@ -205,17 +221,22 @@ contract Collector is VersionedInitializable, ICollector, ReentrancyGuard {
}

/// @inheritdoc ICollector
function setFundsAdmin(address admin) external onlyFundsAdmin {
_setFundsAdmin(admin);
function setACLManager(address manager) external onlyFundsAdmin {
_setACLManager(manager);
}

/**
* @dev Transfer the ownership of the funds administrator role.
* @param admin The address of the new funds administrator
* @dev Switch ACL Manager contract address.
* @param manager The address of the new ACL Manager contract address
*/
function _setFundsAdmin(address admin) internal {
_fundsAdmin = admin;
emit NewFundsAdmin(admin);
function _setACLManager(address manager) internal {
require(manager != address(0), 'cannot be the zero-address');
_aclManager = manager;
emit NewACLManager(manager);
}

function _onlyFundsAdmins() internal view returns (bool) {
return IAccessControl(_aclManager).hasRole(FUNDS_ADMIN_ROLE, msg.sender);
}

struct CreateStreamLocalVars {
Expand Down
22 changes: 14 additions & 8 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,17 +70,23 @@ interface ICollector {
function ETH_MOCK_ADDRESS() external pure returns (address);

/** @notice Initializes the contracts
* @param fundsAdmin Funds admin address
* @param aclManager The address of the ACL Manager
* @param nextStreamId StreamId to set, applied if greater than 0
**/
function initialize(address fundsAdmin, uint256 nextStreamId) external;
function initialize(address aclManager, 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
**/
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.
* @param streamId The id of the stream for which to query the balance.
Expand All @@ -106,11 +112,11 @@ interface ICollector {
function transfer(IERC20 token, address recipient, uint256 amount) external;

/**
* @dev Transfer the ownership of the funds administrator role.
* @dev Switch ACL Manager contract address.
This function should only be callable by the current funds administrator.
* @param admin The address of the new funds administrator
* @param manager The address of the new ACL Manager contract address
*/
function setFundsAdmin(address admin) external;
function setACLManager(address manager) external;

/**
* @notice Creates a new stream funded by this contracts itself and paid towards `recipient`.
Expand Down
Loading