2024-08-27 15:13:22 +08:00

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);
}
}