Contract 0x990a524EBc0A54fd2A7ebC02A1CE54D309fb5CD3 7

 

Contract Overview

Cypher.dog: CDOG Token
Balance:
0 MATIC

MATIC Value:
$0.00

Token:
 
Txn Hash
Method
Block
From
To
Value [Txn Fee]
0x6fa3457b5f198c91ff454817a096697fc51baf6a1d300c9f437992b4189912fcTransfer469699612023-08-31 8:54:1532 days 5 hrs ago0x5c7bed3cca42e4562877ed88b9aa0f5898ed59b0 IN  Cypher.dog: CDOG Token0 MATIC0.006462743904 120.683907023
0x26951e410290c5ce636b50eb4de07b44914e03a59a42a6fa53abdbbd25b42644Transfer464463192023-08-18 6:33:4845 days 7 hrs ago0x1942098f90f3707ee73b990fde2fb22683c266ef IN  Cypher.dog: CDOG Token0 MATIC0.00584225444 88.832612713
0xf25163ddf953b0ef7143064b1e90559501bc0e620971070ba5f2626a0c25ca3dTransfer464463042023-08-18 6:33:1845 days 7 hrs ago0xff44e2d14826b91bc257c8d39665c2c43eda37c0 IN  Cypher.dog: CDOG Token0 MATIC0.00577864781 87.865461562
0xc95b646886a9a699c6e83eb1db5abbb6020dd543aac12aa115370ec4d2c98678Transfer464462092023-08-18 6:29:5645 days 7 hrs ago0x1942098f90f3707ee73b990fde2fb22683c266ef IN  Cypher.dog: CDOG Token0 MATIC0.005764816346 87.63916062
0x66be5f7dd9f429189ff704a9652b23918b85fecc4c2bdeebe0623b8719c13e53Transfer464461162023-08-18 6:26:2645 days 7 hrs ago0xe3bf552d47d5e41a98108b8c1fbb12598a3eff1b IN  Cypher.dog: CDOG Token0 MATIC0.00788799716 119.93852784
0x7609d99bc59914e76c302d670841d1bd87d40a33e6505f82aa4c337e9eaa891eTransfer464461042023-08-18 6:26:0045 days 7 hrs ago0xff44e2d14826b91bc257c8d39665c2c43eda37c0 IN  Cypher.dog: CDOG Token0 MATIC0.008707739095 132.378708936
0x55eaaab0c7cc60eb844ee0972ebcc5acfd82a6b340d519fa1df280015386c68cTransfer464459932023-08-18 6:22:0445 days 7 hrs ago0xe3bf552d47d5e41a98108b8c1fbb12598a3eff1b IN  Cypher.dog: CDOG Token0 MATIC0.005696414493 86.599286913
0x2b47dedf01b844777a7595235d8078d109e0e56010ef9ced43f8e233dd344348Transfer464458802023-08-18 6:18:0445 days 8 hrs ago0xff44e2d14826b91bc257c8d39665c2c43eda37c0 IN  Cypher.dog: CDOG Token0 MATIC0.006260531452 95.175229974
0xb97b7001916ce138161663a5aec6dd94bbef757286c5f5b0e466cdffd234bd65Transfer464458272023-08-18 6:16:1245 days 8 hrs ago0x1942098f90f3707ee73b990fde2fb22683c266ef IN  Cypher.dog: CDOG Token0 MATIC0.007282401525 110.710128244
0xb121eec92fd5a46354a12a42aa2837cb87561e58bdfcfa07e565b3d3a0a8f442Transfer447684042023-07-06 22:53:4487 days 15 hrs ago0x5c7bed3cca42e4562877ed88b9aa0f5898ed59b0 IN  Cypher.dog: CDOG Token0 MATIC0.009895872493 140.090778375
0x4fdf5ef853e6bfb1ce560819cfc95c909e6edde5a03473ccb1f452e013db5322Transfer434427842023-06-02 10:24:17122 days 3 hrs ago0x7eb58bb90e9b4db095cd8c0996dbd366dea98400 IN  Cypher.dog: CDOG Token0 MATIC0.009810304773 155.615379807
0x497161f9520f41fa6dba5db496dfeb200d65935c8b13464cf969a7f9e860566dTransfer434414392023-06-02 9:34:55122 days 4 hrs ago0x1c3dfef229f4aa27dc98a57cf8c138b9f538b1ae IN  Cypher.dog: CDOG Token0 MATIC0.009548854245 151.468136247
0xf14fb91777bf4c9d97211953f681bec40ea2c4be3ee587968f4d988f9b69dd62Transfer434414162023-06-02 9:34:07122 days 4 hrs ago0x1c3dfef229f4aa27dc98a57cf8c138b9f538b1ae IN  Cypher.dog: CDOG Token0 MATIC0.00935415423 148.37971876
0x3704e9c0c6c096026cbad7e34d33c2403fd53a7279ee7eb1847951b6bc185490Transfer433952022023-06-01 5:11:47123 days 9 hrs ago0x485473f0ad70cef75f62cd4dae1659a2d7e5348e IN  Cypher.dog: CDOG Token0 MATIC0.013013461129 162.404357038
0xe7fe6b18f0d9f1de4c1129b33a1b28a83b3c74ec4c83646504973f9fb68ad63eTransfer422106942023-05-02 9:33:20153 days 4 hrs ago0x1c3dfef229f4aa27dc98a57cf8c138b9f538b1ae IN  Cypher.dog: CDOG Token0 MATIC0.013504940566 214.221321765
0x9909ff7d2b040c7220245b2480a88084dd0eebea6260cdcb81f644853c8b9b67Transfer419202922023-04-25 0:14:46160 days 14 hrs ago0x5c7bed3cca42e4562877ed88b9aa0f5898ed59b0 IN  Cypher.dog: CDOG Token0 MATIC0.018020628282 336.588809706
0x0b607335b5444b6455ceb8ac7154512b178f8578262c8b2aee9e913028171d4aTransfer416109002023-04-16 20:47:23168 days 17 hrs ago0x1943535c8487686e245708b6315f82be83d4a1ec IN  Cypher.dog: CDOG Token0 MATIC0.014522697565 230.409290274
0x2681f814d2855676e8f3b5f21a7d0fdf4aa94ba02563082df703de8942b2bd8fTransfer416105072023-04-16 20:32:41168 days 17 hrs ago0xa7cb513bf4b765671cfb3e1504bee6256085d354 IN  Cypher.dog: CDOG Token0 MATIC0.012582798043 157.029802119
0x8db8126556b65118bbd539b9465237986cbd91505707572edef1c78ded66995fTransfer411854252023-04-05 20:30:44179 days 17 hrs ago0x7eb58bb90e9b4db095cd8c0996dbd366dea98400 IN  Cypher.dog: CDOG Token0 MATIC0.0060697961 96.281781992
0x2f667f072fbe1c0b6d87cdbc5a05a5e977a155a15a1086ab7004f45c2dae833eTransfer411061222023-04-03 19:23:04181 days 18 hrs ago0x1c3dfef229f4aa27dc98a57cf8c138b9f538b1ae IN  Cypher.dog: CDOG Token0 MATIC0.006332002135 100.460132241
0xf79605d5edc65d50e0da931a933445a80c0de847f99f24dc22e4fcd2995f88ffTransfer410972472023-04-03 13:51:14182 days 29 mins ago0x539fbcbb5f1ceffefdd06d3b689ee9ce4f98b411 IN  Cypher.dog: CDOG Token0 MATIC0.006919440937 169.83974221
0x58b9e9f139a4b0669abb76c617efe34d029bf0a823687d04e28f6ac08df46db3Transfer410965562023-04-03 13:26:46182 days 53 mins ago0x539fbcbb5f1ceffefdd06d3b689ee9ce4f98b411 IN  Cypher.dog: CDOG Token0 MATIC0.004145049179 101.74146877
0xe9c72b82a1b9d8b0d784b0bd0f63976098cf1e1c79ac96eba2571698a694b7daTransfer410964522023-04-03 13:23:06182 days 57 mins ago0x539fbcbb5f1ceffefdd06d3b689ee9ce4f98b411 IN  Cypher.dog: CDOG Token0 MATIC0.00436821522 107.282344493
0x76d98963f5033c8817237acfb4c60a87d7391d91443bc436d1d382b4519f7682Transfer410964042023-04-03 13:21:24182 days 59 mins ago0x539fbcbb5f1ceffefdd06d3b689ee9ce4f98b411 IN  Cypher.dog: CDOG Token0 MATIC0.004231750473 103.869577907
0x3177c4e5a2b3540bf46bc27cba5243601838e4568e0ab903b3a1d683ba340c45Transfer410963852023-04-03 13:20:44182 days 59 mins ago0x539fbcbb5f1ceffefdd06d3b689ee9ce4f98b411 IN  Cypher.dog: CDOG Token0 MATIC0.006606890337 104.80140759
[ Download CSV Export 

OVERVIEW

Cypherdog offers secure file transfer, cloud storage, and messaging with no third-party access to data and absolute protection of the private key for business and private use.

Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CypherDogToken

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 1 : CypherDogToken.sol
/**
 *  SourceUnit: cypherdog/contracts/CypherDogToken.sol
 */

// SPDX-License-Identifier: MIT
// based on https://github.com/CoinbaseStablecoin/eip-3009

pragma solidity ^0.8.0;

abstract contract EIP712Domain {
    /**
     * @dev EIP712 Domain Separator
     */
    bytes32 public DOMAIN_SEPARATOR;
    uint256 public CHAINID;
    bytes32 public EIP712_DOMAIN_TYPEHASH;
}

error InvalidSignature();
error InvalidS();
error InvalidV();

/**
 * @title ECRecover
 * @notice A library that provides a safe ECDSA recovery function
 */
library ECRecover {
    /**
     * @notice Recover signer's address from a signed message
     * @dev Adapted from: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/65e4ffde586ec89af3b7e9140bdc9235d1254853/contracts/cryptography/ECDSA.sol
     * Modifications: Accept v, r, and s as separate arguments
     * @param digest    Keccak-256 hash digest of the signed message
     * @param v         v of the signature
     * @param r         r of the signature
     * @param s         s of the signature
     * @return Signer address
     */
    function recover(
        bytes32 digest,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (
            uint256(s) >
            0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0
        ) {
            revert InvalidS();
        }

        if (v < 27 || v > 28) {
            revert InvalidV();
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(digest, v, r, s);
        if (signer == address(0)) revert InvalidSignature();

        return signer;
    }
}

/**
 * @title EIP712
 * @notice A library that provides EIP712 helper functions
 */
library EIP712 {
    // keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
    bytes32 public constant EIP712_DOMAIN_TYPEHASH =
        0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;

    /**
     * @notice Make EIP712 domain separator
     * @param name      Contract name
     * @param version   Contract version
     * @return Domain separator
     */
    function makeDomainSeparator(
        string memory name,
        string memory version,
        uint256 chainId
    ) internal view returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    EIP712_DOMAIN_TYPEHASH,
                    keccak256(bytes(name)),
                    keccak256(bytes(version)),
                    chainId,
                    address(this)
                )
            );
    }

    /**
     * @notice Recover signer's address from a EIP712 signature
     * @param domainSeparator   Domain separator
     * @param v                 v of the signature
     * @param r                 r of the signature
     * @param s                 s of the signature
     * @param typeHashAndData   Type hash concatenated with data
     * @return Signer's address
     */
    function recover(
        bytes32 domainSeparator,
        uint8 v,
        bytes32 r,
        bytes32 s,
        bytes memory typeHashAndData
    ) internal pure returns (address) {
        bytes32 digest = keccak256(
            abi.encodePacked(
                "\x19\x01",
                domainSeparator,
                keccak256(typeHashAndData)
            )
        );
        return ECRecover.recover(digest, v, r, s);
    }
}

/**
 *  SourceUnit: cypherdog/contracts/CypherDogToken.sol
 */

////// SPDX-License-Identifier-FLATTEN-SUPPRESS-WARNING: MIT

pragma solidity ^0.8.0;

/**
    Internal functions from ERC20 token to be used for IEP2612 and IEP3009
 */
abstract contract ERC20Internal {
    // internal _approve call
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual;

    // internal _transfer call
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual;
}

/**
 *  SourceUnit: cypherdog/contracts/CypherDogToken.sol
 */

////// SPDX-License-Identifier-FLATTEN-SUPPRESS-WARNING: MIT

pragma solidity ^0.8.0;

/**
    Ownership contract
    Modified https://eips.ethereum.org/EIPS/eip-173
    A confirmation of ownership transfer has been added
     to prevent ownership from being transferred to the wrong address
 */
contract Ownable {
    /// Current contract owner
    address public owner;
    /// New contract owner to be confirmed
    address public newOwner;
    /// Emit on every owner change
    event OwnershipChanged(address indexed from, address indexed to);

    /**
        Set default owner as contract deployer
     */
    constructor() {
        owner = msg.sender;
    }

    /**
        Use this modifier to limit function to contract owner
     */
    modifier onlyOwner() {
        require(msg.sender == owner, "Only for Owner");
        _;
    }

    /**
        Prepare to change ownersip. New owner need to confirm it.
        @param user address delegated to be new contract owner
     */
    function giveOwnership(address user) external onlyOwner {
        require(user != address(0x0), "renounceOwnership() instead");
        newOwner = user;
    }

    /**
        Accept contract ownership by new owner.
     */
    function acceptOwnership() external {
        require(
            newOwner != address(0x0) && msg.sender == newOwner,
            "Only newOwner can accept"
        );
        emit OwnershipChanged(owner, newOwner);
        owner = newOwner;
        newOwner = address(0x0);
    }

    /**
        Renounce ownership of the contract.
        Any function uses "onlyOwner" modifier will be inaccessible.
     */
    function renounceOwnership() external onlyOwner {
        emit OwnershipChanged(owner, address(0x0));
        owner = address(0x0);
    }
}

/**
 *  SourceUnit: cypherdog/contracts/CypherDogToken.sol
 */

////// SPDX-License-Identifier-FLATTEN-SUPPRESS-WARNING: MIT

pragma solidity ^0.8.0;

/**
    Full ERC20 interface
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount)
        external
        returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * ////////IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
}

/**
 *  SourceUnit: cypherdog/contracts/CypherDogToken.sol
 */

////// SPDX-License-Identifier-FLATTEN-SUPPRESS-WARNING: MIT
// Following https://eips.ethereum.org/EIPS/eip-3009
// based on https://github.com/CoinbaseStablecoin/eip-3009

pragma solidity ^0.8.0;

////import "./ERC20Internal.sol";
////import "./EIP712.sol";

/**
    EIP3009 implementation
 */
abstract contract ERC3009 is ERC20Internal, EIP712Domain {
    // events
    event AuthorizationUsed(address indexed authorizer, bytes32 indexed nonce);
    event AuthorizationCanceled(
        address indexed authorizer,
        bytes32 indexed nonce
    );

    // constant typehashes
    // keccak256("TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)")
    bytes32 public constant TRANSFER_WITH_AUTHORIZATION_TYPEHASH =
        0x7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267;

    // keccak256("ReceiveWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)")
    bytes32 public constant RECEIVE_WITH_AUTHORIZATION_TYPEHASH =
        0xd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8;

    // keccak256("CancelAuthorization(address authorizer,bytes32 nonce)")
    bytes32 public constant CANCEL_AUTHORIZATION_TYPEHASH =
        0x158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429;

    // errors
    error AuthorizationReused();
    error CallerMustBeThePayee();
    error AuthorizationIsNotYetValid();
    error AuthorizationExpired();
    /**
     * @dev authorizer address => nonce => state (true = used / false = unused)
     */
    mapping(address => mapping(bytes32 => bool)) internal _authorizationStates;

    // viewers

    /**
     * @notice Returns the state of an authorization
     * @dev Nonces are randomly generated 32-byte data unique to the authorizer's
     * address
     * @param authorizer    Authorizer's address
     * @param nonce         Nonce of the authorization
     * @return True if the nonce is used
     */
    function authorizationState(address authorizer, bytes32 nonce)
        external
        view
        returns (bool)
    {
        return _authorizationStates[authorizer][nonce];
    }

    // functions

    /**
     * @notice Execute a transfer with a signed authorization
     * @param from          Payer's address (Authorizer)
     * @param to            Payee's address
     * @param value         Amount to be transferred
     * @param validAfter    The time after which this is valid (unix time)
     * @param validBefore   The time before which this is valid (unix time)
     * @param nonce         Unique nonce
     * @param v             v of the signature
     * @param r             r of the signature
     * @param s             s of the signature
     */
    function transferWithAuthorization(
        address from,
        address to,
        uint256 value,
        uint256 validAfter,
        uint256 validBefore,
        bytes32 nonce,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external {
        _transferWithAuthorization(
            TRANSFER_WITH_AUTHORIZATION_TYPEHASH,
            from,
            to,
            value,
            validAfter,
            validBefore,
            nonce,
            v,
            r,
            s
        );
    }

    /**
     * @notice Receive a transfer with a signed authorization from the payer
     * @dev This has an additional check to ensure that the payee's address matches
     * the caller of this function to prevent front-running attacks. (See security
     * considerations)
     * @param from          Payer's address (Authorizer)
     * @param to            Payee's address
     * @param value         Amount to be transferred
     * @param validAfter    The time after which this is valid (unix time)
     * @param validBefore   The time before which this is valid (unix time)
     * @param nonce         Unique nonce
     * @param v             v of the signature
     * @param r             r of the signature
     * @param s             s of the signature
     */
    function receiveWithAuthorization(
        address from,
        address to,
        uint256 value,
        uint256 validAfter,
        uint256 validBefore,
        bytes32 nonce,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external {
        if (to != msg.sender) revert CallerMustBeThePayee();

        _transferWithAuthorization(
            RECEIVE_WITH_AUTHORIZATION_TYPEHASH,
            from,
            to,
            value,
            validAfter,
            validBefore,
            nonce,
            v,
            r,
            s
        );
    }

    function _transferWithAuthorization(
        bytes32 typeHash,
        address from,
        address to,
        uint256 value,
        uint256 validAfter,
        uint256 validBefore,
        bytes32 nonce,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 timeNow = block.timestamp;

        if (timeNow < validAfter) revert AuthorizationIsNotYetValid();
        if (timeNow > validBefore) revert AuthorizationExpired();
        if (_authorizationStates[from][nonce]) revert AuthorizationReused();

        bytes memory data = abi.encode(
            typeHash,
            from,
            to,
            value,
            validAfter,
            validBefore,
            nonce
        );
        if (EIP712.recover(DOMAIN_SEPARATOR, v, r, s, data) != from)
            revert InvalidSignature();

        _authorizationStates[from][nonce] = true;
        emit AuthorizationUsed(from, nonce);

        _transfer(from, to, value);
    }

    /**
     * @notice Attempt to cancel an authorization
     * @param authorizer    Authorizer's address
     * @param nonce         Nonce of the authorization
     * @param v             v of the signature
     * @param r             r of the signature
     * @param s             s of the signature
     */
    function cancelAuthorization(
        address authorizer,
        bytes32 nonce,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external {
        if (_authorizationStates[authorizer][nonce])
            revert AuthorizationReused();

        bytes memory data = abi.encode(
            CANCEL_AUTHORIZATION_TYPEHASH,
            authorizer,
            nonce
        );
        if (EIP712.recover(DOMAIN_SEPARATOR, v, r, s, data) != authorizer)
            revert InvalidSignature();

        _authorizationStates[authorizer][nonce] = true;
        emit AuthorizationCanceled(authorizer, nonce);
    }
}

/**
 *  SourceUnit: cypherdog/contracts/CypherDogToken.sol
 */

////// SPDX-License-Identifier-FLATTEN-SUPPRESS-WARNING: MIT
// Following https://eips.ethereum.org/EIPS/eip-2612
// based on https://github.com/CoinbaseStablecoin/eip-3009

pragma solidity ^0.8.0;

////import "./ERC20Internal.sol";
////import "./EIP712.sol";

/**
    EIP2612 implementation
 */
abstract contract ERC2612 is ERC20Internal, EIP712Domain {
    // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)")
    bytes32 public constant PERMIT_TYPEHASH =
        0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;

    mapping(address => uint256) internal _nonces;

    error PermitExpired();

    /**
     * @notice Nonces for permit
     * @param owner Token owner's address
     * @return Next nonce
     */
    function nonces(address owner) external view returns (uint256) {
        return _nonces[owner];
    }

    /**
     * @notice update allowance with a signed permit
     * @param owner     Token owner's address (Authorizer)
     * @param spender   Spender's address
     * @param value     Amount of allowance
     * @param deadline  The time at which this expires (unix time)
     * @param v         v of the signature
     * @param r         r of the signature
     * @param s         s of the signature
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external {
        if (deadline < block.timestamp) revert PermitExpired();

        bytes memory data = abi.encode(
            PERMIT_TYPEHASH,
            owner,
            spender,
            value,
            _nonces[owner]++,
            deadline
        );
        if (EIP712.recover(DOMAIN_SEPARATOR, v, r, s, data) != owner)
            revert InvalidSignature();

        _approve(owner, spender, value);
    }
}

/**
 *  SourceUnit: cypherdog/contracts/CypherDogToken.sol
 */

////// SPDX-License-Identifier-FLATTEN-SUPPRESS-WARNING: MIT

pragma solidity ^0.8.0;

////import "./IERC20.sol";
////import "./Ownable.sol";

/**
    ERC20 token and native coin recovery functions
 */
abstract contract Recoverable is Ownable {
    error NothingToRecover();

    /// Recover native coin from contract
    function recoverETH() external onlyOwner {
        uint256 amt = address(this).balance;
        if (amt == 0) revert NothingToRecover();
        payable(owner).transfer(amt);
    }

    /// Recover ERC20 token from contract
    function recoverERC20(address token) external virtual onlyOwner {
        uint256 amt = IERC20(token).balanceOf(address(this));
        if (amt == 0) revert NothingToRecover();
        IERC20(token).transfer(owner, amt);
    }
}

/**
 *  SourceUnit: cypherdog/contracts/CypherDogToken.sol
 */

////// SPDX-License-Identifier-FLATTEN-SUPPRESS-WARNING: MIT
pragma solidity ^0.8.10;

////import "./IERC20.sol";
////import "./Recovery.sol";
////import "./ERC20Internal.sol";
////import "./ERC2612.sol";
////import "./ERC3009.sol";

contract CypherDogToken is
    IERC20,
    ERC20Internal,
    Recoverable,
    ERC2612,
    ERC3009
{
    /**
        part of transaction fee that will be burned until reach minTotalSupply
     */
    uint256 public burnFees = 5;

    /**
        Part of transaction fee that is distributed among hodlers
    */
    uint256 public constant rewardFees = 5;

    /**
        Minimum total supply, when reached burning stops
    */
    uint256 public immutable minTotalSupply;

    struct Summary {
        uint256 totalExcluded; // total held by excluded accounts
        uint256 totalHolding; // total held by holder accounts
        uint256 totalRewards; // total rewards
        uint256 totalSupply; // total supply
    }

    // metadata

    string public constant override name = "CYPHER.DOG";
    string public constant override symbol = "CDOG";
    uint8 public constant override decimals = 18;

    Summary public summary;

    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => uint256)) private _allowances;
    mapping(address => bool) private _excluded;

    // events

    /**
     * @dev Emitted when fees are updated
     * @param burnFees burn fees
     * @param rewardFees rewards fees
     */
    event FeesUpdated(uint256 burnFees, uint256 rewardFees);

    /**
     * @dev Emitted when account is excluded
     * @param account account address
     */
    event AccountExcluded(address indexed account);

    /**
     * @dev Emitted when total rewards amount is updated
     * @param totalRewards total rewards amount
     */
    event TotalRewardsUpdated(uint256 totalRewards);

    //
    // error messages
    //
    error OnlyExcludedCanBurn();
    error ZeroAddressDisallowed();
    error FeesToHigh();
    error AllowanceToLow();
    error NothingToChange();
    error BalanceToLow();
    error MinimumSupplyReached();

    //
    // modifiers
    //
    modifier notZeroAddress(address user) {
        if (user == address(0)) revert ZeroAddressDisallowed();
        _;
    }

    /**
      @dev Initializes the contract
      @param _minTotalSupply min total supply
      @param _supply total supply of tokens minted to owner
     */
    constructor(
        uint256 _minTotalSupply,
        uint256 _supply,
        address[] memory _excluded_
    ) {
        minTotalSupply = _minTotalSupply;

        // excludes owner account
        _excluded[msg.sender] = true;
        emit AccountExcluded(msg.sender);

        // mint supply
        _balances[msg.sender] = _supply;
        summary.totalExcluded = _supply;
        summary.totalSupply = _supply;
        emit Transfer(address(0), msg.sender, _supply);

        // adds predefined excluded accounts
        uint256 _excludedLen = _excluded_.length;
        uint256 index;
        for (index; index < _excludedLen; index++) {
            address user = _excluded_[index];
            _excluded[user] = true;
            emit AccountExcluded(user);
        }
        // initialize EIP712
        uint256 chainId = block.chainid;
        DOMAIN_SEPARATOR = EIP712.makeDomainSeparator(name, "1", chainId);
        CHAINID = chainId;
        EIP712_DOMAIN_TYPEHASH = EIP712.EIP712_DOMAIN_TYPEHASH;
    }

    //
    // external functions
    //

    /**
     * @dev Excludes account from paying fees
     * @param account account address
     */
    function excludeAccount(address account) external onlyOwner {
        if (_excluded[account]) revert NothingToChange();

        uint256 balance = _balances[account];
        if (balance > 0) {
            // we need to kind of _transferToExcludedAccount
            uint256 toExcluded = balance;
            if (summary.totalRewards != 0) {
                uint256 rewards = _calcRewards(account);
                toExcluded += rewards;
                _balances[account] += rewards;
            }
            summary.totalExcluded += toExcluded;
            summary.totalHolding -= balance;
        }

        _excluded[account] = true;

        emit AccountExcluded(account);
    }

    /**
     * @dev Approve spending limit
     * @param spender spender address
     * @param amount spending limit
     */
    function approve(address spender, uint256 amount)
        external
        override
        returns (bool)
    {
        _approve(msg.sender, spender, amount);

        return true;
    }

    /**
     * @dev Burns tokens from msg.sender
     * @param amount tokens amount
     */
    function burn(uint256 amount) external {
        if (!_excluded[msg.sender]) revert OnlyExcludedCanBurn();
        //ERC20 allows to send 0, so we allow to burn 0
        if (amount > 0) {
            if (_balances[msg.sender] < amount) revert BalanceToLow();

            summary.totalSupply -= amount;
            _balances[msg.sender] -= amount;

            summary.totalExcluded -= amount;
        }
        emit Transfer(msg.sender, address(0), amount);
    }

    /**
     * @dev Transfers tokens to recipient
     * @param recipient recipient address
     * @param amount tokens amount
     */
    function transfer(address recipient, uint256 amount)
        external
        override
        returns (bool)
    {
        _transfer(msg.sender, recipient, amount);

        return true;
    }

    /**
     * @dev Transfers tokens from sender to recipient
     * @param sender sender address
     * @param recipient recipient address
     * @param amount tokens amount
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external override returns (bool) {
        uint256 _allowance = _allowances[sender][msg.sender];
        if (_allowance < amount) revert AllowanceToLow();
        if (_allowance < type(uint256).max) {
            unchecked {
                _allowance -= amount;
            }
            _allowances[sender][msg.sender] = _allowance;
        }

        _transfer(sender, recipient, amount);
        return true;
    }

    //
    // external functions (views)
    //

    /**
     * @dev Gets excluded account
     * @param account account address
     */
    function getExcludedAccount(address account) external view returns (bool) {
        return (_excluded[account]);
    }

    /**
     * @dev Gets total supply
     * @return total supply
     */
    function totalSupply() external view override returns (uint256) {
        return summary.totalSupply;
    }

    /**
     * @dev Gets allowance
     * @param sender address
     * @param spender address
     * @return allowance
     */
    function allowance(address sender, address spender)
        external
        view
        override
        returns (uint256)
    {
        return _allowances[sender][spender];
    }

    /**
     * @dev Gets balance of
     * @param account account address
     * @return result account balance
     */
    function balanceOf(address account)
        external
        view
        override
        returns (uint256)
    {
        return _balances[account] + _calcRewards(account);
    }

    /**
     * @dev Gets balance summary
     * @param account account address
     */
    function getBalanceSummary(address account)
        external
        view
        returns (
            uint256 totalBalance,
            uint256 holdingBalance,
            uint256 totalRewards
        )
    {
        holdingBalance = _balances[account];
        totalRewards = _calcRewards(account);
        totalBalance = holdingBalance + totalRewards;

        return (totalBalance, holdingBalance, totalRewards);
    }

    //
    // private functions
    //

    function _approve(
        address sender,
        address spender,
        uint256 amount
    ) internal override notZeroAddress(spender) {
        _allowances[sender][spender] = amount;

        emit Approval(sender, spender, amount);
    }

    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal override notZeroAddress(sender) notZeroAddress(recipient) {
        //ERC20 allows to send 0 tokens
        if (amount > 0) {
            if (_excluded[sender]) {
                if (_excluded[recipient]) {
                    _transferBetweenExcludedAccounts(sender, recipient, amount);
                } else _transferFromExcludedAccount(sender, recipient, amount);
            } else if (_excluded[recipient]) {
                _transferToExcludedAccount(sender, recipient, amount);
            } else _transferBetweenHolderAccounts(sender, recipient, amount);
        } else emit Transfer(sender, recipient, amount);
    }

    function _transferBetweenHolderAccounts(
        address sender,
        address recipient,
        uint256 amount
    ) private {
        uint256 senderAmount;
        uint256 recipientAmount = amount;
        uint256 burnFee;
        uint256 totalFee;
        Summary memory s = summary;
        uint256 totalSupply_ = s.totalSupply;

        (totalFee, burnFee) = _calcTransferFees(amount);

        (totalSupply_, totalFee, burnFee) = _matchTotalSupplyWithFees(
            totalSupply_,
            totalFee,
            burnFee
        );

        senderAmount = amount + totalFee;
        // appends total rewards
        if (s.totalRewards != 0) {
            uint256 inclRewards = s.totalHolding + s.totalRewards;
            unchecked {
                senderAmount = (senderAmount * s.totalHolding) / inclRewards;
                recipientAmount =
                    (recipientAmount * s.totalHolding) /
                    inclRewards;
                totalFee = (totalFee * s.totalHolding) / inclRewards;
            }
        }
        uint256 currSender = _balances[sender];
        if (currSender < senderAmount) revert BalanceToLow();
        unchecked {
            _balances[sender] = currSender - senderAmount;
            _balances[recipient] += recipientAmount;

            summary.totalSupply = totalSupply_;
            summary.totalHolding = s.totalHolding - totalFee;
        }
        emit Transfer(sender, recipient, amount);
        if (burnFee > 0) {
            emit Transfer(sender, address(0), burnFee);
        }

        _updateTotalRewards();
    }

    function _transferFromExcludedAccount(
        address sender,
        address recipient,
        uint256 amount
    ) private {
        uint256 currSender = _balances[sender];
        if (currSender < amount) revert BalanceToLow();
        unchecked {
            _balances[sender] = currSender - amount;
            _balances[recipient] += amount;

            summary.totalExcluded -= amount;
            summary.totalHolding += amount;
        }
        emit Transfer(sender, recipient, amount);

        _updateTotalRewards();
    }

    function _transferToExcludedAccount(
        address sender,
        address recipient,
        uint256 amount
    ) private {
        uint256 totalFee;
        uint256 burnFee;
        Summary memory s = summary;
        uint256 totalSupply_ = s.totalSupply;

        (totalFee, burnFee) = _calcTransferFees(amount);

        (totalSupply_, totalFee, burnFee) = _matchTotalSupplyWithFees(
            totalSupply_,
            totalFee,
            burnFee
        );

        uint256 senderAmount = amount + totalFee;

        // append total rewards
        if (s.totalRewards != 0) {
            uint256 totalHolding = s.totalHolding;
            unchecked {
                senderAmount =
                    (senderAmount * totalHolding) /
                    (totalHolding + s.totalRewards);
            }
        }
        uint256 currSender = _balances[sender];
        if (currSender < senderAmount) revert BalanceToLow();
        unchecked {
            _balances[sender] = currSender - senderAmount;
            _balances[recipient] += amount;

            summary.totalSupply = totalSupply_;
            summary.totalExcluded = s.totalExcluded + amount;
            summary.totalHolding = s.totalHolding - senderAmount;
        }
        emit Transfer(sender, recipient, amount);
        if (burnFee > 0) {
            emit Transfer(sender, address(0), burnFee);
        }
        _updateTotalRewards();
    }

    function _transferBetweenExcludedAccounts(
        address sender,
        address recipient,
        uint256 amount
    ) private {
        uint256 currSender = _balances[sender];
        if (currSender < amount) revert BalanceToLow();
        unchecked {
            _balances[sender] = currSender - amount;
            _balances[recipient] += amount;
        }
        emit Transfer(sender, recipient, amount);
    }

    function _calcTransferFees(uint256 amount)
        private
        view
        returns (uint256 totalFee, uint256 burnFee)
    {
        burnFee = _percent(amount, burnFees);
        totalFee = _percent(amount, rewardFees) + burnFee;
    }

    function _updateTotalRewards() private {
        // totalRewards = totalSupply - totalExcluded - totalHolding
        uint256 totalRewards = summary.totalSupply -
            summary.totalExcluded -
            summary.totalHolding;

        if (totalRewards != summary.totalRewards) {
            summary.totalRewards = totalRewards;

            emit TotalRewardsUpdated(totalRewards);
        }
    }

    function _matchTotalSupplyWithFees(
        uint256 totalSupply_,
        uint256 totalFee,
        uint256 burnFee
    )
        private
        returns (
            uint256,
            uint256,
            uint256
        )
    {
        if (burnFee != 0) {
            uint256 newTotalSupply = totalSupply_ - burnFee;

            if (newTotalSupply >= minTotalSupply) {
                totalSupply_ = newTotalSupply;
            } else {
                // turn off burn fee, this will happen only once
                burnFees = 0;
                // are we still over minimum at start?
                if (totalSupply_ > minTotalSupply) {
                    totalSupply_ = minTotalSupply;
                    // refund burn fee difference
                    uint256 diff = minTotalSupply - newTotalSupply;
                    burnFee -= diff;
                    totalFee += diff;
                } else {
                    // it was already under minimum - refund burn fee
                    totalFee -= burnFee;
                    burnFee = 0;
                }
            }
        }

        return (totalSupply_, totalFee, burnFee);
    }

    //
    // private functions (views)
    //

    function _calcRewards(address account)
        private
        view
        returns (uint256 result)
    {
        Summary memory s = summary;
        if (
            !_excluded[account] && s.totalRewards != 0 // only for holders
        ) {
            result = (s.totalRewards * _balances[account]) / s.totalHolding;
        }
    }

    //
    // private functions (pure)
    //

    /**
        Calculate given percent (1/100) of amount.
        @param amount to divide
        @param pct percent to calculate
        @return result caluclated value
     */
    function _percent(uint256 amount, uint256 pct)
        internal
        pure
        returns (uint256 result)
    {
        if (pct == 0 || amount == 0) {
            return result;
        }
        result = (amount * pct) / 100;
    }
}

Settings
{
  "remappings": [],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "evmVersion": "istanbul",
  "libraries": {},
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"_minTotalSupply","type":"uint256"},{"internalType":"uint256","name":"_supply","type":"uint256"},{"internalType":"address[]","name":"_excluded_","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AllowanceToLow","type":"error"},{"inputs":[],"name":"AuthorizationExpired","type":"error"},{"inputs":[],"name":"AuthorizationIsNotYetValid","type":"error"},{"inputs":[],"name":"AuthorizationReused","type":"error"},{"inputs":[],"name":"BalanceToLow","type":"error"},{"inputs":[],"name":"CallerMustBeThePayee","type":"error"},{"inputs":[],"name":"FeesToHigh","type":"error"},{"inputs":[],"name":"InvalidS","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"InvalidV","type":"error"},{"inputs":[],"name":"MinimumSupplyReached","type":"error"},{"inputs":[],"name":"NothingToChange","type":"error"},{"inputs":[],"name":"NothingToRecover","type":"error"},{"inputs":[],"name":"OnlyExcludedCanBurn","type":"error"},{"inputs":[],"name":"PermitExpired","type":"error"},{"inputs":[],"name":"ZeroAddressDisallowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"AccountExcluded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationUsed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"burnFees","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardFees","type":"uint256"}],"name":"FeesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"totalRewards","type":"uint256"}],"name":"TotalRewardsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"CANCEL_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CHAINID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EIP712_DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RECEIVE_WITH_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TRANSFER_WITH_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"authorizationState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burnFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"cancelAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"excludeAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getBalanceSummary","outputs":[{"internalType":"uint256","name":"totalBalance","type":"uint256"},{"internalType":"uint256","name":"holdingBalance","type":"uint256"},{"internalType":"uint256","name":"totalRewards","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getExcludedAccount","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"giveOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"receiveWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recoverETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"summary","outputs":[{"internalType":"uint256","name":"totalExcluded","type":"uint256"},{"internalType":"uint256","name":"totalHolding","type":"uint256"},{"internalType":"uint256","name":"totalRewards","type":"uint256"},{"internalType":"uint256","name":"totalSupply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"transferWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a060405260056007553480156200001657600080fd5b50604051620023d1380380620023d1833981016040819052620000399162000262565b600080546001600160a01b0319163390811782556080859052808252600e6020526040808320805460ff191660011790555190916000805160206200239183398151915291a2336000818152600c602090815260408083208690556008869055600b869055518581527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3805160005b818110156200014f576000838281518110620000f257620000f26200034b565b6020908102919091018101516001600160a01b0381166000818152600e9093526040808420805460ff1916600117905551919350916000805160206200239183398151915291a25080620001468162000361565b915050620000d2565b6000469050620001a76040518060400160405280600a8152602001694359504845522e444f4760b01b815250604051806040016040528060018152602001603160f81b81525083620001cc60201b6200100b1760201c565b6002556003555050600080516020620023b1833981519152600455506200038b915050565b825160209384012082519284019290922060408051600080516020620023b18339815191528187015280820194909452606084019190915260808301919091523060a0808401919091528151808403909101815260c09092019052805191012090565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b03811681146200025d57600080fd5b919050565b6000806000606084860312156200027857600080fd5b835160208086015160408701519295509350906001600160401b0380821115620002a157600080fd5b818701915087601f830112620002b657600080fd5b815181811115620002cb57620002cb6200022f565b8060051b604051601f19603f83011681018181108582111715620002f357620002f36200022f565b60405291825284820192508381018501918a8311156200031257600080fd5b938501935b828510156200033b576200032b8562000245565b8452938501939285019262000317565b8096505050505050509250925092565b634e487b7160e01b600052603260045260246000fd5b60006000198214156200038457634e487b7160e01b600052601160045260246000fd5b5060010190565b608051611fd5620003bc6000396000818161039401528181611ae401528181611b180152611b400152611fd56000f3fe608060405234801561001057600080fd5b50600436106102275760003560e01c80637f2eecc311610130578063d4ee1d90116100b8578063e3a0a1481161007c578063e3a0a1481461059b578063e3ee160e146105ae578063e94a0102146105c1578063ef55bec6146105fa578063f2cc0c181461060d57600080fd5b8063d4ee1d90146104e9578063d505accf146104fc578063d91694871461050f578063da498b8314610536578063dd62ed3e1461056257600080fd5b8063a0cc6a68116100ff578063a0cc6a6814610467578063a9059cbb1461048e578063b16a867c146104a1578063c7977be7146104d7578063cc79f97b146104e057600080fd5b80637f2eecc3146103df5780638da5cb5b1461040657806395d89b41146104315780639e8c708e1461045457600080fd5b80633644e515116101b357806370a082311161018257806370a082311461036c578063715018a61461037f57806379ba50971461038757806379db63461461038f5780637ecebe00146103b657600080fd5b80633644e5151461033457806340f6ac311461033d57806342966c68146103465780635a049a701461035957600080fd5b806323b872dd116101fa57806323b872dd146102aa5780632bf8e8f6146102bd5780632d380315146102c557806330adf81f146102f3578063313ce5671461031a57600080fd5b80630614117a1461022c57806306fdde0314610236578063095ea7b31461027557806318160ddd14610298575b600080fd5b610234610620565b005b61025f6040518060400160405280600a8152602001694359504845522e444f4760b01b81525081565b60405161026c9190611be0565b60405180910390f35b610288610283366004611c51565b6106af565b604051901515815260200161026c565b600b545b60405190815260200161026c565b6102886102b8366004611c7b565b6106c6565b61029c600581565b6102d86102d3366004611cb7565b610757565b6040805193845260208401929092529082015260600161026c565b61029c7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b610322601281565b60405160ff909116815260200161026c565b61029c60025481565b61029c60075481565b610234610354366004611cd2565b61078e565b610234610367366004611cfc565b610876565b61029c61037a366004611cb7565b6109b2565b6102346109e0565b610234610a54565b61029c7f000000000000000000000000000000000000000000000000000000000000000081565b61029c6103c4366004611cb7565b6001600160a01b031660009081526005602052604090205490565b61029c7fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de881565b600054610419906001600160a01b031681565b6040516001600160a01b03909116815260200161026c565b61025f6040518060400160405280600481526020016343444f4760e01b81525081565b610234610462366004611cb7565b610b28565b61029c7f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a226781565b61028861049c366004611c51565b610c59565b600854600954600a54600b546104b79392919084565b60408051948552602085019390935291830152606082015260800161026c565b61029c60045481565b61029c60035481565b600154610419906001600160a01b031681565b61023461050a366004611d4a565b610c66565b61029c7f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742981565b610288610544366004611cb7565b6001600160a01b03166000908152600e602052604090205460ff1690565b61029c610570366004611db4565b6001600160a01b039182166000908152600d6020908152604080832093909416825291909152205490565b6102346105a9366004611cb7565b610d76565b6102346105bc366004611de7565b610e18565b6102886105cf366004611c51565b6001600160a01b03919091166000908152600660209081526040808320938352929052205460ff1690565b610234610608366004611de7565b610e55565b61023461061b366004611cb7565b610eb0565b6000546001600160a01b031633146106535760405162461bcd60e51b815260040161064a90611e65565b60405180910390fd5b47806106725760405163157474a960e31b815260040160405180910390fd5b600080546040516001600160a01b039091169183156108fc02918491818181858888f193505050501580156106ab573d6000803e3d6000fd5b5050565b60006106bc33848461107f565b5060015b92915050565b6001600160a01b0383166000908152600d602090815260408083203384529091528120548281101561070b5760405163a628c8ff60e01b815260040160405180910390fd5b600019811015610741576001600160a01b0385166000908152600d60209081526040808320338452909152902090839003908190555b61074c85858561110a565b506001949350505050565b6001600160a01b0381166000908152600c60205260408120548161077a84611237565b90506107868183611ea3565b949193509150565b336000908152600e602052604090205460ff166107be57604051630a7787c560e11b815260040160405180910390fd5b801561084d57336000908152600c60205260409020548111156107f457604051633d57bedb60e01b815260040160405180910390fd5b80600860030160008282546108099190611ebb565b9091555050336000908152600c60205260408120805483929061082d908490611ebb565b909155505060088054829190600090610847908490611ebb565b90915550505b6040518181526000903390600080516020611f808339815191529060200160405180910390a350565b6001600160a01b038516600090815260066020908152604080832087845290915290205460ff16156108bb57604051630b45e91560e11b815260040160405180910390fd5b604080517f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742960208201526001600160a01b03871691810191909152606081018590526000906080016040516020818303038152906040529050856001600160a01b031661092d600254868686866112de565b6001600160a01b03161461095457604051638baa579f60e01b815260040160405180910390fd5b6001600160a01b0386166000818152600660209081526040808320898452909152808220805460ff19166001179055518792917f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d8191a3505050505050565b60006109bd82611237565b6001600160a01b0383166000908152600c60205260409020546106c09190611ea3565b6000546001600160a01b03163314610a0a5760405162461bcd60e51b815260040161064a90611e65565b600080546040516001600160a01b03909116907f0384899bd253d83b23daa4d29aaa2efe0563d1132b43101e9ad667235aeb951b908390a3600080546001600160a01b0319169055565b6001546001600160a01b031615801590610a7857506001546001600160a01b031633145b610ac45760405162461bcd60e51b815260206004820152601860248201527f4f6e6c79206e65774f776e65722063616e206163636570740000000000000000604482015260640161064a565b600154600080546040516001600160a01b0393841693909116917f0384899bd253d83b23daa4d29aaa2efe0563d1132b43101e9ad667235aeb951b91a360018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6000546001600160a01b03163314610b525760405162461bcd60e51b815260040161064a90611e65565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610b99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbd9190611ed2565b905080610bdd5760405163157474a960e31b815260040160405180910390fd5b60005460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529083169063a9059cbb906044016020604051808303816000875af1158015610c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c549190611eeb565b505050565b60006106bc33848461110a565b42841015610c875760405163068568f360e21b815260040160405180910390fd5b6001600160a01b038716600090815260056020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a919086610cd483611f0d565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040529050876001600160a01b0316610d3a600254868686866112de565b6001600160a01b031614610d6157604051638baa579f60e01b815260040160405180910390fd5b610d6c88888861107f565b5050505050505050565b6000546001600160a01b03163314610da05760405162461bcd60e51b815260040161064a90611e65565b6001600160a01b038116610df65760405162461bcd60e51b815260206004820152601b60248201527f72656e6f756e63654f776e657273686970282920696e73746561640000000000604482015260640161064a565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b610e4a7f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a22678a8a8a8a8a8a8a8a8a611340565b505050505050505050565b6001600160a01b0388163314610e7e57604051639301fec360e01b815260040160405180910390fd5b610e4a7fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de88a8a8a8a8a8a8a8a8a611340565b6000546001600160a01b03163314610eda5760405162461bcd60e51b815260040161064a90611e65565b6001600160a01b0381166000908152600e602052604090205460ff1615610f14576040516328e9001b60e01b815260040160405180910390fd5b6001600160a01b0381166000908152600c60205260409020548015610fbe57600a54819015610f88576000610f4884611237565b9050610f548183611ea3565b6001600160a01b0385166000908152600c6020526040812080549294508392909190610f81908490611ea3565b9091555050505b8060086000016000828254610f9d9190611ea3565b909155505060098054839190600090610fb7908490611ebb565b9091555050505b6001600160a01b0382166000818152600e6020526040808220805460ff19166001179055517fc43ac1ed89a6611862c89bd827657f1406e2a407bc2be9eaa4844539d0b583ed9190a25050565b8251602093840120825192840192909220604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8187015280820194909452606084019190915260808301919091523060a0808401919091528151808403909101815260c09092019052805191012090565b816001600160a01b0381166110a757604051637e9a8a9560e01b815260040160405180910390fd5b6001600160a01b038481166000818152600d602090815260408083209488168084529482529182902086905590518581527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a350505050565b826001600160a01b03811661113257604051637e9a8a9560e01b815260040160405180910390fd5b826001600160a01b03811661115a57604051637e9a8a9560e01b815260040160405180910390fd5b82156111f4576001600160a01b0385166000908152600e602052604090205460ff16156111bd576001600160a01b0384166000908152600e602052604090205460ff16156111b2576111ad8585856114d0565b611230565b6111ad858585611558565b6001600160a01b0384166000908152600e602052604090205460ff16156111e9576111ad858585611607565b6111ad858585611777565b836001600160a01b0316856001600160a01b0316600080516020611f808339815191528560405161122791815260200190565b60405180910390a35b5050505050565b604080516080810182526008548152600954602080830191909152600a5482840152600b5460608301526001600160a01b0384166000908152600e9091529182205460ff1615801561128c5750604081015115155b156112d8578060200151600c6000856001600160a01b03166001600160a01b031681526020019081526020016000205482604001516112cb9190611f28565b6112d59190611f5d565b91505b50919050565b60008086838051906020012060405160200161131192919061190160f01b81526002810192909252602282015260420190565b6040516020818303038152906040528051906020012090506113358187878761192d565b979650505050505050565b428681101561136257604051635bc294d160e11b815260040160405180910390fd5b8581111561138357604051630f05f5bf60e01b815260040160405180910390fd5b6001600160a01b038a16600090815260066020908152604080832088845290915290205460ff16156113c857604051630b45e91560e11b815260040160405180910390fd5b60408051602081018d90526001600160a01b03808d1692820192909252908a1660608201526080810189905260a0810188905260c0810187905260e081018690526000906101000160405160208183030381529060405290508a6001600160a01b031661143a600254878787866112de565b6001600160a01b03161461146157604051638baa579f60e01b815260040160405180910390fd5b6001600160a01b038b1660008181526006602090815260408083208a8452909152808220805460ff19166001179055518892917f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a591a36114c28b8b8b61110a565b505050505050505050505050565b6001600160a01b0383166000908152600c60205260409020548181101561150a57604051633d57bedb60e01b815260040160405180910390fd5b6001600160a01b038085166000818152600c60205260408082208686039055928616808252908390208054860190559151600080516020611f80833981519152906110fc9086815260200190565b6001600160a01b0383166000908152600c60205260409020548181101561159257604051633d57bedb60e01b815260040160405180910390fd5b6001600160a01b038085166000818152600c602052604080822086860390559286168082529083902080548601905560088054869003905560098054860190559151600080516020611f80833981519152906115f19086815260200190565b60405180910390a3611601611a34565b50505050565b6040805160808101825260085481526009546020820152600a5491810191909152600b5460608201819052600091829161164085611a9c565b9094509250611650818585611aca565b9095509350905060006116638587611ea3565b90508260400151600014611692576020830151604084015181018282028161168d5761168d611f47565b049150505b6001600160a01b0388166000908152600c6020526040902054818110156116cc57604051633d57bedb60e01b815260040160405180910390fd5b6001600160a01b03808a166000818152600c602090815260408083208787039055938c168083529184902080548c019055600b87905587518b016008558701518590036009559151600080516020611f8083398151915290611731908b815260200190565b60405180910390a3841561176f576040518581526000906001600160a01b038b1690600080516020611f808339815191529060200160405180910390a35b610e4a611a34565b6040805160808101825260085481526009546020820152600a5491810191909152600b54606082018190526000918391839182916117b485611a9c565b945092506117c3818486611aca565b9550935090506117d38388611ea3565b95508160400151600014611843576000826040015183602001516117f79190611ea3565b905080836020015188028161180e5761180e611f47565b04965080836020015187028161182657611826611f47565b04955080836020015185028161183e5761183e611f47565b049350505b6001600160a01b0389166000908152600c60205260409020548681101561187d57604051633d57bedb60e01b815260040160405180910390fd5b6001600160a01b03808b166000818152600c602090815260408083208c87039055938d168083529184902080548b019055600b8690558601518790036009559151600080516020611f80833981519152906118db908c815260200190565b60405180910390a38415611919576040518581526000906001600160a01b038c1690600080516020611f808339815191529060200160405180910390a35b611921611a34565b50505050505050505050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115611970576040516308183ce960e31b815260040160405180910390fd5b601b8460ff1610806119855750601c8460ff16115b156119a35760405163119bce3960e01b815260040160405180910390fd5b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa1580156119f7573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611a2b57604051638baa579f60e01b815260040160405180910390fd5b95945050505050565b600954600854600b5460009291611a4a91611ebb565b611a549190611ebb565b600a549091508114611a9957600a8190556040518181527f8629690313970e9e42939fc905246bd1ff3a69dae5efc961f8b40a91a838dffe9060200160405180910390a15b50565b600080611aab83600754611bac565b905080611ab9846005611bac565b611ac39190611ea3565b9150915091565b600080808315611ba0576000611ae08588611ebb565b90507f00000000000000000000000000000000000000000000000000000000000000008110611b1157809650611b9e565b60006007557f0000000000000000000000000000000000000000000000000000000000000000871115611b8d577f000000000000000000000000000000000000000000000000000000000000000096506000611b6d8289611ebb565b9050611b798187611ebb565b9550611b858188611ea3565b965050611b9e565b611b978587611ebb565b9550600094505b505b50939492935090919050565b6000811580611bb9575082155b15611bc3576106c0565b6064611bcf8385611f28565b611bd99190611f5d565b9392505050565b600060208083528351808285015260005b81811015611c0d57858101830151858201604001528201611bf1565b81811115611c1f576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b0381168114611c4c57600080fd5b919050565b60008060408385031215611c6457600080fd5b611c6d83611c35565b946020939093013593505050565b600080600060608486031215611c9057600080fd5b611c9984611c35565b9250611ca760208501611c35565b9150604084013590509250925092565b600060208284031215611cc957600080fd5b611bd982611c35565b600060208284031215611ce457600080fd5b5035919050565b803560ff81168114611c4c57600080fd5b600080600080600060a08688031215611d1457600080fd5b611d1d86611c35565b945060208601359350611d3260408701611ceb565b94979396509394606081013594506080013592915050565b600080600080600080600060e0888a031215611d6557600080fd5b611d6e88611c35565b9650611d7c60208901611c35565b95506040880135945060608801359350611d9860808901611ceb565b925060a0880135915060c0880135905092959891949750929550565b60008060408385031215611dc757600080fd5b611dd083611c35565b9150611dde60208401611c35565b90509250929050565b60008060008060008060008060006101208a8c031215611e0657600080fd5b611e0f8a611c35565b9850611e1d60208b01611c35565b975060408a0135965060608a0135955060808a0135945060a08a01359350611e4760c08b01611ceb565b925060e08a013591506101008a013590509295985092959850929598565b6020808252600e908201526d27b7363c903337b91027bbb732b960911b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60008219821115611eb657611eb6611e8d565b500190565b600082821015611ecd57611ecd611e8d565b500390565b600060208284031215611ee457600080fd5b5051919050565b600060208284031215611efd57600080fd5b81518015158114611bd957600080fd5b6000600019821415611f2157611f21611e8d565b5060010190565b6000816000190483118215151615611f4257611f42611e8d565b500290565b634e487b7160e01b600052601260045260246000fd5b600082611f7a57634e487b7160e01b600052601260045260246000fd5b50049056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220f2055fbb0f74d201b89980371315d0ae685ac51285b213ec27d920defa54ca3b64736f6c634300080a0033c43ac1ed89a6611862c89bd827657f1406e2a407bc2be9eaa4844539d0b583ed8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f00000000000000000000000000000000000000000cecb8f27f4200f3a00000000000000000000000000000000000000000000000204fce5e3e2502611000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000000000000000000000cecb8f27f4200f3a00000000000000000000000000000000000000000000000204fce5e3e2502611000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _minTotalSupply (uint256): 4000000000000000000000000000
Arg [1] : _supply (uint256): 10000000000000000000000000000

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000cecb8f27f4200f3a0000000
Arg [1] : 0000000000000000000000000000000000000000204fce5e3e25026110000000
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.