Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0x5c6D51ecBA4D8E4F20373e3ce96a62342B125D6d
Balance 0 ETH
Nonce 1
Code Size 5002 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

5002 bytes
0x608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063a9059cbb1161008c578063d505accf11610066578063d505accf1461035a578063dd62ed3e1461036d578063fe9fbb801461039857610177565b8063a9059cbb14610311578063b6a5d7de14610324578063b91816111461033757610177565b80638da5cb5b116100bd5780638da5cb5b146102b157806395d89b41146102f65780639dc29fac146102fe57610177565b806370a08231146102715780637ecebe001461029157610177565b806327c97fa51161012f578063313ce56711610114578063313ce567146102365780633644e5151461025557806340c10f191461025e57610177565b806327c97fa5146101fc57806330adf81f1461020f57610177565b806313af40351161016057806313af4035146101bd57806318160ddd146101d257806323b872dd146101e957610177565b806306fdde031461017c578063095ea7b31461019a575b600080fd5b6101846103ab565b60405161019191906111f8565b60405180910390f35b6101ad6101a83660046111cf565b610439565b6040519015158152602001610191565b6101d06101cb3660046110d7565b6104b2565b005b6101db60095481565b604051908152602001610191565b6101ad6101f7366004611123565b61057f565b6101d061020a3660046110d7565b6107e7565b6101db7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6002546102439060ff1681565b60405160ff9091168152602001610191565b6101db60065481565b6101d061026c3660046111cf565b6108b4565b6101db61027f3660046110d7565b60036020526000908152604090205481565b6101db61029f3660046110d7565b60056020526000908152604090205481565b6007546102d19073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b610184610943565b6101d061030c3660046111cf565b610950565b6101ad61031f3660046111cf565b6109db565b6101d06103323660046110d7565b6109ef565b6101ad6103453660046110d7565b60086020526000908152604090205460ff1681565b6101d061036836600461115e565b610ac6565b6101db61037b3660046110f1565b600460209081526000928352604080842090915290825290205481565b6101ad6103a63660046110d7565b610ecd565b600080546103b890611298565b80601f01602080910402602001604051908101604052809291908181526020018280546103e490611298565b80156104315780601f1061040657610100808354040283529160200191610431565b820191906000526020600020905b81548152906001019060200180831161041457829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906104a19086815260200190565b60405180910390a350600192915050565b60075473ffffffffffffffffffffffffffffffffffffffff163314610538576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f53656e646572206e6f74206f776e65720000000000000000000000000000000060448201526064015b60405180910390fd5b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548281101561060f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f45524332303a20696e73756666696369656e742d62616c616e63650000000000604482015260640161052f565b73ffffffffffffffffffffffffffffffffffffffff8516331461072c5773ffffffffffffffffffffffffffffffffffffffff851660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461072a57838110156106ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e742d616c6c6f77616e6365000000604482015260640161052f565b6106f88482611281565b73ffffffffffffffffffffffffffffffffffffffff871660009081526004602090815260408083203384529091529020555b505b6107368382611281565b73ffffffffffffffffffffffffffffffffffffffff8087166000908152600360205260408082209390935590861681522054610773908490611269565b73ffffffffffffffffffffffffffffffffffffffff80861660008181526003602052604090819020939093559151908716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906107d49087815260200190565b60405180910390a3506001949350505050565b60075473ffffffffffffffffffffffffffffffffffffffff163314610868576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f53656e646572206e6f74206f776e657200000000000000000000000000000000604482015260640161052f565b73ffffffffffffffffffffffffffffffffffffffff16600090815260086020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60075473ffffffffffffffffffffffffffffffffffffffff163314610935576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f53656e646572206e6f74206f776e657200000000000000000000000000000000604482015260640161052f565b61093f8282610efc565b5050565b600180546103b890611298565b60075473ffffffffffffffffffffffffffffffffffffffff1633146109d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f53656e646572206e6f74206f776e657200000000000000000000000000000000604482015260640161052f565b61093f8282610fbf565b60006109e833848461057f565b9392505050565b60075473ffffffffffffffffffffffffffffffffffffffff163314610a70576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f53656e646572206e6f74206f776e657200000000000000000000000000000000604482015260640161052f565b610ac38173ffffffffffffffffffffffffffffffffffffffff16600090815260086020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b50565b60065473ffffffffffffffffffffffffffffffffffffffff8881166000818152600560209081526040918290205482517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981840152808401859052948c166060860152608085018b905260a085015260c08085018a90528251808603909101815260e0850183528051908201207f1901000000000000000000000000000000000000000000000000000000000000610100860152610102850195909552610122808501959095528151808503909501855261014290930190528251929091019190912090610c10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45524332303a20696e76616c69642d616464726573732d300000000000000000604482015260640161052f565b60408051600081526020810180835283905260ff861691810191909152606081018490526080810183905260019060a0016020604051602081039080840390855afa158015610c63573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614610d01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f45524332303a20696e76616c69642d7065726d69740000000000000000000000604482015260640161052f565b841580610d0e5750844211155b610d74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f45524332303a207065726d69742d657870697265640000000000000000000000604482015260640161052f565b7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115610e24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161052f565b73ffffffffffffffffffffffffffffffffffffffff88166000908152600560205260408120805491610e55836112ec565b909155505073ffffffffffffffffffffffffffffffffffffffff8881166000818152600460209081526040808320948c16808452948252918290208a905590518981527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a35050505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526008602052604090205460ff165b919050565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260036020526040902054610f2d908290611269565b73ffffffffffffffffffffffffffffffffffffffff831660009081526003602052604081209190915560098054839290610f68908490611269565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260036020526040902054818110156110185773ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812055611049565b6110228282611281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600360205260409020555b816009600082825461105b9190611281565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610ef757600080fd5b6000602082840312156110e8578081fd5b6109e8826110b3565b60008060408385031215611103578081fd5b61110c836110b3565b915061111a602084016110b3565b90509250929050565b600080600060608486031215611137578081fd5b611140846110b3565b925061114e602085016110b3565b9150604084013590509250925092565b600080600080600080600060e0888a031215611178578283fd5b611181886110b3565b965061118f602089016110b3565b95506040880135945060608801359350608088013560ff811681146111b2578384fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156111e1578182fd5b6111ea836110b3565b946020939093013593505050565b6000602080835283518082850152825b8181101561122457858101830151858201604001528201611208565b818111156112355783604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000821982111561127c5761127c611325565b500190565b60008282101561129357611293611325565b500390565b600181811c908216806112ac57607f821691505b602082108114156112e6577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561131e5761131e611325565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea2646970667358221220dbafbdd9de34b90bb3540768ed2302841fd36ed26b25a9cf114ef83052146e2664736f6c63430008030033

Verified Source Code Full Match

Compiler: v0.8.3+commit.8d00100c EVM: istanbul Optimization: Yes (10000 runs)
IERC20.sol 35 lines
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.3;

interface IERC20 {
    function symbol() external view returns (string memory);

    function balanceOf(address account) external view returns (uint256);

    // Note this is non standard but nearly all ERC20 have exposed decimal functions
    function decimals() external view returns (uint8);

    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
    );
}
ERC20Permit.sol 244 lines
// SPDX-License-Identifier: Apache-2.0
// Copied from https://github.com/element-fi/elf-contracts/blob/a6cb960896301b7562ced70a8b221f3cc964ea0a/contracts/libraries/ERC20Permit.sol

pragma solidity ^0.8.3;

import "../interfaces/IERC20Permit.sol";

// This default erc20 library is designed for max efficiency and security.
// WARNING: By default it does not include totalSupply which breaks the ERC20 standard
//          to use a fully standard compliant ERC20 use 'ERC20PermitWithSupply"
abstract contract ERC20Permit is IERC20Permit {
    // --- ERC20 Data ---
    // The name of the erc20 token
    string public name;
    // The symbol of the erc20 token
    string public override symbol;
    // The decimals of the erc20 token, should default to 18 for new tokens
    uint8 public override decimals;

    // A mapping which tracks user token balances
    mapping(address => uint256) public override balanceOf;
    // A mapping which tracks which addresses a user allows to move their tokens
    mapping(address => mapping(address => uint256)) public override allowance;
    // A mapping which tracks the permit signature nonces for users
    mapping(address => uint256) public override nonces;

    // --- EIP712 niceties ---
    // solhint-disable-next-line var-name-mixedcase
    bytes32 public override DOMAIN_SEPARATOR;
    // bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
    bytes32 public constant PERMIT_TYPEHASH =
        0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;

    /// @notice Initializes the erc20 contract
    /// @param name_ the value 'name' will be set to
    /// @param symbol_ the value 'symbol' will be set to
    /// @dev decimals default to 18 and must be reset by an inheriting contract for
    ///      non standard decimal values
    constructor(string memory name_, string memory symbol_) {
        // Set the state variables
        name = name_;
        symbol = symbol_;
        decimals = 18;

        // By setting these addresses to 0 attempting to execute a transfer to
        // either of them will revert. This is a gas efficient way to prevent
        // a common user mistake where they transfer to the token address.
        // These values are not considered 'real' tokens and so are not included
        // in 'total supply' which only contains minted tokens.
        balanceOf[address(0)] = type(uint256).max;
        balanceOf[address(this)] = type(uint256).max;

        // Optional extra state manipulation
        _extraConstruction();

        // Computes the EIP 712 domain separator which prevents user signed messages for
        // this contract to be replayed in other contracts.
        // https://eips.ethereum.org/EIPS/eip-712
        DOMAIN_SEPARATOR = keccak256(
            abi.encode(
                keccak256(
                    "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
                ),
                keccak256(bytes(name)),
                keccak256(bytes("1")),
                block.chainid,
                address(this)
            )
        );
    }

    /// @notice An optional override function to execute and change state before immutable assignment
    function _extraConstruction() internal virtual {}

    // --- Token ---
    /// @notice Allows a token owner to send tokens to another address
    /// @param recipient The address which will be credited with the tokens
    /// @param amount The amount user token to send
    /// @return returns true on success, reverts on failure so cannot return false.
    /// @dev transfers to this contract address or 0 will fail
    function transfer(address recipient, uint256 amount)
        public
        virtual
        override
        returns (bool)
    {
        // We forward this call to 'transferFrom'
        return transferFrom(msg.sender, recipient, amount);
    }

    /// @notice Transfers an amount of erc20 from a spender to a receipt
    /// @param spender The source of the ERC20 tokens
    /// @param recipient The destination of the ERC20 tokens
    /// @param amount the number of tokens to send
    /// @return returns true on success and reverts on failure
    /// @dev will fail transfers which send funds to this contract or 0
    function transferFrom(
        address spender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        // Load balance and allowance
        uint256 balance = balanceOf[spender];
        require(balance >= amount, "ERC20: insufficient-balance");
        // We potentially have to change allowances
        if (spender != msg.sender) {
            // Loading the allowance in the if block prevents vanilla transfers
            // from paying for the sload.
            uint256 allowed = allowance[spender][msg.sender];
            // If the allowance is max we do not reduce it
            // Note - This means that max allowances will be more gas efficient
            // by not requiring a sstore on 'transferFrom'
            if (allowed != type(uint256).max) {
                require(allowed >= amount, "ERC20: insufficient-allowance");
                allowance[spender][msg.sender] = allowed - amount;
            }
        }
        // Update the balances
        balanceOf[spender] = balance - amount;
        // Note - In the constructor we initialize the 'balanceOf' of address 0 and
        //        the token address to uint256.max and so in 8.0 transfers to those
        //        addresses revert on this step.
        balanceOf[recipient] = balanceOf[recipient] + amount;
        // Emit the needed event
        emit Transfer(spender, recipient, amount);
        // Return that this call succeeded
        return true;
    }

    /// @notice This internal minting function allows inheriting contracts
    ///         to mint tokens in the way they wish.
    /// @param account the address which will receive the token.
    /// @param amount the amount of token which they will receive
    /// @dev This function is virtual so that it can be overridden, if you
    ///      are reviewing this contract for security you should ensure to
    ///      check for overrides
    function _mint(address account, uint256 amount) internal virtual {
        // Add tokens to the account
        balanceOf[account] = balanceOf[account] + amount;
        // Emit an event to track the minting
        emit Transfer(address(0), account, amount);
    }

    /// @notice This internal burning function allows inheriting contracts to
    ///         burn tokens in the way they see fit.
    /// @param account the account to remove tokens from
    /// @param amount  the amount of tokens to remove
    /// @dev This function is virtual so that it can be overridden, if you
    ///      are reviewing this contract for security you should ensure to
    ///      check for overrides
    function _burn(address account, uint256 amount) internal virtual {
        // Reduce the balance of the account
        balanceOf[account] = balanceOf[account] - amount;
        // Emit an event tracking transfers
        emit Transfer(account, address(0), amount);
    }

    /// @notice This function allows a user to approve an account which can transfer
    ///         tokens on their behalf.
    /// @param account The account which will be approve to transfer tokens
    /// @param amount The approval amount, if set to uint256.max the allowance does not go down on transfers.
    /// @return returns true for compatibility with the ERC20 standard
    function approve(address account, uint256 amount)
        public
        virtual
        override
        returns (bool)
    {
        // Set the senders allowance for account to amount
        allowance[msg.sender][account] = amount;
        // Emit an event to track approvals
        emit Approval(msg.sender, account, amount);
        return true;
    }

    /// @notice This function allows a caller who is not the owner of an account to execute the functionality of 'approve' with the owners signature.
    /// @param owner the owner of the account which is having the new approval set
    /// @param spender the address which will be allowed to spend owner's tokens
    /// @param value the new allowance value
    /// @param deadline the timestamp which the signature must be submitted by to be valid
    /// @param v Extra ECDSA data which allows public key recovery from signature assumed to be 27 or 28
    /// @param r The r component of the ECDSA signature
    /// @param s The s component of the ECDSA signature
    /// @dev The signature for this function follows EIP 712 standard and should be generated with the
    ///      eth_signTypedData JSON RPC call instead of the eth_sign JSON RPC call. If using out of date
    ///      parity signing libraries the v component may need to be adjusted. Also it is very rare but possible
    ///      for v to be other values, those values are not supported.
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external override {
        // The EIP 712 digest for this function
        bytes32 digest =
            keccak256(
                abi.encodePacked(
                    "\x19\x01",
                    DOMAIN_SEPARATOR,
                    keccak256(
                        abi.encode(
                            PERMIT_TYPEHASH,
                            owner,
                            spender,
                            value,
                            nonces[owner],
                            deadline
                        )
                    )
                )
            );
        // Require that the owner is not zero
        require(owner != address(0), "ERC20: invalid-address-0");
        // Require that we have a valid signature from the owner
        require(owner == ecrecover(digest, v, r, s), "ERC20: invalid-permit");
        // Require that the signature is not expired
        require(
            deadline == 0 || block.timestamp <= deadline,
            "ERC20: permit-expired"
        );
        // Format the signature to the default format
        require(
            uint256(s) <=
                0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,
            "ERC20: invalid signature 's' value"
        );
        // Increment the signature nonce to prevent replay
        nonces[owner]++;
        // Set the allowance to the new value
        allowance[owner][spender] = value;
        // Emit an approval event to be able to track this happening
        emit Approval(owner, spender, value);
    }

    /// @notice Internal function which allows inheriting contract to set custom decimals
    /// @param decimals_ the new decimal value
    function _setupDecimals(uint8 decimals_) internal {
        // Set the decimals
        decimals = decimals_;
    }
}
Authorizable.sol 59 lines
// SPDX-License-Identifier: Apache-2.0
pragma solidity >=0.7.0;

contract Authorizable {
    // This contract allows a flexible authorization scheme

    // The owner who can change authorization status
    address public owner;
    // A mapping from an address to its authorization status
    mapping(address => bool) public authorized;

    /// @dev We set the deployer to the owner
    constructor() {
        owner = msg.sender;
    }

    /// @dev This modifier checks if the msg.sender is the owner
    modifier onlyOwner() {
        require(msg.sender == owner, "Sender not owner");
        _;
    }

    /// @dev This modifier checks if an address is authorized
    modifier onlyAuthorized() {
        require(isAuthorized(msg.sender), "Sender not Authorized");
        _;
    }

    /// @dev Returns true if an address is authorized
    /// @param who the address to check
    /// @return true if authorized false if not
    function isAuthorized(address who) public view returns (bool) {
        return authorized[who];
    }

    /// @dev Privileged function authorize an address
    /// @param who the address to authorize
    function authorize(address who) external onlyOwner() {
        _authorize(who);
    }

    /// @dev Privileged function to de authorize an address
    /// @param who The address to remove authorization from
    function deauthorize(address who) external onlyOwner() {
        authorized[who] = false;
    }

    /// @dev Function to change owner
    /// @param who The new owner address
    function setOwner(address who) public onlyOwner() {
        owner = who;
    }

    /// @dev Inheritable function which authorizes someone
    /// @param who the address to authorize
    function _authorize(address who) internal {
        authorized[who] = true;
    }
}
IERC20Permit.sol 62 lines
// Forked from openzepplin
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.3;

import "./IERC20.sol";

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit is IERC20 {
    /**
     * @dev Sets `value` as the allowance of `spender` over `owner`'s tokens,
     * given `owner`'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for `permit`, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}
ERC20PermitWithMint.sol 70 lines
// SPDX-License-Identifier: Apache-2.0
// Largely based on https://github.com/element-fi/elf-contracts/blob/a6cb960896301b7562ced70a8b221f3cc964ea0a/contracts/libraries/ERC20PermitWithSupply.sol

pragma solidity ^0.8.3;

import "./ERC20Permit.sol";
import "./Authorizable.sol";

// This contract adds total supply and minting to the generic erc20
contract ERC20PermitWithMint is ERC20Permit, Authorizable {
    /// @notice Initializes the erc20 contract
    /// @param name_ the value 'name' will be set to
    /// @param symbol_ the value 'symbol' will be set to
    /// @param owner_ address which has the power to mint
    constructor(
        string memory name_,
        string memory symbol_,
        address owner_
    ) ERC20Permit(name_, symbol_) {
        setOwner(owner_);
    }

    // The stored totalSupply, it equals all tokens minted - all tokens burned
    uint256 public totalSupply;

    /// @notice Allows the governance to mint
    /// @param account the account to addd tokens to
    /// @param amount the amount of tokens to add
    function mint(address account, uint256 amount) external onlyOwner {
        _mint(account, amount);
    }

    /// @notice This function overrides the ERC20Permit Library's _mint and causes it
    ///          to track total supply.
    /// @param account the account to addd tokens to
    /// @param amount the amount of tokens to add
    function _mint(address account, uint256 amount) internal override {
        // Increase account balance
        balanceOf[account] = balanceOf[account] + amount;
        // Increase total supply
        totalSupply += amount;
        // Emit a transfer from zero to emulate a mint
        emit Transfer(address(0), account, amount);
    }

    /// @notice Allows the governance to burn
    /// @param account the account to burn from
    /// @param amount the amount of token to burn
    function burn(address account, uint256 amount) external onlyOwner {
        _burn(account, amount);
    }

    /// @notice This function overrides the ERC20Permit Library's _burn to decrement total supply
    /// @param account the account to burn from
    /// @param amount the amount of token to burn
    function _burn(address account, uint256 amount) internal override {
        // Decrease user balance
        uint256 currentBalance = balanceOf[account];
        // This logic prevents a reversion if the _burn is frontrun
        if (currentBalance < amount) {
            balanceOf[account] = 0;
        } else {
            balanceOf[account] = currentBalance - amount;
        }
        // Decrease total supply
        totalSupply -= amount;
        // Emit an event tracking the burn
        emit Transfer(account, address(0), amount);
    }
}

Read Contract

DOMAIN_SEPARATOR 0x3644e515 → bytes32
PERMIT_TYPEHASH 0x30adf81f → bytes32
allowance 0xdd62ed3e → uint256
authorized 0xb9181611 → bool
balanceOf 0x70a08231 → uint256
decimals 0x313ce567 → uint8
isAuthorized 0xfe9fbb80 → bool
name 0x06fdde03 → string
nonces 0x7ecebe00 → uint256
owner 0x8da5cb5b → address
symbol 0x95d89b41 → string
totalSupply 0x18160ddd → uint256

Write Contract 9 functions

These functions modify contract state and require a wallet transaction to execute.

approve 0x095ea7b3
address account
uint256 amount
returns: bool
authorize 0xb6a5d7de
address who
burn 0x9dc29fac
address account
uint256 amount
deauthorize 0x27c97fa5
address who
mint 0x40c10f19
address account
uint256 amount
permit 0xd505accf
address owner
address spender
uint256 value
uint256 deadline
uint8 v
bytes32 r
bytes32 s
setOwner 0x13af4035
address who
transfer 0xa9059cbb
address recipient
uint256 amount
returns: bool
transferFrom 0x23b872dd
address spender
address recipient
uint256 amount
returns: bool

Recent Transactions

No transactions found for this address