Description:
ERC20 token contract with Mintable, Burnable, Pausable capabilities. Standard implementation for fungible tokens on Ethereum.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{"Blacklistable.sol":{"content":"// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;
import {Ownable} from "./Ownable.sol";
abstract contract Blacklistable is Ownable {
address private _blacklister;
mapping(address =\u003e bool) internal _blacklisted;
event Blacklisted(address indexed _address);
event UnBlacklisted(address indexed _address);
event BlacklisterChanged(address indexed newBlacklister);
event BlackFundsDestroyed(address _blackListedUser, uint _balance);
modifier onlyBlacklister() {
require(
msg.sender == _blacklister,
"Blacklistable: caller is not the blacklister"
);
_;
}
modifier notBlacklisted(address _address) {
require(
!_blacklisted[_address],
"Blacklistable: address is blacklisted"
);
_;
}
constructor(address initialBlacklister) {
setBlacklister(initialBlacklister);
}
function blacklister() external view returns (address) {
return _blacklister;
}
function isBlacklisted(address _address) external view returns (bool) {
return _blacklisted[_address];
}
function blacklist(
address _address
) external onlyBlacklister returns (bool) {
_blacklisted[_address] = true;
emit Blacklisted(_address);
return true;
}
function unBlacklist(
address _address
) external onlyBlacklister returns (bool) {
_blacklisted[_address] = false;
emit UnBlacklisted(_address);
return true;
}
function setBlacklister(address newBlacklister) internal {
require(
newBlacklister != address(0),
"Blacklistable: new blacklister is the zero address"
);
_blacklister = newBlacklister;
}
function updateBlacklister(
address newBlacklister
) public onlyOwner returns (bool) {
setBlacklister(newBlacklister);
emit BlacklisterChanged(_blacklister);
return true;
}
function destroyBlackFunds(
address blacklistedAddress
) external virtual returns (bool);
}
"},"ERC20.sol":{"content":"// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;
import {Ownable} from "./Ownable.sol";
abstract contract ERC20 is Ownable {
string private _name;
string private _symbol;
uint8 private _decimals;
string private _currency;
uint internal _totalSupply;
mapping(address =\u003e uint) internal _balances;
mapping(address =\u003e mapping(address =\u003e uint)) internal _allowances;
uint public basisPointsRate;
uint public maximumFee;
uint public constant MAX_UINT = 2 ** 256 - 1;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
event ParamsUpdated(uint feeBasisPoints, uint maxFee);
constructor(
string memory name_,
string memory symbol_,
uint8 decimals_,
string memory currency_
) {
_name = name_;
_symbol = symbol_;
_decimals = decimals_;
_currency = currency_;
_totalSupply = 0;
basisPointsRate = 0;
maximumFee = 0;
}
function name() external view virtual returns (string memory) {
return _name;
}
function symbol() external view virtual returns (string memory) {
return _symbol;
}
function decimals() external view virtual returns (uint8) {
return _decimals;
}
function currency() external view returns (string memory) {
return _currency;
}
function totalSupply() public view virtual returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual returns (uint256) {
return _balances[account];
}
function allowance(
address owner,
address spender
) public view virtual returns (uint256) {
return _allowances[owner][spender];
}
function transfer(address to, uint256 value) public virtual returns (bool) {
require(to != address(0), "ERC20: transfer to the zero address");
require(_balances[msg.sender] \u003e= value, "ERC20: insufficient balance");
uint fee = (value * basisPointsRate) / 10000;
if (fee \u003e maximumFee) {
fee = maximumFee;
}
uint sendAmount = value - fee;
_balances[msg.sender] -= value;
_balances[to] += sendAmount;
if (fee \u003e 0) {
_balances[_owner] += fee;
emit Transfer(msg.sender, _owner, fee);
}
emit Transfer(msg.sender, to, sendAmount);
return true;
}
function approve(
address spender,
uint256 value
) public virtual returns (bool) {
require(spender != address(0), "ERC20: approve from the zero address");
_allowances[msg.sender][spender] = value;
emit Approval(msg.sender, spender, value);
return true;
}
function transferFrom(
address from,
address to,
uint256 value
) public virtual returns (bool) {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
require(_balances[from] \u003e= value, "ERC20: insufficient balance");
require(
_allowances[from][msg.sender] \u003e= value,
"ERC20: Insufficient allowance"
);
uint fee = (value * basisPointsRate) / 10000;
if (fee \u003e maximumFee) {
fee = maximumFee;
}
uint sendAmount = value - fee;
if (_allowances[from][msg.sender] \u003c MAX_UINT) {
_allowances[from][msg.sender] -= value;
}
_balances[from] -= value;
_balances[to] += sendAmount;
if (fee \u003e 0) {
_balances[_owner] += fee;
emit Transfer(from, _owner, fee);
}
emit Transfer(from, to, sendAmount);
return true;
}
function mint(
address _recipient,
uint256 value
) external virtual returns (bool);
function burn(uint256 value) external virtual returns (bool);
function setParams(
uint newBasisPoints,
uint newMaxFee
) public onlyOwner returns (bool) {
require(newBasisPoints \u003c= 100, "ERC20: value exceeds maximum (100)");
require(newMaxFee \u003c= 1000, "ERC20: value exceeds maximum (1000)");
basisPointsRate = newBasisPoints;
maximumFee = newMaxFee * (10 ** _decimals);
emit ParamsUpdated(basisPointsRate, maximumFee);
return true;
}
}
"},"MyRUB.sol":{"content":"// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;
import {Ownable} from "./Ownable.sol";
import {Pausable} from "./Pausable.sol";
import {Blacklistable} from "./Blacklistable.sol";
import {ERC20} from "./ERC20.sol";
contract MyRUB is Ownable, Pausable, Blacklistable, ERC20 {
mapping(address =\u003e bool) internal _minters;
mapping(address =\u003e uint256) internal _minterAllowed;
address public masterMinter;
event Mint(address indexed minter, address indexed to, uint256 amount);
event Burn(address indexed burner, uint256 amount);
event MinterConfigured(address indexed minter, uint256 minterAllowedAmount);
event MinterRemoved(address indexed oldMinter);
event MasterMinterChanged(address indexed newMasterMinter);
modifier onlyMasterMinter() {
require(
msg.sender == masterMinter,
"MyRUB: caller is not the masterMinter"
);
_;
}
modifier onlyMinters() {
require(_minters[msg.sender], "MyRUB: caller is not a minter");
_;
}
constructor(
string memory name_,
string memory symbol_,
string memory currency_,
uint8 decimals_,
address initialOwner,
address initialPauser,
address initialBlacklister,
address initialMasterMinter
)
ERC20(name_, symbol_, decimals_, currency_)
Ownable(initialOwner)
Pausable(initialPauser)
Blacklistable(initialBlacklister)
{
require(
initialMasterMinter != address(0),
"MyRUB: initialMasterMinter is the zero address"
);
masterMinter = initialMasterMinter;
}
function isMinter(address _address) external view returns (bool) {
return _minters[_address];
}
function minterAllowance(address minter) external view returns (uint256) {
return _minterAllowed[minter];
}
function configureMinter(
address minter,
uint256 minterAllowedAmount
) external notPaused onlyMasterMinter returns (bool) {
_minters[minter] = true;
_minterAllowed[minter] = minterAllowedAmount;
emit MinterConfigured(minter, minterAllowedAmount);
return true;
}
function removeMinter(
address minter
) external onlyMasterMinter returns (bool) {
_minters[minter] = false;
_minterAllowed[minter] = 0;
emit MinterRemoved(minter);
return true;
}
function updateMasterMinter(
address newMasterMinter
) external onlyOwner returns (bool) {
require(
newMasterMinter != address(0),
"MyRUB: new masterMinter is the zero address"
);
masterMinter = newMasterMinter;
emit MasterMinterChanged(masterMinter);
return true;
}
function balanceOf(address account) public view override returns (uint256) {
return super.balanceOf(account);
}
function totalSupply() public view override returns (uint256) {
return super.totalSupply();
}
function allowance(
address owner,
address spender
) public view override returns (uint256) {
return super.allowance(owner, spender);
}
function transfer(
address to,
uint value
)
public
override
notPaused
notBlacklisted(msg.sender)
notBlacklisted(to)
returns (bool success)
{
return super.transfer(to, value);
}
function approve(
address spender,
uint value
)
public
override
notPaused
notBlacklisted(msg.sender)
notBlacklisted(spender)
returns (bool success)
{
return super.approve(spender, value);
}
function transferFrom(
address from,
address to,
uint value
)
public
override
notPaused
notBlacklisted(msg.sender)
notBlacklisted(from)
notBlacklisted(to)
returns (bool success)
{
return super.transferFrom(from, to, value);
}
function mint(
address _recipient,
uint256 _value
)
external
override
notPaused
onlyMinters
notBlacklisted(msg.sender)
notBlacklisted(_recipient)
returns (bool)
{
require(_recipient != address(0), "MyRUB: mint to the zero address");
require(_value \u003e 0, "MyRUB: mint amount not greater than 0");
require(
_value \u003c= _minterAllowed[msg.sender],
"MyRUB: mint amount exceeds minterAllowance"
);
_totalSupply += _value;
_balances[_recipient] += _value;
_minterAllowed[msg.sender] -= _value;
emit Mint(msg.sender, _recipient, _value);
emit Transfer(address(0), _recipient, _value);
return true;
}
function burn(
uint256 value
)
external
override
notPaused
onlyMinters
notBlacklisted(msg.sender)
returns (bool)
{
uint256 balance = balanceOf(msg.sender);
require(value \u003e 0, "MyRUB: burn amount not greater than 0");
require(balance \u003e= value, "MyRUB: burn amount exceeds balance");
_totalSupply -= value;
_balances[msg.sender] = balance - value;
emit Burn(msg.sender, value);
emit Transfer(msg.sender, address(0), value);
return true;
}
function destroyBlackFunds(
address blacklistedAddress
) external override onlyOwner returns (bool) {
require(
_blacklisted[blacklistedAddress],
"MyRUB: address isn\u0027t blacklisted"
);
uint dirtyFunds = balanceOf(blacklistedAddress);
_balances[blacklistedAddress] = 0;
_totalSupply -= dirtyFunds;
emit BlackFundsDestroyed(blacklistedAddress, dirtyFunds);
return true;
}
function getVersion() external pure virtual returns (uint256) {
return 1;
}
}
"},"Ownable.sol":{"content":"// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;
contract Ownable {
address internal _owner;
event OwnerChanged(address previousOwner, address newOwner);
modifier onlyOwner() {
require(msg.sender == _owner, \u0027Ownable: caller is not the owner\u0027);
_;
}
constructor(address initialOwner) {
setOwner(initialOwner);
}
function owner() external view returns (address) {
return _owner;
}
function setOwner(address newOwner) internal {
require(newOwner != address(0), \u0027Ownable: new owner is the zero address\u0027);
_owner = newOwner;
}
function updateOwner(address newOwner) external onlyOwner returns (bool) {
address oldOwner = _owner;
setOwner(newOwner);
emit OwnerChanged(oldOwner, newOwner);
return true;
}
}"},"Pausable.sol":{"content":"// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;
import { Ownable } from \u0027./Ownable.sol\u0027;
abstract contract Pausable is Ownable {
bool public paused;
address private _pauser;
event Paused();
event Unpaused();
event PauserChanged(address indexed newAddress);
modifier notPaused() {
require(!paused, \u0027Pausable: is paused\u0027);
_;
}
modifier isPaused() {
require(paused, "Pausable: isn\u0027t paused");
_;
}
modifier onlyPauser() {
require(msg.sender == _pauser, \u0027Pausable: caller is not the pauser\u0027);
_;
}
constructor(address initialPauser) {
paused = false;
setPauser(initialPauser);
}
function pauser() external view returns (address) {
return _pauser;
}
function pause() external notPaused onlyPauser returns (bool) {
paused = true;
emit Paused();
return true;
}
function unpause() external isPaused onlyPauser returns (bool) {
paused = false;
emit Unpaused();
return true;
}
function setPauser(address newPauser) internal {
require(newPauser != address(0), \u0027Pausable: new pauser is the zero address\u0027);
_pauser = newPauser;
}
function updatePauser(address newPauser) public onlyOwner returns (bool) {
setPauser(newPauser);
emit PauserChanged(_pauser);
return true;
}
}"}}
Submitted on: 2025-10-14 19:14:57
Comments
Log in to comment.
No comments yet.