Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0x4Ff57e25eeB7AFfbBB060e0BAd2E1759eFc8BeC4
Balance 0 ETH
Nonce 1
Code Size 6394 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

6394 bytes
0x608060405260043610610164575f3560e01c80638da5cb5b116100cd578063b51816c211610087578063dce259b411610062578063dce259b414610455578063dd62ed3e14610474578063e154ebc2146104b8578063f2fde38b146104e6575f80fd5b8063b51816c214610403578063d123685c14610422578063db32733014610436575f80fd5b80638da5cb5b1461034957806395d89b411461036657806399a904b51461037a5780639e281a98146103a6578063a9059cbb146103c5578063aad2b723146103e4575f80fd5b8063313ce5671161011e578063313ce567146102915780635e0d566b146102ac578063668f8867146102c057806370a08231146102df578063715018a6146103135780637ac3c02f14610327575f80fd5b806306fdde03146101a5578063095ea7b3146101cf57806318160ddd146101fe57806323b872dd1461021c578063258ae5821461023b5780632f4ea5ea14610272575f80fd5b366101a1576005546040516001600160a01b03909116903480156108fc02915f818181858888f1935050505015801561019f573d5f803e3d5ffd5b005b5f80fd5b3480156101b0575f80fd5b506101b9610505565b6040516101c69190611274565b60405180910390f35b3480156101da575f80fd5b506101ee6101e93660046112a8565b610595565b60405190151581526020016101c6565b348015610209575f80fd5b506002545b6040519081526020016101c6565b348015610227575f80fd5b506101ee6102363660046112d0565b6105ae565b348015610246575f80fd5b5061025a6102553660046113a6565b6105d1565b6040516001600160a01b0390911681526020016101c6565b34801561027d575f80fd5b5061020e61028c3660046113ea565b61068a565b34801561029c575f80fd5b50604051601281526020016101c6565b3480156102b7575f80fd5b5060075461020e565b3480156102cb575f80fd5b5061019f6102da366004611401565b6106dc565b3480156102ea575f80fd5b5061020e6102f936600461148e565b6001600160a01b03165f9081526020819052604090205490565b34801561031e575f80fd5b5061019f6108c8565b348015610332575f80fd5b5060095461010090046001600160a01b031661025a565b348015610354575f80fd5b506005546001600160a01b031661025a565b348015610371575f80fd5b506101b96108db565b348015610385575f80fd5b506103996103943660046113ea565b6108ea565b6040516101c691906114f3565b3480156103b1575f80fd5b5061019f6103c03660046112a8565b610a08565b3480156103d0575f80fd5b506101ee6103df3660046112a8565b610aa4565b3480156103ef575f80fd5b5061019f6103fe36600461148e565b610ab1565b34801561040e575f80fd5b5061019f61041d366004611505565b610b64565b34801561042d575f80fd5b5060085461020e565b348015610441575f80fd5b5061020e61045036600461157a565b610d29565b348015610460575f80fd5b5061039961046f3660046113ea565b610d64565b34801561047f575f80fd5b5061020e61048e3660046115de565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b3480156104c3575f80fd5b506101ee6104d23660046113ea565b5f908152600c602052604090205460ff1690565b3480156104f1575f80fd5b5061019f61050036600461148e565b610dfb565b6060600380546105149061160f565b80601f01602080910402602001604051908101604052809291908181526020018280546105409061160f565b801561058b5780601f106105625761010080835404028352916020019161058b565b820191905f5260205f20905b81548152906001019060200180831161056e57829003601f168201915b5050505050905090565b5f336105a2818585610e38565b60019150505b92915050565b5f336105bb858285610e45565b6105c6858585610ec0565b506001949350505050565b6020810151604082015160608301515f929190831a601b8110156105fd576105fa601b8261165b565b90505b8060ff16601b1415801561061557508060ff16601c14155b15610625575f93505050506105a8565b604080515f81526020810180835288905260ff831691810191909152606081018490526080810183905260019060a0016020604051602081039080840390855afa158015610675573d5f803e3d5ffd5b5050604051601f190151979650505050505050565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018290525f90605c01604051602081830303815290604052805190602001209050919050565b6106e4610f1d565b5f848152600c602052604090205460ff16156107355760405162461bcd60e51b815260206004820152600b60248201526a155251081a5cc81d5cd95960aa1b60448201526064015b60405180910390fd5b5f848152600c60205260409020805460ff191660011790556107578284611674565b42111561078f5760405162461bcd60e51b815260040161072c906020808252600490820152631919585960e21b604082015260600190565b5f61079d3389888888610d29565b6009549091506107bc9061010090046001600160a01b03168284610f47565b6107c7333088610ec0565b6040805160a08101825233815260208082018981528284018b81524260608501908152608085018e81526008545f908152600a90955295909320845181546001600160a01b0319166001600160a01b0390911617815591516001830155516002820155905160038201559151909190600482019061084590826116cc565b50506008545f818152600a60205260409081902090517f29d41863210e5467680f07bb56e7cd8ec4974dc005f37c595b2c7ac23541e5d99350610889929190611842565b60405180910390a1600160085f8282546108a39190611674565b909155506108b49050305f88610fb1565b506108bf6001600655565b50505050505050565b6108d06110d7565b6108d95f611104565b565b6060600480546105149061160f565b6109216040518060a001604052805f6001600160a01b031681526020015f81526020015f81526020015f8152602001606081525090565b5f828152600a6020908152604091829020825160a08101845281546001600160a01b03168152600182015492810192909252600281015492820192909252600382015460608201526004820180549192916080840191906109819061160f565b80601f01602080910402602001604051908101604052809291908181526020018280546109ad9061160f565b80156109f85780601f106109cf576101008083540402835291602001916109f8565b820191905f5260205f20905b8154815290600101906020018083116109db57829003601f168201915b5050505050815250509050919050565b610a106110d7565b816001600160a01b031663a9059cbb610a316005546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303815f875af1158015610a7b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a9f919061185a565b505050565b5f336105a2818585610ec0565b610ab96110d7565b6001600160a01b038116610af95760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161072c565b600980546001600160a01b03838116610100818102610100600160a81b031985161790945560408051949093049091168084526020840191909152917feeb293e1f8f3a9db91ade748726387ed1352ca78f5430c5f06fe3d1e1ad50579910160405180910390a15050565b610b6c610f1d565b610b746110d7565b5f828152600c602052604090205460ff1615610bc05760405162461bcd60e51b815260206004820152600b60248201526a155251081a5cc81d5cd95960aa1b604482015260640161072c565b5f828152600c60205260409020805460ff191660011790558215610c2b57610be95f8685610fb1565b6001600160a01b038516610c2b576040518381527fb2576ae8febf5b95593ad494cc3c6e4a7b170f1a46d72f84bc1db63b6ba909e49060200160405180910390a15b6040805160a0810182526001600160a01b03888116825260208083018881528385018881524260608601908152608086018881526007545f908152600b90955296909320855181546001600160a01b03191695169490941784559051600184015551600283015551600382015591519091906004820190610cac90826116cc565b50905050610cbb5f8786610fb1565b6007545f818152600b60205260409081902090517f49c5c74b0423706585666fa98b423707612cea0cda653f8054cb66700cd1d62592610cfc929091611842565b60405180910390a1600160075f828254610d169190611674565b909155505060016006555b505050505050565b5f8585858585604051602001610d43959493929190611879565b60405160208183030381529060405280519060200120905095945050505050565b610d9b6040518060a001604052805f6001600160a01b031681526020015f81526020015f81526020015f8152602001606081525090565b5f828152600b6020908152604091829020825160a08101845281546001600160a01b03168152600182015492810192909252600281015492820192909252600382015460608201526004820180549192916080840191906109819061160f565b610e036110d7565b6001600160a01b038116610e2c57604051631e4fbdf760e01b81525f600482015260240161072c565b610e3581611104565b50565b610a9f8383836001611155565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f198114610eba5781811015610eac57604051637dc7a0d960e11b81526001600160a01b0384166004820152602481018290526044810183905260640161072c565b610eba84848484035f611155565b50505050565b6001600160a01b038316610ee957604051634b637e8f60e11b81525f600482015260240161072c565b6001600160a01b038216610f125760405163ec442f0560e01b81525f600482015260240161072c565b610a9f838383610fb1565b600260065403610f4057604051633ee5aeb560e01b815260040160405180910390fd5b6002600655565b610f59610f538361068a565b826105d1565b6001600160a01b0316836001600160a01b031614610a9f5760405162461bcd60e51b81526020600482015260156024820152740a6d2cedccae440c8decae640dcdee840dac2e8c6d605b1b604482015260640161072c565b6001600160a01b038316610fdb578060025f828254610fd09190611674565b9091555061104b9050565b6001600160a01b0383165f908152602081905260409020548181101561102d5760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640161072c565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b03821661106757600280548290039055611085565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516110ca91815260200190565b60405180910390a3505050565b6005546001600160a01b031633146108d95760405163118cdaa760e01b815233600482015260240161072c565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6001600160a01b03841661117e5760405163e602df0560e01b81525f600482015260240161072c565b6001600160a01b0383166111a757604051634a1406b160e11b81525f600482015260240161072c565b6001600160a01b038085165f9081526001602090815260408083209387168352929052208290558015610eba57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161121991815260200190565b60405180910390a350505050565b5f5b83811015611241578181015183820152602001611229565b50505f910152565b5f8151808452611260816020860160208601611227565b601f01601f19169290920160200192915050565b602081525f6112866020830184611249565b9392505050565b80356001600160a01b03811681146112a3575f80fd5b919050565b5f80604083850312156112b9575f80fd5b6112c28361128d565b946020939093013593505050565b5f805f606084860312156112e2575f80fd5b6112eb8461128d565b92506112f96020850161128d565b9150604084013590509250925092565b634e487b7160e01b5f52604160045260245ffd5b5f82601f83011261132c575f80fd5b813567ffffffffffffffff8082111561134757611347611309565b604051601f8301601f19908116603f0116810190828211818310171561136f5761136f611309565b81604052838152866020858801011115611387575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f80604083850312156113b7575f80fd5b82359150602083013567ffffffffffffffff8111156113d4575f80fd5b6113e08582860161131d565b9150509250929050565b5f602082840312156113fa575f80fd5b5035919050565b5f805f805f805f60e0888a031215611417575f80fd5b873567ffffffffffffffff8082111561142e575f80fd5b61143a8b838c0161131d565b985060208a0135975060408a0135965060608a0135955060808a0135945060a08a0135935060c08a0135915080821115611472575f80fd5b5061147f8a828b0161131d565b91505092959891949750929550565b5f6020828403121561149e575f80fd5b6112868261128d565b60018060a01b0381511682526020810151602083015260408101516040830152606081015160608301525f608082015160a060808501526114eb60a0850182611249565b949350505050565b602081525f61128660208301846114a7565b5f805f805f8060c0878903121561151a575f80fd5b6115238761128d565b95506115316020880161128d565b945060408701359350606087013592506080870135915060a087013567ffffffffffffffff811115611561575f80fd5b61156d89828a0161131d565b9150509295509295509295565b5f805f805f60a0868803121561158e575f80fd5b6115978661128d565b9450602086013567ffffffffffffffff8111156115b2575f80fd5b6115be8882890161131d565b959895975050505060408401359360608101359360809091013592509050565b5f80604083850312156115ef575f80fd5b6115f88361128d565b91506116066020840161128d565b90509250929050565b600181811c9082168061162357607f821691505b60208210810361164157634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b60ff81811683821601908111156105a8576105a8611647565b808201808211156105a8576105a8611647565b601f821115610a9f575f81815260208120601f850160051c810160208610156116ad5750805b601f850160051c820191505b81811015610d21578281556001016116b9565b815167ffffffffffffffff8111156116e6576116e6611309565b6116fa816116f4845461160f565b84611687565b602080601f83116001811461172d575f84156117165750858301515b5f19600386901b1c1916600185901b178555610d21565b5f85815260208120601f198616915b8281101561175b5788860151825594840194600190910190840161173c565b508582101561177857878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b60018060a01b0381541682525f60018083015460208181870152600285015460408701526003850154606087015260048501915060a060808701525f82546117cf8161160f565b8060a08a015260c08683165f81146117ee576001811461180857611833565b60ff1984168b83015282151560051b8b0182019450611833565b865f52855f205f5b8481101561182b5781548d8201850152908901908701611810565b8c0183019550505b50929998505050505050505050565b828152604060208201525f6114eb6040830184611788565b5f6020828403121561186a575f80fd5b81518015158114611286575f80fd5b6bffffffffffffffffffffffff198660601b1681525f85516118a2816014850160208a01611227565b601492019182019490945260348101929092526054820152607401939250505056fea264697066735822122074103026343f7e5e5bf705f351e34755a3f93172f65c6210b434f130b0cfd26664736f6c63430008140033

Verified Source Code Partial Match

Compiler: v0.8.20+commit.a1b79de6 EVM: shanghai Optimization: Yes (200 runs)
BLOCX.sol 782 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

interface IERC20 {
    /**
     * @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
    );

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

interface IERC20Metadata is IERC20 {
    /**
     * @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);
}

abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

interface IERC20Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientBalance(
        address sender,
        uint256 balance,
        uint256 needed
    );

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC20InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC20InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     * @param allowance Amount of tokens a `spender` is allowed to operate with.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientAllowance(
        address spender,
        uint256 allowance,
        uint256 needed
    );

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC20InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC20InvalidSpender(address spender);
}

abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
    mapping(address account => uint256) private _balances;

    mapping(address account => mapping(address spender => uint256))
        private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the default value returned by this function, unless
     * it's overridden.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `value`.
     */
    function transfer(address to, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, value);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(
        address owner,
        address spender
    ) public view virtual returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(
        address spender,
        uint256 value
    ) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, value);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `value`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `value`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 value
    ) public virtual returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, value);
        _transfer(from, to, value);
        return true;
    }

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _transfer(address from, address to, uint256 value) internal {
        if (from == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        if (to == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(from, to, value);
    }

    /**
     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
     * this function.
     *
     * Emits a {Transfer} event.
     */
    function _update(address from, address to, uint256 value) internal virtual {
        if (from == address(0)) {
            // Overflow check required: The rest of the code assumes that totalSupply never overflows
            _totalSupply += value;
        } else {
            uint256 fromBalance = _balances[from];
            if (fromBalance < value) {
                revert ERC20InsufficientBalance(from, fromBalance, value);
            }
            unchecked {
                // Overflow not possible: value <= fromBalance <= totalSupply.
                _balances[from] = fromBalance - value;
            }
        }

        if (to == address(0)) {
            unchecked {
                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
                _totalSupply -= value;
            }
        } else {
            unchecked {
                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
                _balances[to] += value;
            }
        }

        emit Transfer(from, to, value);
    }

    /**
     * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     *
     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
     */
    function _approve(address owner, address spender, uint256 value) internal {
        _approve(owner, spender, value, true);
    }

    /**
     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
     *
     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
     * `Approval` event during `transferFrom` operations.
     *
     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
     * true using the following override:
     * ```
     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
     *     super._approve(owner, spender, value, true);
     * }
     * ```
     *
     * Requirements are the same as {_approve}.
     */
    function _approve(
        address owner,
        address spender,
        uint256 value,
        bool emitEvent
    ) internal virtual {
        if (owner == address(0)) {
            revert ERC20InvalidApprover(address(0));
        }
        if (spender == address(0)) {
            revert ERC20InvalidSpender(address(0));
        }
        _allowances[owner][spender] = value;
        if (emitEvent) {
            emit Approval(owner, spender, value);
        }
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `value`.
     *
     * Does not update the allowance value in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Does not emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 value
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            if (currentAllowance < value) {
                revert ERC20InsufficientAllowance(
                    spender,
                    currentAllowance,
                    value
                );
            }
            unchecked {
                _approve(owner, spender, currentAllowance - value, false);
            }
        }
    }
}

abstract contract Ownable is Context {
    address private _owner;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

abstract contract ReentrancyGuard {
    uint256 private constant NOT_ENTERED = 1;
    uint256 private constant ENTERED = 2;

    uint256 private _status;

    error ReentrancyGuardReentrantCall();

    function setStatus() internal {
        _status = NOT_ENTERED;
    }

    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        if (_status == ENTERED) {
            revert ReentrancyGuardReentrantCall();
        }

        _status = ENTERED;
    }

    function _nonReentrantAfter() private {
        _status = NOT_ENTERED;
    }

    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == ENTERED;
    }
}

contract Sign {
    function verify(
        bytes32 _ethSignedMessageHash,
        bytes memory _signature
    ) public pure returns (address) {
        bytes32 r;
        bytes32 s;
        uint8 v;
        assembly {
            r := mload(add(_signature, 0x20))
            s := mload(add(_signature, 0x40))
            v := byte(0, mload(add(_signature, 0x60)))
        }
        if (v < 27) {
            v += 27;
        }

        if (v != 27 && v != 28) {
            return (address(0));
        }
        return ecrecover(_ethSignedMessageHash, v, r, s);
    }

    function getEthSignedHash(
        bytes32 _messageHash
    ) public pure returns (bytes32) {
        return
            keccak256(
                abi.encodePacked(
                    "\x19Ethereum Signed Message:\n32",
                    _messageHash
                )
            );
    }

    function getHash(
        address caller,
        string memory _withdrawl_address,
        uint _amount,
        uint _uniqueId,
        uint _deadline
    ) public pure returns (bytes32) {
        return
            keccak256(
                abi.encodePacked(
                    caller,
                    _withdrawl_address,
                    _amount,
                    _uniqueId,
                    _deadline
                )
            );
    }

    function matchAddress(
        address signer,
        bytes32 hashOf,
        bytes memory _adminSignature
    ) internal pure {
        require(
            signer == verify(getEthSignedHash(hashOf), _adminSignature),
            "Signer does not match"
        );
    }
}

contract BLOCX is ERC20, Ownable, Sign, ReentrancyGuard {
    struct DRequest {
        address _to;
        uint256 _amount;
        uint256 _feeAmount;
        uint256 _approvalTime;
        string _utxo;
    }

    struct WRequest {
        address _invoker;
        uint256 _amount;
        uint256 _feeAmount;
        uint256 _reqTime;
        string _withdrawal_address;
    }

    uint256 _dreqNumber;
    uint256 _wreqNumber;
    bool isInitialized;

    address signer;

    mapping(uint256 => WRequest) _wreqs;
    mapping(uint256 => DRequest) _dreqs;
    mapping(uint256 => bool) isUidUsed;

    event FeeBurnt(uint256 _amount);
    event SignerChanged(address _from, address _to);
    event AmountDeposited(uint256 seq, DRequest dreq);
    event WithdrawalRequestInitiated(uint256 seq, WRequest wreq);

    constructor()
        ERC20("BLOCX. (Bridge)", "BLOCX")
        Ownable(0x00C9eb9381Ba20E90d6dFB67586eE9dCcFF7c8eD)
    {
        setStatus();
        signer = 0x2C682a7409c5afeAe97Cb32532c2365F4DF66e0e;
    }

    function releaseToken(
        address _to,
        address _feeAddress,
        uint256 _amount,
        uint256 _fee,
        uint256 _uid,
        string memory _utxo
    ) external nonReentrant onlyOwner {
        require(!isUidUsed[_uid], "UID is used");
        isUidUsed[_uid] = true;

        if (_fee > 0) {
            _update(address(0), _feeAddress, _fee);
            if (_feeAddress == address(0)) {
                emit FeeBurnt(_fee);
            }
        }
        _dreqs[_dreqNumber] = DRequest({
            _to: _to,
            _amount: _amount,
            _feeAmount: _fee,
            _approvalTime: block.timestamp,
            _utxo: _utxo
        });

        _update(address(0), _to, _amount);

        emit AmountDeposited(_dreqNumber, _dreqs[_dreqNumber]);
        _dreqNumber += 1;
    }

    function releaseCoin(
        string memory _withdrawl_address,
        uint256 _fee,
        uint256 _amount,
        uint256 _uniqueId,
        uint256 _deadline,
        uint256 _extraTime,
        bytes memory _adminSignature
    ) external nonReentrant {
        require(!isUidUsed[_uniqueId], "UID is used");
        isUidUsed[_uniqueId] = true;

        require(block.timestamp <= _deadline + _extraTime, "dead");

        bytes32 hash = getHash(
            msg.sender,
            _withdrawl_address,
            _amount,
            _uniqueId,
            _deadline
        );

        matchAddress(signer, hash, _adminSignature);

        _transfer(msg.sender, address(this), _amount);
        _wreqs[_wreqNumber] = WRequest({
            _invoker: msg.sender,
            _amount: _amount,
            _feeAmount: _fee,
            _reqTime: block.timestamp,
            _withdrawal_address: _withdrawl_address
        });
        emit WithdrawalRequestInitiated(_wreqNumber, _wreqs[_wreqNumber]);
        _wreqNumber += 1;
        _update(address(this), address(0), _amount);
    }

    function changeSigner(address _signer) external onlyOwner {
        require(_signer != address(0), "Invalid");
        address _temp = signer;
        signer = _signer;
        emit SignerChanged(_temp, _signer);
    }

    function getSigner() external view returns (address) {
        return signer;
    }

    function getWithdrawalRequestInfo(
        uint256 _reqId
    ) external view returns (WRequest memory) {
        return _wreqs[_reqId];
    }

    function getDepositRequestInfo(
        uint256 _reqId
    ) external view returns (DRequest memory) {
        return _dreqs[_reqId];
    }

    function getLatestDepositSeq() external view returns (uint256) {
        return _dreqNumber;
    }

    function getLatestWithdrawalSeq() external view returns (uint256) {
        return _wreqNumber;
    }

    function getIsUniqueIdUsed(uint256 _uid) external view returns (bool) {
        return isUidUsed[_uid];
    }

    function withdrawToken(address _token, uint256 _amount) external onlyOwner {
        IERC20(_token).transfer(owner(), _amount);
    }

    receive() external payable {
        payable(owner()).transfer(msg.value);
    }
}

Read Contract

allowance 0xdd62ed3e → uint256
balanceOf 0x70a08231 → uint256
decimals 0x313ce567 → uint8
getDepositRequestInfo 0xdce259b4 → tuple
getEthSignedHash 0x2f4ea5ea → bytes32
getHash 0xdb327330 → bytes32
getIsUniqueIdUsed 0xe154ebc2 → bool
getLatestDepositSeq 0x5e0d566b → uint256
getLatestWithdrawalSeq 0xd123685c → uint256
getSigner 0x7ac3c02f → address
getWithdrawalRequestInfo 0x99a904b5 → tuple
name 0x06fdde03 → string
owner 0x8da5cb5b → address
symbol 0x95d89b41 → string
totalSupply 0x18160ddd → uint256
verify 0x258ae582 → address

Write Contract 9 functions

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

approve 0x095ea7b3
address spender
uint256 value
returns: bool
changeSigner 0xaad2b723
address _signer
releaseCoin 0x668f8867
string _withdrawl_address
uint256 _fee
uint256 _amount
uint256 _uniqueId
uint256 _deadline
uint256 _extraTime
bytes _adminSignature
releaseToken 0xb51816c2
address _to
address _feeAddress
uint256 _amount
uint256 _fee
uint256 _uid
string _utxo
renounceOwnership 0x715018a6
No parameters
transfer 0xa9059cbb
address to
uint256 value
returns: bool
transferFrom 0x23b872dd
address from
address to
uint256 value
returns: bool
transferOwnership 0xf2fde38b
address newOwner
withdrawToken 0x9e281a98
address _token
uint256 _amount

Recent Transactions

No transactions found for this address