2020-08-20 12:32:20 +00:00
|
|
|
// SPDX-License-Identifier: agpl-3.0
|
2020-11-20 10:41:58 +00:00
|
|
|
pragma solidity 0.6.12;
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-11-23 10:28:57 +00:00
|
|
|
import {Context} from '../../dependencies/openzeppelin/contracts/Context.sol';
|
|
|
|
import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
|
|
|
|
import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
|
|
|
|
import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol';
|
|
|
|
import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol';
|
2020-05-29 16:45:37 +00:00
|
|
|
|
|
|
|
/**
|
2020-09-04 14:27:35 +00:00
|
|
|
* @title ERC20
|
|
|
|
* @notice Basic ERC20 implementation
|
2020-09-15 12:36:02 +00:00
|
|
|
* @author Aave, inspired by the Openzeppelin ERC20 implementation
|
2020-09-04 14:27:35 +00:00
|
|
|
**/
|
2021-01-28 10:05:19 +00:00
|
|
|
abstract contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
|
2020-07-13 08:54:08 +00:00
|
|
|
using SafeMath for uint256;
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-09-15 12:36:02 +00:00
|
|
|
mapping(address => uint256) internal _balances;
|
2020-09-15 15:43:55 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
mapping(address => mapping(address => uint256)) private _allowances;
|
2020-09-15 12:36:02 +00:00
|
|
|
uint256 internal _totalSupply;
|
2020-09-04 14:27:35 +00:00
|
|
|
string private _name;
|
|
|
|
string private _symbol;
|
2020-07-13 08:54:08 +00:00
|
|
|
uint8 private _decimals;
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-09-04 14:27:35 +00:00
|
|
|
constructor(
|
|
|
|
string memory name,
|
|
|
|
string memory symbol,
|
2021-01-28 10:05:19 +00:00
|
|
|
uint8 decimals
|
2020-09-04 14:27:35 +00:00
|
|
|
) public {
|
2020-07-13 08:54:08 +00:00
|
|
|
_name = name;
|
|
|
|
_symbol = symbol;
|
2020-09-04 14:27:35 +00:00
|
|
|
_decimals = decimals;
|
2020-07-13 08:54:08 +00:00
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
/**
|
2020-11-26 09:21:18 +00:00
|
|
|
* @return The name of the token
|
2020-09-04 14:27:35 +00:00
|
|
|
**/
|
2020-11-23 10:28:57 +00:00
|
|
|
function name() public view override returns (string memory) {
|
2020-07-13 08:54:08 +00:00
|
|
|
return _name;
|
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
/**
|
2020-11-26 09:21:18 +00:00
|
|
|
* @return The symbol of the token
|
2020-09-04 14:27:35 +00:00
|
|
|
**/
|
2020-11-23 10:28:57 +00:00
|
|
|
function symbol() public view override returns (string memory) {
|
2020-07-13 08:54:08 +00:00
|
|
|
return _symbol;
|
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
/**
|
2020-11-26 09:21:18 +00:00
|
|
|
* @return The decimals of the token
|
2020-09-04 14:27:35 +00:00
|
|
|
**/
|
2020-11-23 10:28:57 +00:00
|
|
|
function decimals() public view override returns (uint8) {
|
2020-07-13 08:54:08 +00:00
|
|
|
return _decimals;
|
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
/**
|
2020-11-26 09:21:18 +00:00
|
|
|
* @return The total supply of the token
|
2020-09-04 14:27:35 +00:00
|
|
|
**/
|
2020-11-23 10:28:57 +00:00
|
|
|
function totalSupply() public view virtual override returns (uint256) {
|
2020-07-13 08:54:08 +00:00
|
|
|
return _totalSupply;
|
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
/**
|
2020-11-26 09:21:18 +00:00
|
|
|
* @return The balance of the token
|
2020-09-04 14:27:35 +00:00
|
|
|
**/
|
2020-11-23 10:28:57 +00:00
|
|
|
function balanceOf(address account) public view virtual override returns (uint256) {
|
2020-07-13 08:54:08 +00:00
|
|
|
return _balances[account];
|
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2021-01-28 10:05:19 +00:00
|
|
|
/**
|
|
|
|
* @return Abstract function implemented by the child aToken/debtToken.
|
|
|
|
* Done this way in order to not break compatibility with previous versions of aTokens/debtTokens
|
|
|
|
**/
|
|
|
|
function _getIncentivesController() internal view virtual returns(IAaveIncentivesController);
|
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
/**
|
2020-11-26 09:21:18 +00:00
|
|
|
* @dev Executes a transfer of tokens from _msgSender() to recipient
|
|
|
|
* @param recipient The recipient of the tokens
|
|
|
|
* @param amount The amount of tokens being transferred
|
|
|
|
* @return `true` if the transfer succeeds, `false` otherwise
|
2020-09-04 14:27:35 +00:00
|
|
|
**/
|
2020-07-13 08:54:08 +00:00
|
|
|
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
|
|
|
|
_transfer(_msgSender(), recipient, amount);
|
2020-10-27 13:42:11 +00:00
|
|
|
emit Transfer(_msgSender(), recipient, amount);
|
2020-07-13 08:54:08 +00:00
|
|
|
return true;
|
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
/**
|
2020-11-26 09:21:18 +00:00
|
|
|
* @dev Returns the allowance of spender on the tokens owned by owner
|
|
|
|
* @param owner The owner of the tokens
|
|
|
|
* @param spender The user allowed to spend the owner's tokens
|
|
|
|
* @return The amount of owner's tokens spender is allowed to spend
|
2020-09-04 14:27:35 +00:00
|
|
|
**/
|
2020-07-13 08:54:08 +00:00
|
|
|
function allowance(address owner, address spender)
|
|
|
|
public
|
2020-11-23 10:28:57 +00:00
|
|
|
view
|
2020-07-13 08:54:08 +00:00
|
|
|
virtual
|
|
|
|
override
|
|
|
|
returns (uint256)
|
|
|
|
{
|
|
|
|
return _allowances[owner][spender];
|
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
/**
|
2020-11-26 09:21:18 +00:00
|
|
|
* @dev Allows `spender` to spend the tokens owned by _msgSender()
|
|
|
|
* @param spender The user allowed to spend _msgSender() tokens
|
|
|
|
* @return `true`
|
2020-09-04 14:27:35 +00:00
|
|
|
**/
|
2020-07-13 08:54:08 +00:00
|
|
|
function approve(address spender, uint256 amount) public virtual override returns (bool) {
|
|
|
|
_approve(_msgSender(), spender, amount);
|
|
|
|
return true;
|
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
/**
|
2020-11-26 09:21:18 +00:00
|
|
|
* @dev Executes a transfer of token from sender to recipient, if _msgSender() is allowed to do so
|
|
|
|
* @param sender The owner of the tokens
|
|
|
|
* @param recipient The recipient of the tokens
|
|
|
|
* @param amount The amount of tokens being transferred
|
|
|
|
* @return `true` if the transfer succeeds, `false` otherwise
|
2020-09-04 14:27:35 +00:00
|
|
|
**/
|
2020-07-13 08:54:08 +00:00
|
|
|
function transferFrom(
|
|
|
|
address sender,
|
|
|
|
address recipient,
|
|
|
|
uint256 amount
|
|
|
|
) public virtual override returns (bool) {
|
|
|
|
_transfer(sender, recipient, amount);
|
|
|
|
_approve(
|
|
|
|
sender,
|
|
|
|
_msgSender(),
|
|
|
|
_allowances[sender][_msgSender()].sub(amount, 'ERC20: transfer amount exceeds allowance')
|
|
|
|
);
|
2020-09-15 12:36:02 +00:00
|
|
|
emit Transfer(sender, recipient, amount);
|
2020-07-13 08:54:08 +00:00
|
|
|
return true;
|
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
/**
|
2020-11-26 09:21:18 +00:00
|
|
|
* @dev Increases the allowance of spender to spend _msgSender() tokens
|
|
|
|
* @param spender The user allowed to spend on behalf of _msgSender()
|
|
|
|
* @param addedValue The amount being added to the allowance
|
|
|
|
* @return `true`
|
2020-09-04 14:27:35 +00:00
|
|
|
**/
|
2020-07-13 08:54:08 +00:00
|
|
|
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
|
|
|
|
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
|
|
|
|
return true;
|
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
/**
|
2020-11-26 09:21:18 +00:00
|
|
|
* @dev Decreases the allowance of spender to spend _msgSender() tokens
|
|
|
|
* @param spender The user allowed to spend on behalf of _msgSender()
|
|
|
|
* @param subtractedValue The amount being subtracted to the allowance
|
|
|
|
* @return `true`
|
2020-09-04 14:27:35 +00:00
|
|
|
**/
|
2020-07-13 08:54:08 +00:00
|
|
|
function decreaseAllowance(address spender, uint256 subtractedValue)
|
|
|
|
public
|
|
|
|
virtual
|
|
|
|
returns (bool)
|
|
|
|
{
|
|
|
|
_approve(
|
|
|
|
_msgSender(),
|
|
|
|
spender,
|
|
|
|
_allowances[_msgSender()][spender].sub(
|
|
|
|
subtractedValue,
|
|
|
|
'ERC20: decreased allowance below zero'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
return true;
|
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
function _transfer(
|
|
|
|
address sender,
|
|
|
|
address recipient,
|
|
|
|
uint256 amount
|
|
|
|
) internal virtual {
|
|
|
|
require(sender != address(0), 'ERC20: transfer from the zero address');
|
|
|
|
require(recipient != address(0), 'ERC20: transfer to the zero address');
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
_beforeTokenTransfer(sender, recipient, amount);
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-09-15 13:53:20 +00:00
|
|
|
uint256 oldSenderBalance = _balances[sender];
|
|
|
|
_balances[sender] = oldSenderBalance.sub(amount, 'ERC20: transfer amount exceeds balance');
|
|
|
|
uint256 oldRecipientBalance = _balances[recipient];
|
2020-07-13 08:54:08 +00:00
|
|
|
_balances[recipient] = _balances[recipient].add(amount);
|
2020-09-15 13:53:20 +00:00
|
|
|
|
2021-01-28 10:05:19 +00:00
|
|
|
if (address(_getIncentivesController()) != address(0)) {
|
2020-10-27 12:04:07 +00:00
|
|
|
uint256 currentTotalSupply = _totalSupply;
|
2021-01-28 10:05:19 +00:00
|
|
|
_getIncentivesController().handleAction(sender, currentTotalSupply, oldSenderBalance);
|
2020-09-15 14:49:53 +00:00
|
|
|
if (sender != recipient) {
|
2021-01-28 10:05:19 +00:00
|
|
|
_getIncentivesController().handleAction(recipient, currentTotalSupply, oldRecipientBalance);
|
2020-09-15 14:49:53 +00:00
|
|
|
}
|
2020-09-15 13:53:20 +00:00
|
|
|
}
|
2020-07-13 08:54:08 +00:00
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
function _mint(address account, uint256 amount) internal virtual {
|
|
|
|
require(account != address(0), 'ERC20: mint to the zero address');
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
_beforeTokenTransfer(address(0), account, amount);
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-09-15 13:53:20 +00:00
|
|
|
uint256 oldTotalSupply = _totalSupply;
|
|
|
|
_totalSupply = oldTotalSupply.add(amount);
|
|
|
|
|
|
|
|
uint256 oldAccountBalance = _balances[account];
|
|
|
|
_balances[account] = oldAccountBalance.add(amount);
|
|
|
|
|
2021-01-28 10:05:19 +00:00
|
|
|
if (address(_getIncentivesController()) != address(0)) {
|
|
|
|
_getIncentivesController().handleAction(account, oldTotalSupply, oldAccountBalance);
|
2020-09-15 13:53:20 +00:00
|
|
|
}
|
2020-07-13 08:54:08 +00:00
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
function _burn(address account, uint256 amount) internal virtual {
|
|
|
|
require(account != address(0), 'ERC20: burn from the zero address');
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
_beforeTokenTransfer(account, address(0), amount);
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-09-15 13:53:20 +00:00
|
|
|
uint256 oldTotalSupply = _totalSupply;
|
|
|
|
_totalSupply = oldTotalSupply.sub(amount);
|
|
|
|
|
|
|
|
uint256 oldAccountBalance = _balances[account];
|
|
|
|
_balances[account] = oldAccountBalance.sub(amount, 'ERC20: burn amount exceeds balance');
|
|
|
|
|
2021-01-28 10:05:19 +00:00
|
|
|
if (address(_getIncentivesController()) != address(0)) {
|
|
|
|
_getIncentivesController().handleAction(account, oldTotalSupply, oldAccountBalance);
|
2020-09-15 13:53:20 +00:00
|
|
|
}
|
2020-07-13 08:54:08 +00:00
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
function _approve(
|
|
|
|
address owner,
|
|
|
|
address spender,
|
|
|
|
uint256 amount
|
|
|
|
) internal virtual {
|
|
|
|
require(owner != address(0), 'ERC20: approve from the zero address');
|
|
|
|
require(spender != address(0), 'ERC20: approve to the zero address');
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
_allowances[owner][spender] = amount;
|
|
|
|
emit Approval(owner, spender, amount);
|
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-09-04 14:27:35 +00:00
|
|
|
function _setName(string memory newName) internal {
|
|
|
|
_name = newName;
|
|
|
|
}
|
|
|
|
|
|
|
|
function _setSymbol(string memory newSymbol) internal {
|
|
|
|
_symbol = newSymbol;
|
|
|
|
}
|
|
|
|
|
|
|
|
function _setDecimals(uint8 newDecimals) internal {
|
|
|
|
_decimals = newDecimals;
|
2020-07-13 08:54:08 +00:00
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
function _beforeTokenTransfer(
|
|
|
|
address from,
|
|
|
|
address to,
|
|
|
|
uint256 amount
|
|
|
|
) internal virtual {}
|
2020-05-29 16:45:37 +00:00
|
|
|
}
|