Branch data Line data Source code
1 : : // SPDX-License-Identifier: MIT
2 : : pragma solidity ^0.8.10;
3 : :
4 : : import {Context} from '../../../dependencies/openzeppelin/contracts/Context.sol';
5 : : import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol';
6 : : import {IERC20Detailed} from '../../../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
7 : : import {SafeCast} from '../../../dependencies/openzeppelin/contracts/SafeCast.sol';
8 : : import {WadRayMath} from '../../libraries/math/WadRayMath.sol';
9 : : import {Errors} from '../../libraries/helpers/Errors.sol';
10 : : import {IAaveIncentivesController} from '../../../interfaces/IAaveIncentivesController.sol';
11 : : import {IPoolAddressesProvider} from '../../../interfaces/IPoolAddressesProvider.sol';
12 : : import {IPool} from '../../../interfaces/IPool.sol';
13 : : import {IACLManager} from '../../../interfaces/IACLManager.sol';
14 : :
15 : : /**
16 : : * @title IncentivizedERC20
17 : : * @author Aave, inspired by the Openzeppelin ERC20 implementation
18 : : * @notice Basic ERC20 implementation
19 : : */
20 : : abstract contract IncentivizedERC20 is Context, IERC20Detailed {
21 : : using WadRayMath for uint256;
22 : : using SafeCast for uint256;
23 : :
24 : : /**
25 : : * @dev Only pool admin can call functions marked by this modifier.
26 : : */
27 : : modifier onlyPoolAdmin() {
28 : 3 : IACLManager aclManager = IACLManager(_addressesProvider.getACLManager());
29 : 3 : require(aclManager.isPoolAdmin(msg.sender), Errors.CALLER_NOT_POOL_ADMIN);
30 : : _;
31 : : }
32 : :
33 : : /**
34 : : * @dev Only pool can call functions marked by this modifier.
35 : : */
36 : : modifier onlyPool() {
37 : 34199 : require(_msgSender() == address(POOL), Errors.CALLER_MUST_BE_POOL);
38 : : _;
39 : : }
40 : :
41 : : /**
42 : : * @dev UserState - additionalData is a flexible field.
43 : : * ATokens and VariableDebtTokens use this field store the index of the
44 : : * user's last supply/withdrawal/borrow/repayment.
45 : : */
46 : : struct UserState {
47 : : uint128 balance;
48 : : uint128 additionalData;
49 : : }
50 : : // Map of users address and their state data (userAddress => userStateData)
51 : : mapping(address => UserState) internal _userState;
52 : :
53 : : // Map of allowances (delegator => delegatee => allowanceAmount)
54 : : mapping(address => mapping(address => uint256)) private _allowances;
55 : :
56 : : uint256 internal _totalSupply;
57 : : string private _name;
58 : : string private _symbol;
59 : : uint8 private _decimals;
60 : : IAaveIncentivesController internal _incentivesController;
61 : : IPoolAddressesProvider internal immutable _addressesProvider;
62 : : IPool public immutable POOL;
63 : :
64 : : /**
65 : : * @dev Constructor.
66 : : * @param pool The reference to the main Pool contract
67 : : * @param name_ The name of the token
68 : : * @param symbol_ The symbol of the token
69 : : * @param decimals_ The number of decimals of the token
70 : : */
71 : : constructor(IPool pool, string memory name_, string memory symbol_, uint8 decimals_) {
72 : 7197 : _addressesProvider = pool.ADDRESSES_PROVIDER();
73 : 15179 : _name = name_;
74 : 7139 : _symbol = symbol_;
75 : 7154 : _decimals = decimals_;
76 : 15111 : POOL = pool;
77 : : }
78 : :
79 : : /// @inheritdoc IERC20Detailed
80 : : function name() public view override returns (string memory) {
81 : 420799 : return _name;
82 : : }
83 : :
84 : : /// @inheritdoc IERC20Detailed
85 : : function symbol() external view override returns (string memory) {
86 : 81379 : return _symbol;
87 : : }
88 : :
89 : : /// @inheritdoc IERC20Detailed
90 : : function decimals() external view override returns (uint8) {
91 : 81163 : return _decimals;
92 : : }
93 : :
94 : : /// @inheritdoc IERC20
95 : : function totalSupply() public view virtual override returns (uint256) {
96 : 151623 : return _totalSupply;
97 : : }
98 : :
99 : : /// @inheritdoc IERC20
100 : : function balanceOf(address account) public view virtual override returns (uint256) {
101 : 339047 : return _userState[account].balance;
102 : : }
103 : :
104 : : /**
105 : : * @notice Returns the address of the Incentives Controller contract
106 : : * @return The address of the Incentives Controller
107 : : */
108 : : function getIncentivesController() external view virtual returns (IAaveIncentivesController) {
109 : 81148 : return _incentivesController;
110 : : }
111 : :
112 : : /**
113 : : * @notice Sets a new Incentives Controller
114 : : * @param controller the new Incentives controller
115 : : */
116 : : function setIncentivesController(IAaveIncentivesController controller) external onlyPoolAdmin {
117 : 1 : _incentivesController = controller;
118 : : }
119 : :
120 : : /// @inheritdoc IERC20
121 : : function transfer(address recipient, uint256 amount) external virtual override returns (bool) {
122 : 4018 : uint128 castAmount = amount.toUint128();
123 : 4017 : _transfer(_msgSender(), recipient, castAmount);
124 : 4016 : return true;
125 : : }
126 : :
127 : : /// @inheritdoc IERC20
128 : : function allowance(
129 : : address owner,
130 : : address spender
131 : : ) external view virtual override returns (uint256) {
132 : 26 : return _allowances[owner][spender];
133 : : }
134 : :
135 : : /// @inheritdoc IERC20
136 : : function approve(address spender, uint256 amount) external virtual override returns (bool) {
137 : 12021 : _approve(_msgSender(), spender, amount);
138 : 12021 : return true;
139 : : }
140 : :
141 : : /// @inheritdoc IERC20
142 : : function transferFrom(
143 : : address sender,
144 : : address recipient,
145 : : uint256 amount
146 : : ) external virtual override returns (bool) {
147 : 15025 : uint128 castAmount = amount.toUint128();
148 : 15025 : _approve(sender, _msgSender(), _allowances[sender][_msgSender()] - castAmount);
149 : 13025 : _transfer(sender, recipient, castAmount);
150 : 13025 : return true;
151 : : }
152 : :
153 : : /**
154 : : * @notice Increases the allowance of spender to spend _msgSender() tokens
155 : : * @param spender The user allowed to spend on behalf of _msgSender()
156 : : * @param addedValue The amount being added to the allowance
157 : : * @return `true`
158 : : */
159 : : function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool) {
160 : 4 : _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
161 : 4 : return true;
162 : : }
163 : :
164 : : /**
165 : : * @notice Decreases the allowance of spender to spend _msgSender() tokens
166 : : * @param spender The user allowed to spend on behalf of _msgSender()
167 : : * @param subtractedValue The amount being subtracted to the allowance
168 : : * @return `true`
169 : : */
170 : : function decreaseAllowance(
171 : : address spender,
172 : : uint256 subtractedValue
173 : : ) external virtual returns (bool) {
174 : 1 : _approve(_msgSender(), spender, _allowances[_msgSender()][spender] - subtractedValue);
175 : 1 : return true;
176 : : }
177 : :
178 : : /**
179 : : * @notice Transfers tokens between two users and apply incentives if defined.
180 : : * @param sender The source address
181 : : * @param recipient The destination address
182 : : * @param amount The amount getting transferred
183 : : */
184 : : function _transfer(address sender, address recipient, uint128 amount) internal virtual {
185 : 25056 : uint128 oldSenderBalance = _userState[sender].balance;
186 : 25056 : _userState[sender].balance = oldSenderBalance - amount;
187 : 25056 : uint128 oldRecipientBalance = _userState[recipient].balance;
188 : 25056 : _userState[recipient].balance = oldRecipientBalance + amount;
189 : :
190 : 25056 : IAaveIncentivesController incentivesControllerLocal = _incentivesController;
191 : 25056 : if (address(incentivesControllerLocal) != address(0)) {
192 : 25055 : uint256 currentTotalSupply = _totalSupply;
193 : 25055 : incentivesControllerLocal.handleAction(sender, currentTotalSupply, oldSenderBalance);
194 : 25055 : if (sender != recipient) {
195 : 25053 : incentivesControllerLocal.handleAction(recipient, currentTotalSupply, oldRecipientBalance);
196 : : }
197 : : }
198 : : }
199 : :
200 : : /**
201 : : * @notice Approve `spender` to use `amount` of `owner`s balance
202 : : * @param owner The address owning the tokens
203 : : * @param spender The address approved for spending
204 : : * @param amount The amount of tokens to approve spending of
205 : : */
206 : : function _approve(address owner, address spender, uint256 amount) internal virtual {
207 : 26061 : _allowances[owner][spender] = amount;
208 : 26061 : emit Approval(owner, spender, amount);
209 : : }
210 : :
211 : : /**
212 : : * @notice Update the name of the token
213 : : * @param newName The new name for the token
214 : : */
215 : : function _setName(string memory newName) internal {
216 : 339394 : _name = newName;
217 : : }
218 : :
219 : : /**
220 : : * @notice Update the symbol for the token
221 : : * @param newSymbol The new symbol for the token
222 : : */
223 : : function _setSymbol(string memory newSymbol) internal {
224 : 339394 : _symbol = newSymbol;
225 : : }
226 : :
227 : : /**
228 : : * @notice Update the number of decimals for the token
229 : : * @param newDecimals The new number of decimals for the token
230 : : */
231 : : function _setDecimals(uint8 newDecimals) internal {
232 : 339394 : _decimals = newDecimals;
233 : : }
234 : : }
|