OpMev

Description:

ERC20 token contract with Burnable, Factory capabilities. Standard implementation for fungible tokens on Ethereum.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "src/OpMev.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

import {ERC20} from "@superopevm/contracts/token/ERC20/ERC20.sol";
import {ERC20Burnable} from "@superopevm/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import {ERC20PermitWithSignatureChecker} from "@superopevm/contracts/token/ERC20/extensions/ERC20PermitWithSignatureChecker.sol";

/**
 * @title OpMev
 * @dev ERC20 token Custom SuperOpMev
 */
contract OpMev is ERC20, ERC20Burnable, ERC20PermitWithSignatureChecker {
    constructor(uint256 initialSupply) 
        ERC20("Op Mev", "OV")
        ERC20PermitWithSignatureChecker("Op Mev")
    {
        _mint(msg.sender, initialSupply);
    }
}
"
    },
    "lib/superopevm/contracts/token/ERC20/ERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

import {IERC20 as IERC20} from "@superopevm/contracts/interfaces/IERC20.sol";
import {IERC20Metadata as IERC20Metadata} from "@superopevm/contracts/interfaces/IERC20Metadata.sol";
import {Context as Context} from "@superopevm/contracts/utils/Context.sol";

/**
 * @dev Implementation of the ERC20 standard
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => 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 override returns (string memory) {
        return _name;
    }

    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        unchecked {
            _approve(sender, _msgSender(), currentAllowance - amount);
        }
        return true;
    }

    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
        return true;
    }

    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(_msgSender(), spender, currentAllowance - subtractedValue);
        }
        return true;
    }

    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");
        _beforeTokenTransfer(sender, recipient, amount);
        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[sender] = senderBalance - amount;
        }
        _balances[recipient] += amount;
        emit Transfer(sender, recipient, amount);
        _afterTokenTransfer(sender, recipient, amount);
    }

    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");
        _beforeTokenTransfer(address(0), account, amount);
        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);
        _afterTokenTransfer(address(0), account, amount);
    }

    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");
        _beforeTokenTransfer(account, address(0), amount);
        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;
        emit Transfer(account, address(0), amount);
        _afterTokenTransfer(account, address(0), amount);
    }

    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");
        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}

    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}
}
"
    },
    "lib/superopevm/contracts/token/ERC20/extensions/ERC20Burnable.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

import {ERC20 as ERC20} from "@superopevm/contracts/token/ERC20/ERC20.sol";
import {Context as Context} from "@superopevm/contracts/utils/Context.sol";

/**
 * @dev Extension of ERC20 that allows token holders to destroy tokens
 */
abstract contract ERC20Burnable is Context, ERC20 {
    function burn(uint256 amount) public virtual {
        _burn(_msgSender(), amount);
    }

    function burnFrom(address account, uint256 amount) public virtual {
        uint256 currentAllowance = allowance(account, _msgSender());
        require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance");
        unchecked {
            _approve(account, _msgSender(), currentAllowance - amount);
        }
        _burn(account, amount);
    }
}
"
    },
    "lib/superopevm/contracts/token/ERC20/extensions/ERC20PermitWithSignatureChecker.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

import {IERC20Permit as IERC20Permit} from "@superopevm/contracts/interfaces/IERC20Permit.sol";
import {ERC20 as ERC20} from "@superopevm/contracts/token/ERC20/ERC20.sol";
import {SignatureChecker as SignatureChecker} from "@superopevm/contracts/utils/cryptography/SignatureChecker.sol";
import {Counters as Counters} from "@superopevm/contracts/utils/math/Counters.sol";
import {EIP712 as EIP712} from "@superopevm/contracts/utils/cryptography/EIP712.sol";

/**
 * @title ERC20PermitWithSignatureChecker
 * @dev ERC20Permit implementation using SignatureChecker
 */
abstract contract ERC20PermitWithSignatureChecker is ERC20, IERC20Permit, EIP712 {
    using Counters for Counters.Counter;
    
    mapping(address => Counters.Counter) private _nonces;
    
    bytes32 private constant _PERMIT_TYPEHASH = 
        keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
    
    constructor(string memory name) EIP712(name, "1") {}
    
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual override(IERC20Permit) {
        require(block.timestamp <= deadline, "ERC20Permit: expired deadline");
        
        bytes32 structHash = keccak256(
            abi.encode(
                _PERMIT_TYPEHASH,
                owner,
                spender,
                value,
                _nonces[owner].current(),
                deadline
            )
        );
        
        bytes32 hash = _hashTypedDataV4(structHash);
        require(SignatureChecker.isValidSignatureNow(owner, hash, v, r, s), "ERC20Permit: invalid signature");
        
        _nonces[owner].increment();
        _approve(owner, spender, value);
    }
    
    function nonces(address owner) public view virtual override(IERC20Permit) returns (uint256) {
        return _nonces[owner].current();
    }
    
    function DOMAIN_SEPARATOR() public view virtual override(EIP712, IERC20Permit) returns (bytes32) {
        return EIP712.DOMAIN_SEPARATOR();
    }
}
"
    },
    "lib/superopevm/contracts/interfaces/IERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

/**
 * @dev Interface of the ERC20 standard
 */
interface IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}
"
    },
    "lib/superopevm/contracts/interfaces/IERC20Metadata.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

import {IERC20 as IERC20} from "@superopevm/contracts/interfaces/IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard
 */
interface IERC20Metadata is IERC20 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);
}
"
    },
    "lib/superopevm/contracts/utils/Context.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

/**
 * @dev Provides information about the current execution context
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}
"
    },
    "lib/superopevm/contracts/interfaces/IERC20Permit.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

/**
 * @title IERC20Permit
 * @dev Interface for the Permit functionality (EIP-2612)
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over `owner`'s tokens,
     * given `owner`'s signed approval.
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature.
     */
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}
"
    },
    "lib/superopevm/contracts/utils/cryptography/SignatureChecker.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

import {ECDSA as ECDSA} from "@superopevm/contracts/utils/cryptography/ECDSA.sol";

/**
 * @title SignatureChecker
 * @dev Helper for verifying signatures
 */
library SignatureChecker {
    function isValidSignatureNow(
        address signer,
        bytes32 hash,
        bytes memory signature
    ) internal view returns (bool) {
        (address recovered, ECDSA.RecoverError error) = ECDSA.recover(hash, signature);
        return (error == ECDSA.RecoverError.NoError && recovered == signer);
    }
    
    function isValidSignatureNow(
        address signer,
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal view returns (bool) {
        (address recovered, ECDSA.RecoverError error) = ECDSA.recover(hash, v, r, s);
        return (error == ECDSA.RecoverError.NoError && recovered == signer);
    }
}
"
    },
    "lib/superopevm/contracts/utils/math/Counters.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

/**
 * @title Counters
 * @dev Provides counters that can only be incremented or decremented by one.
 */
library Counters {
    struct Counter {
        uint256 _value;
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counters: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}
"
    },
    "lib/superopevm/contracts/utils/cryptography/EIP712.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

/**
 * @title EIP712
 * @dev Helper for EIP-712 typed data hashing and signing
 */
abstract contract EIP712 {
    bytes32 private immutable _HASHED_NAME;
    bytes32 private immutable _HASHED_VERSION;
    bytes32 private immutable _TYPE_HASH;
    bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
    uint256 private immutable _CACHED_CHAIN_ID;
    address private immutable _CACHED_THIS;
    
    constructor(string memory name, string memory version) {
        bytes32 hashedName = keccak256(bytes(name));
        bytes32 hashedVersion = keccak256(bytes(version));
        bytes32 typeHash = keccak256(
            "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
        );
        
        _HASHED_NAME = hashedName;
        _HASHED_VERSION = hashedVersion;
        _CACHED_CHAIN_ID = block.chainid;
        _CACHED_THIS = address(this);
        _TYPE_HASH = typeHash;
        
        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
    }
    
    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {
            return _CACHED_DOMAIN_SEPARATOR;
        } else {
            return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
        }
    }
    
    function _buildDomainSeparator(
        bytes32 typeHash,
        bytes32 nameHash,
        bytes32 versionHash
    ) private view returns (bytes32) {
        return keccak256(
            abi.encode(
                typeHash,
                nameHash,
                versionHash,
                block.chainid,
                address(this)
            )
        );
    }
    
    function _hashTypedDataV4(bytes32 structHash) internal view returns (bytes32) {
        return keccak256(
            abi.encodePacked(
                "\x19\x01",
                DOMAIN_SEPARATOR(),
                structHash
            )
        );
    }
}
"
    },
    "lib/superopevm/contracts/utils/cryptography/ECDSA.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

/**
 * @title ECDSA
 * @dev Elliptic Curve Digital Signature Algorithm operations
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function recover(
        bytes32 hash,
        bytes memory signature
    ) internal pure returns (address, RecoverError) {
        if (signature.length != 65) {
            return (address(0), RecoverError.InvalidSignatureLength);
        }

        bytes32 r;
        bytes32 s;
        uint8 v;

        assembly {
            r := mload(add(signature, 0x20))
            s := mload(add(signature, 0x40))
            v := byte(0, mload(add(signature, 0x60)))
        }

        return recover(hash, v, r, s);
    }

    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }

        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        return (tryRecover(hash, v, r, s), RecoverError.NoError);
    }

    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        bytes32 digest = keccak256(
            abi.encodePacked("\x19Ethereum Signed Message:\
32", hash)
        );
        return ecrecover(digest, v, r, s);
    }

    function toEthSignedMessageHash(
        bytes32 hash
    ) internal pure returns (bytes32) {
        return keccak256(
            abi.encodePacked("\x19Ethereum Signed Message:\
32", hash)
        );
    }
}
"
    }
  },
  "settings": {
    "remappings": [
      "@superopevm/=lib/superopevm/",
      "forge-std/=lib/forge-std/src/",
      "superopevm/=lib/superopevm/contracts/"
    ],
    "optimizer": {
      "enabled": false,
      "runs": 200
    },
    "metadata": {
      "useLiteralContent": false,
      "bytecodeHash": "ipfs",
      "appendCBOR": true
    },
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    },
    "evmVersion": "prague",
    "viaIR": false
  }
}}

Tags:
ERC20, Token, Burnable, Factory|addr:0x0f1834c84d63edf604363847ec420bf866391f08|verified:true|block:23420877|tx:0x55b2408a87b17f6a0ed5ba0a530460d2bb024c80632b4b78ca45bd6f5e0c3c47|first_check:1758715144

Submitted on: 2025-09-24 13:59:09

Comments

Log in to comment.

No comments yet.