Contract Name:
EmoliumToken
Contract Source Code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./sources/OZ/ERC20.sol";
import "./sources/OZ/Ownable.sol";
import "./sources/OZ/ERC20Burnable.sol";
import "./sources/OZ/Pausable.sol";
contract EmoliumToken is ERC20, ERC20Burnable, Ownable, Pausable {
uint256 public initialSupply = 0 * 10**18;
string public constant tokenName = "Emolium";
string public constant tokenSymbol = "EML";
// Mapping for authorized minters and burners
mapping(address => bool) public authorizedMinters;
mapping(address => bool) public authorizedBurners;
// Mapping to store registered blockchains with a string ID
mapping(string => string) public blockchainRegistry;
// Variable to store the Chief Validator address
address public chiefValidator;
// Reward amount per proof
uint256 public rewardPerProof;
event MinterAdded(address indexed minter);
event MinterRemoved(address indexed minter);
event BurnerAdded(address indexed burner);
event BurnerRemoved(address indexed burner);
event BlockchainRegistered(string indexed chainId, string chainName);
event ChiefValidatorSet(address indexed chiefValidator);
event RewardPerProofUpdated(uint256 rewardPerProof);
// The constructor takes the initial owner address and calls the Ownable constructor
constructor(address initialOwner) ERC20(tokenName, tokenSymbol) Ownable(initialOwner) {
_mint(initialOwner, initialSupply);
transferOwnership(initialOwner);
}
// Modifier to limit access to authorized minters
modifier onlyAuthorizedMinter() {
require(authorizedMinters[msg.sender], "Not an authorized minter");
_;
}
// Modifier to limit access to authorized burners
modifier onlyAuthorizedBurner() {
require(authorizedBurners[msg.sender], "Not an authorized burner");
_;
}
// Function to add an authorized minter
function addMinter(address minter) external onlyOwner {
authorizedMinters[minter] = true;
emit MinterAdded(minter);
}
// Function to remove an authorized minter
function removeMinter(address minter) external onlyOwner {
authorizedMinters[minter] = false;
emit MinterRemoved(minter);
}
// Function to add an authorized burner
function addBurner(address burner) external onlyOwner {
authorizedBurners[burner] = true;
emit BurnerAdded(burner);
}
// Function to remove an authorized burner
function removeBurner(address burner) external onlyOwner {
authorizedBurners[burner] = false;
emit BurnerRemoved(burner);
}
// Function to mint for authorized minters
function mint(address to, uint256 amount) external onlyAuthorizedMinter whenNotPaused {
_mint(to, amount);
}
// Function to burn for authorized burners
function burn(uint256 amount) public override onlyAuthorizedBurner whenNotPaused {
super.burn(amount);
}
// Function to burnFrom for authorized burners
function burnFrom(address account, uint256 amount) public override onlyAuthorizedBurner whenNotPaused {
super.burnFrom(account, amount);
}
// Function to register a blockchain with its ID and name
function registerBlockchain(string calldata id, string calldata chainName) external onlyOwner whenNotPaused {
blockchainRegistry[id] = chainName;
emit BlockchainRegistered(id, chainName);
}
// Function to get the name of a registered blockchain from its ID
function getBlockchainById(string calldata id) external view returns (string memory) {
return blockchainRegistry[id];
}
// Function to set the Chief Validator address
function setChiefValidator(address _chiefValidator) external onlyOwner {
chiefValidator = _chiefValidator;
emit ChiefValidatorSet(_chiefValidator);
}
// Function to get the Chief Validator address
function getChiefValidator() external view returns (address) {
return chiefValidator;
}
// Function to set the reward amount per proof
function setRewardPerProof(uint256 _rewardPerProof) external onlyOwner {
rewardPerProof = _rewardPerProof;
emit RewardPerProofUpdated(_rewardPerProof);
}
// Function to get the reward amount per proof
function getRewardPerProof() external view returns (uint256) {
return rewardPerProof;
}
// Function to pause the contract
function pause() external onlyOwner {
_pause();
}
// Function to unpause the contract
function unpause() external onlyOwner {
_unpause();
}
// Override transfer to include pause check
function transfer(address recipient, uint256 amount) public override whenNotPaused returns (bool) {
return super.transfer(recipient, amount);
}
// Override transferFrom to include pause check
function transferFrom(address sender, address recipient, uint256 amount) public override whenNotPaused returns (bool) {
return super.transferFrom(sender, recipient, amount);
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)
pragma solidity ^0.8.20;
import {Context} from "./Context.sol";
abstract contract Pausable is Context {
bool private _paused;
event Paused(address account);
event Unpaused(address account);
error EnforcedPause();
error ExpectedPause();
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
if (paused()) {
revert EnforcedPause();
}
}
function _requirePaused() internal view virtual {
if (!paused()) {
revert ExpectedPause();
}
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Burnable.sol)
pragma solidity ^0.8.20;
import "./ERC20.sol";
import "./Context.sol";
abstract contract ERC20Burnable is Context, ERC20 {
function burn(uint256 value) public virtual {
_burn(_msgSender(), value);
}
function burnFrom(address account, uint256 value) public virtual {
_spendAllowance(account, _msgSender(), value);
_burn(account, value);
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import "./Context.sol";
abstract contract Ownable is Context {
address private _owner;
error OwnableUnauthorizedAccount(address account);
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.20;
import "./IERC20.sol";
import "./IERC20Metadata.sol";
import "./Context.sol";
import "./draft-IERC6093.sol";
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
mapping(address account => uint256) private _balances;
mapping(address account => mapping(address spender => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function name() public view virtual returns (string memory) {
return _name;
}
function symbol() public view virtual returns (string memory) {
return _symbol;
}
function decimals() public view virtual returns (uint8) {
return 18;
}
function totalSupply() public view virtual returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual returns (uint256) {
return _balances[account];
}
function transfer(address to, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_transfer(owner, to, value);
return true;
}
function allowance(address owner, address spender) public view virtual returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, value);
return true;
}
function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, value);
_transfer(from, to, value);
return true;
}
function _transfer(address from, address to, uint256 value) internal {
if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (to == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(from, to, value);
}
function _update(address from, address to, uint256 value) internal virtual {
if (from == address(0)) {
_totalSupply += value;
} else {
uint256 fromBalance = _balances[from];
if (fromBalance < value) {
revert ERC20InsufficientBalance(from, fromBalance, value);
}
unchecked {
_balances[from] = fromBalance - value;
}
}
if (to == address(0)) {
unchecked {
_totalSupply -= value;
}
} else {
unchecked {
_balances[to] += value;
}
}
emit Transfer(from, to, value);
}
function _mint(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(address(0), account, value);
}
function _burn(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidSender(address(0));
}
_update(account, address(0), value);
}
function _approve(address owner, address spender, uint256 value) internal {
_approve(owner, spender, value, true);
}
function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
if (owner == address(0)) {
revert ERC20InvalidApprover(address(0));
}
if (spender == address(0)) {
revert ERC20InvalidSpender(address(0));
}
_allowances[owner][spender] = value;
if (emitEvent) {
emit Approval(owner, spender, value);
}
}
function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
if (currentAllowance < value) {
revert ERC20InsufficientAllowance(spender, currentAllowance, value);
}
unchecked {
_approve(owner, spender, currentAllowance - value, false);
}
}
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;
interface IERC20Errors {
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
error ERC20InvalidSender(address sender);
error ERC20InvalidReceiver(address receiver);
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
error ERC20InvalidApprover(address approver);
error ERC20InvalidSpender(address spender);
}
interface IERC721Errors {
error ERC721InvalidOwner(address owner);
error ERC721NonexistentToken(uint256 tokenId);
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
error ERC721InvalidSender(address sender);
error ERC721InvalidReceiver(address receiver);
error ERC721InsufficientApproval(address operator, uint256 tokenId);
error ERC721InvalidApprover(address approver);
error ERC721InvalidOperator(address operator);
}
interface IERC1155Errors {
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
error ERC1155InvalidSender(address sender);
error ERC1155InvalidReceiver(address receiver);
error ERC1155MissingApprovalForAll(address operator, address owner);
error ERC1155InvalidApprover(address approver);
error ERC1155InvalidOperator(address operator);
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.20;
import "./IERC20.sol";
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}