Skip to content
This repository was archived by the owner on Oct 21, 2025. It is now read-only.

Commit 45d0e3f

Browse files
authored
Merge pull request #63 from aave/feat/collector-contracts
feat: add Collector implementation and controller
2 parents 4137f7a + ad415b0 commit 45d0e3f

File tree

3 files changed

+195
-0
lines changed

3 files changed

+195
-0
lines changed

contracts/treasury/Collector.sol

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// SPDX-License-Identifier: agpl-3.0
2+
pragma solidity 0.8.10;
3+
4+
import {VersionedInitializable} from '@aave/core-v3/contracts/protocol/libraries/aave-upgradeability/VersionedInitializable.sol';
5+
import {IERC20} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/IERC20.sol';
6+
import {ICollector} from './interfaces/ICollector.sol';
7+
8+
/**
9+
* @title Collector
10+
* @notice Stores the fees collected by the protocol and allows the fund administrator
11+
* to approve or transfer the collected ERC20 tokens.
12+
* @dev Implementation contract that must be initialized using transparent proxy pattern.
13+
* @author Aave
14+
**/
15+
contract Collector is VersionedInitializable, ICollector {
16+
// Store the current funds administrator address
17+
address internal _fundsAdmin;
18+
19+
// Revision version of this implementation contract
20+
uint256 public constant REVISION = 1;
21+
22+
/**
23+
* @dev Allow only the funds administrator address to call functions marked by this modifier
24+
*/
25+
modifier onlyFundsAdmin() {
26+
require(msg.sender == _fundsAdmin, 'ONLY_BY_FUNDS_ADMIN');
27+
_;
28+
}
29+
30+
/**
31+
* @dev Initialize the transparent proxy with the admin of the Collector
32+
* @param reserveController The address of the admin that controls Collector
33+
*/
34+
function initialize(address reserveController) external initializer {
35+
_setFundsAdmin(reserveController);
36+
}
37+
38+
/// @inheritdoc VersionedInitializable
39+
function getRevision() internal pure override returns (uint256) {
40+
return REVISION;
41+
}
42+
43+
/// @inheritdoc ICollector
44+
function getFundsAdmin() external view returns (address) {
45+
return _fundsAdmin;
46+
}
47+
48+
/// @inheritdoc ICollector
49+
function approve(
50+
IERC20 token,
51+
address recipient,
52+
uint256 amount
53+
) external onlyFundsAdmin {
54+
token.approve(recipient, amount);
55+
}
56+
57+
/// @inheritdoc ICollector
58+
function transfer(
59+
IERC20 token,
60+
address recipient,
61+
uint256 amount
62+
) external onlyFundsAdmin {
63+
token.transfer(recipient, amount);
64+
}
65+
66+
/// @inheritdoc ICollector
67+
function setFundsAdmin(address admin) external onlyFundsAdmin {
68+
_setFundsAdmin(admin);
69+
}
70+
71+
/**
72+
* @dev Transfer the ownership of the funds administrator role.
73+
* @param admin The address of the new funds administrator
74+
*/
75+
function _setFundsAdmin(address admin) internal {
76+
_fundsAdmin = admin;
77+
emit NewFundsAdmin(admin);
78+
}
79+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// SPDX-License-Identifier: agpl-3.0
2+
pragma solidity 0.8.10;
3+
4+
import {Ownable} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/Ownable.sol';
5+
import {IERC20} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/IERC20.sol';
6+
import {ICollector} from './interfaces/ICollector.sol';
7+
8+
/**
9+
* @title CollectorController
10+
* @notice The CollectorController contracts allows the owner of the contract
11+
to approve or transfer tokens from the collector proxy contract.
12+
The admin of the Collector proxy can't be the same as the fundsAdmin address.
13+
This is needed due the usage of transparent proxy pattern.
14+
* @author Aave
15+
**/
16+
contract CollectorController is Ownable {
17+
ICollector public immutable COLLECTOR;
18+
19+
/**
20+
* @dev Constructor setups the ownership of the contract and the collector proxy
21+
* @param owner The address of the owner of the CollectorController
22+
* @param collectorProxy The address of the Collector transparent proxy
23+
*/
24+
constructor(address owner, address collectorProxy) {
25+
transferOwnership(owner);
26+
COLLECTOR = ICollector(collectorProxy);
27+
}
28+
29+
/**
30+
* @dev Transfer an amount of tokens to the recipient.
31+
* @param token The address of the asset
32+
* @param recipient The address of the entity to transfer the tokens.
33+
* @param amount The amount to be transferred.
34+
*/
35+
function approve(
36+
IERC20 token,
37+
address recipient,
38+
uint256 amount
39+
) external onlyOwner {
40+
COLLECTOR.approve(token, recipient, amount);
41+
}
42+
43+
/**
44+
* @dev Transfer an amount of tokens to the recipient.
45+
* @param token The address of the asset
46+
* @param recipient The address of the entity to transfer the tokens.
47+
* @param amount The amount to be transferred.
48+
*/
49+
function transfer(
50+
IERC20 token,
51+
address recipient,
52+
uint256 amount
53+
) external onlyOwner {
54+
COLLECTOR.transfer(token, recipient, amount);
55+
}
56+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// SPDX-License-Identifier: agpl-3.0
2+
pragma solidity 0.8.10;
3+
4+
import {IERC20} from '@aave/core-v3/contracts/dependencies/openzeppelin/contracts/IERC20.sol';
5+
6+
/**
7+
* @title ICollector
8+
* @notice Defines the interface of the Collector contract
9+
* @author Aave
10+
**/
11+
interface ICollector {
12+
/**
13+
* @dev Emitted during the transfer of ownership of the funds administrator address
14+
* @param fundsAdmin The new funds administrator address
15+
**/
16+
event NewFundsAdmin(address indexed fundsAdmin);
17+
18+
/**
19+
* @dev Retrieve the current implementation Revision of the proxy
20+
* @return The revision version
21+
*/
22+
function REVISION() external view returns (uint256);
23+
24+
/**
25+
* @dev Retrieve the current funds administrator
26+
* @return The address of the funds administrator
27+
*/
28+
function getFundsAdmin() external view returns (address);
29+
30+
/**
31+
* @dev Approve an amount of tokens to be pulled by the recipient.
32+
* @param token The address of the asset
33+
* @param recipient The address of the entity allowed to pull tokens
34+
* @param amount The amount allowed to be pulled. If zero it will revoke the approval.
35+
*/
36+
function approve(
37+
IERC20 token,
38+
address recipient,
39+
uint256 amount
40+
) external;
41+
42+
/**
43+
* @dev Transfer an amount of tokens to the recipient.
44+
* @param token The address of the asset
45+
* @param recipient The address of the entity to transfer the tokens.
46+
* @param amount The amount to be transferred.
47+
*/
48+
function transfer(
49+
IERC20 token,
50+
address recipient,
51+
uint256 amount
52+
) external;
53+
54+
/**
55+
* @dev Transfer the ownership of the funds administrator role.
56+
This function should only be callable by the current funds administrator.
57+
* @param admin The address of the new funds administrator
58+
*/
59+
function setFundsAdmin(address admin) external;
60+
}

0 commit comments

Comments
 (0)