152 lines
4.7 KiB
Solidity
152 lines
4.7 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
|
|
pragma solidity 0.8.19;
|
|
|
|
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
import {IMintable} from "../../interfaces/IMintable.sol";
|
|
import {Governable} from "../../core/Governable.sol";
|
|
|
|
contract EsToken2 is IERC20, IMintable, Governable {
|
|
using SafeERC20 for IERC20;
|
|
|
|
string public name;
|
|
string public symbol;
|
|
uint8 public decimals = 18;
|
|
|
|
uint256 public override totalSupply;
|
|
bool public inPrivateTransferMode;
|
|
|
|
mapping(address => uint256) public balances;
|
|
mapping(address => mapping(address => uint256)) public allowances;
|
|
mapping(address => bool) public nonStakingAccounts;
|
|
mapping(address => bool) public admins;
|
|
|
|
mapping(address => bool) public override isMinter;
|
|
|
|
mapping(address => bool) public isHandler;
|
|
|
|
constructor(string memory _name, string memory _symbol) {
|
|
name = _name;
|
|
symbol = _symbol;
|
|
}
|
|
|
|
modifier onlyMinter() {
|
|
require(isMinter[msg.sender], "EsToken: forbidden");
|
|
_;
|
|
}
|
|
|
|
modifier onlyAdmin() {
|
|
require(admins[msg.sender], "BaseToken: forbidden");
|
|
_;
|
|
}
|
|
|
|
function setMinter(address _minter, bool _isActive) external override onlyGov {
|
|
isMinter[_minter] = _isActive;
|
|
}
|
|
|
|
function addAdmin(address _account) external onlyGov {
|
|
admins[_account] = true;
|
|
}
|
|
|
|
function removeAdmin(address _account) external onlyGov {
|
|
admins[_account] = false;
|
|
}
|
|
|
|
function mint(address _account, uint256 _amount) external override onlyMinter {
|
|
_mint(_account, _amount);
|
|
}
|
|
|
|
function burn(address _account, uint256 _amount) external override onlyMinter {
|
|
_burn(_account, _amount);
|
|
}
|
|
|
|
function setInPrivateTransferMode(bool _inPrivateTransferMode) external onlyGov {
|
|
inPrivateTransferMode = _inPrivateTransferMode;
|
|
}
|
|
|
|
function setHandler(address _handler, bool _isActive) external onlyGov {
|
|
isHandler[_handler] = _isActive;
|
|
}
|
|
|
|
function balanceOf(address _account) external view override returns (uint256) {
|
|
return balances[_account];
|
|
}
|
|
|
|
function stakedBalance(address _account) external view returns (uint256) {
|
|
if (nonStakingAccounts[_account]) {
|
|
return 0;
|
|
}
|
|
return balances[_account];
|
|
}
|
|
|
|
function transfer(address _recipient, uint256 _amount) external override returns (bool) {
|
|
_transfer(msg.sender, _recipient, _amount);
|
|
return true;
|
|
}
|
|
|
|
function allowance(address _owner, address _spender) external view override returns (uint256) {
|
|
return allowances[_owner][_spender];
|
|
}
|
|
|
|
function approve(address _spender, uint256 _amount) external override returns (bool) {
|
|
_approve(msg.sender, _spender, _amount);
|
|
return true;
|
|
}
|
|
|
|
function transferFrom(address _sender, address _recipient, uint256 _amount) external override returns (bool) {
|
|
if (isHandler[msg.sender]) {
|
|
_transfer(_sender, _recipient, _amount);
|
|
return true;
|
|
}
|
|
require(allowances[_sender][msg.sender] >= _amount, "EsToken: transfer amount exceeds allowance");
|
|
uint256 nextAllowance = allowances[_sender][msg.sender] - _amount;
|
|
_approve(_sender, msg.sender, nextAllowance);
|
|
_transfer(_sender, _recipient, _amount);
|
|
return true;
|
|
}
|
|
|
|
function _mint(address _account, uint256 _amount) internal {
|
|
require(_account != address(0), "EsToken: mint to the zero address");
|
|
|
|
totalSupply = totalSupply + _amount;
|
|
balances[_account] = balances[_account] + _amount;
|
|
|
|
emit Transfer(address(0), _account, _amount);
|
|
}
|
|
|
|
function _burn(address _account, uint256 _amount) internal {
|
|
require(_account != address(0), "EsToken: burn from the zero address");
|
|
|
|
require(balances[_account] >= _amount, "EsToken: burn amount exceeds balance");
|
|
balances[_account] = balances[_account] - _amount;
|
|
totalSupply = totalSupply - _amount;
|
|
|
|
emit Transfer(_account, address(0), _amount);
|
|
}
|
|
|
|
function _transfer(address _sender, address _recipient, uint256 _amount) private {
|
|
require(_sender != address(0), "EsToken: transfer from the zero address");
|
|
require(_recipient != address(0), "EsToken: transfer to the zero address");
|
|
|
|
if (inPrivateTransferMode) {
|
|
require(isHandler[msg.sender], "EsToken: msg.sender not whitelisted");
|
|
}
|
|
|
|
require(balances[_sender] >= _amount, "EsToken: transfer amount exceeds balance");
|
|
balances[_sender] = balances[_sender] - _amount;
|
|
balances[_recipient] = balances[_recipient] + _amount;
|
|
|
|
emit Transfer(_sender, _recipient, _amount);
|
|
}
|
|
|
|
function _approve(address _owner, address _spender, uint256 _amount) private {
|
|
require(_owner != address(0), "EsToken: approve from the zero address");
|
|
require(_spender != address(0), "EsToken: approve to the zero address");
|
|
|
|
allowances[_owner][_spender] = _amount;
|
|
|
|
emit Approval(_owner, _spender, _amount);
|
|
}
|
|
}
|