aave-protocol-v2/contracts/tokenization/IncentivizedERC20.sol

254 lines
7.6 KiB
Solidity
Raw Normal View History

// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.6.8;
2020-10-15 13:25:27 +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';
2020-09-15 13:53:20 +00:00
import {IAaveIncentivesController} from '../interfaces/IAaveIncentivesController.sol';
/**
* @title ERC20
* @notice Basic ERC20 implementation
2020-09-15 12:36:02 +00:00
* @author Aave, inspired by the Openzeppelin ERC20 implementation
**/
2020-09-15 15:08:28 +00:00
contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
2020-07-13 08:54:08 +00:00
using SafeMath for uint256;
2020-09-15 13:53:20 +00:00
IAaveIncentivesController internal immutable _incentivesController;
2020-09-15 12:36:02 +00:00
mapping(address => uint256) internal _balances;
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;
string private _name;
string private _symbol;
2020-07-13 08:54:08 +00:00
uint8 private _decimals;
constructor(
string memory name,
string memory symbol,
2020-09-15 13:53:20 +00:00
uint8 decimals,
address incentivesController
) public {
2020-07-13 08:54:08 +00:00
_name = name;
_symbol = symbol;
_decimals = decimals;
2020-09-15 13:53:20 +00:00
_incentivesController = IAaveIncentivesController(incentivesController);
2020-07-13 08:54:08 +00:00
}
2020-07-13 08:54:08 +00:00
/**
* @return the name of the token
**/
function name() public override view returns (string memory) {
2020-07-13 08:54:08 +00:00
return _name;
}
2020-07-13 08:54:08 +00:00
/**
* @return the symbol of the token
**/
function symbol() public override view returns (string memory) {
2020-07-13 08:54:08 +00:00
return _symbol;
}
2020-07-13 08:54:08 +00:00
/**
* @return the decimals of the token
**/
function decimals() public override view returns (uint8) {
2020-07-13 08:54:08 +00:00
return _decimals;
}
2020-07-13 08:54:08 +00:00
/**
* @return the total supply of the token
**/
2020-07-13 08:54:08 +00:00
function totalSupply() public virtual override view returns (uint256) {
return _totalSupply;
}
2020-07-13 08:54:08 +00:00
/**
* @return the balance of the token
**/
2020-07-13 08:54:08 +00:00
function balanceOf(address account) public virtual override view returns (uint256) {
return _balances[account];
}
2020-07-13 08:54:08 +00:00
/**
2020-10-27 13:42:11 +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-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-07-13 08:54:08 +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-07-13 08:54:08 +00:00
function allowance(address owner, address spender)
public
virtual
override
view
returns (uint256)
{
return _allowances[owner][spender];
}
2020-07-13 08:54:08 +00:00
/**
2020-10-27 13:42:11 +00:00
* @dev allows spender to spend the tokens owned by _msgSender()
* @param spender the user allowed to spend _msgSender() tokens
* @return true
**/
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-07-13 08:54:08 +00:00
/**
2020-10-27 13:42:11 +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-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-07-13 08:54:08 +00:00
/**
2020-10-27 13:42:11 +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-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-07-13 08:54:08 +00:00
/**
2020-10-27 13:42:11 +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-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-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-07-13 08:54:08 +00:00
_beforeTokenTransfer(sender, recipient, amount);
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
2020-09-15 14:40:40 +00:00
if (address(_incentivesController) != address(0)) {
uint256 currentTotalSupply = _totalSupply;
_incentivesController.handleAction(sender, currentTotalSupply, oldSenderBalance);
if (sender != recipient) {
_incentivesController.handleAction(recipient, currentTotalSupply, oldRecipientBalance);
}
2020-09-15 13:53:20 +00:00
}
2020-07-13 08:54:08 +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-07-13 08:54:08 +00:00
_beforeTokenTransfer(address(0), account, amount);
2020-09-15 13:53:20 +00:00
uint256 oldTotalSupply = _totalSupply;
_totalSupply = oldTotalSupply.add(amount);
uint256 oldAccountBalance = _balances[account];
_balances[account] = oldAccountBalance.add(amount);
2020-09-15 14:40:40 +00:00
if (address(_incentivesController) != address(0)) {
2020-09-15 13:53:20 +00:00
_incentivesController.handleAction(account, oldTotalSupply, oldAccountBalance);
}
2020-07-13 08:54:08 +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-07-13 08:54:08 +00:00
_beforeTokenTransfer(account, address(0), amount);
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');
2020-09-15 14:40:40 +00:00
if (address(_incentivesController) != address(0)) {
2020-09-15 13:53:20 +00:00
_incentivesController.handleAction(account, oldTotalSupply, oldAccountBalance);
}
2020-07-13 08:54:08 +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-07-13 08:54:08 +00:00
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
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-07-13 08:54:08 +00:00
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}