ETH Price: $2,020.72 (+4.21%)

Contract

0x4200000000000000000000000000000000000006

Overview

ETH Balance

2,228.97780145217401869 ETH

ETH Value

$4,504,133.75 (@ $2,020.72/ETH)

Token Holdings

More Info

Private Name Tags

ContractCreator

GENESIS at txn GENESIS_4200000000000000000000000000000000000006

TokenTracker

Wrapped Ether (WETH) (@$2,024.01)
Transaction Hash
Method
Block
From
To
Withdraw116985812025-03-20 5:02:209 secs ago1742446940IN
Wrapped Ether: WETH Token
0 ETH00.00000025
Approve116985682025-03-20 5:02:0722 secs ago1742446927IN
Wrapped Ether: WETH Token
0 ETH0.000000060.00150038
Deposit116985562025-03-20 5:01:5534 secs ago1742446915IN
Wrapped Ether: WETH Token
0.0002 ETH00.00000025
Withdraw116985332025-03-20 5:01:3257 secs ago1742446892IN
Wrapped Ether: WETH Token
0 ETH00.00000025
Deposit116985112025-03-20 5:01:101 min ago1742446870IN
Wrapped Ether: WETH Token
0.0002 ETH00.00000025
Withdraw116984772025-03-20 5:00:361 min ago1742446836IN
Wrapped Ether: WETH Token
0 ETH00.00000025
Withdraw116984762025-03-20 5:00:351 min ago1742446835IN
Wrapped Ether: WETH Token
0 ETH0.000000040.00150038
Deposit116984412025-03-20 5:00:002 mins ago1742446800IN
Wrapped Ether: WETH Token
0.0002 ETH00.00000025
Deposit116984292025-03-20 4:59:482 mins ago1742446788IN
Wrapped Ether: WETH Token
0.000016 ETH0.000000040.0010004
Deposit116984272025-03-20 4:59:462 mins ago1742446786IN
Wrapped Ether: WETH Token
0.00001487 ETH0.000000040.0010004
Deposit116984252025-03-20 4:59:442 mins ago1742446784IN
Wrapped Ether: WETH Token
0.00001347 ETH0.000000040.0010004
Deposit116984232025-03-20 4:59:422 mins ago1742446782IN
Wrapped Ether: WETH Token
0.00001375 ETH0.000000040.0010004
Deposit116984212025-03-20 4:59:402 mins ago1742446780IN
Wrapped Ether: WETH Token
0.00014763 ETH0.000000060.00150038
Deposit116984112025-03-20 4:59:302 mins ago1742446770IN
Wrapped Ether: WETH Token
0.000018 ETH0.000000040.0010004
Deposit116984102025-03-20 4:59:293 mins ago1742446769IN
Wrapped Ether: WETH Token
0.00001345 ETH0.000000040.0010004
Approve116984102025-03-20 4:59:293 mins ago1742446769IN
Wrapped Ether: WETH Token
0 ETH0.000000060.00150038
Withdraw116984082025-03-20 4:59:273 mins ago1742446767IN
Wrapped Ether: WETH Token
0 ETH00.00000025
Deposit116983982025-03-20 4:59:173 mins ago1742446757IN
Wrapped Ether: WETH Token
0.00001452 ETH0.000000040.0010004
Deposit116983972025-03-20 4:59:163 mins ago1742446756IN
Wrapped Ether: WETH Token
0.00001567 ETH0.000000040.0010004
Deposit116983952025-03-20 4:59:143 mins ago1742446754IN
Wrapped Ether: WETH Token
0.00001243 ETH0.000000040.0010004
Deposit116983942025-03-20 4:59:133 mins ago1742446753IN
Wrapped Ether: WETH Token
0.00001765 ETH0.000000040.0010004
Deposit116983842025-03-20 4:59:033 mins ago1742446743IN
Wrapped Ether: WETH Token
0.0002 ETH00.00000025
Withdraw116983812025-03-20 4:59:003 mins ago1742446740IN
Wrapped Ether: WETH Token
0 ETH0.000000050.00150038
Deposit116983342025-03-20 4:58:134 mins ago1742446693IN
Wrapped Ether: WETH Token
0.00015601 ETH0.000000060.00150038
Deposit116983152025-03-20 4:57:544 mins ago1742446674IN
Wrapped Ether: WETH Token
0.00014435 ETH0.000000040.00150038
View all transactions

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To
116985812025-03-20 5:02:209 secs ago1742446940
Wrapped Ether: WETH Token
0.0002 ETH
116985542025-03-20 5:01:5336 secs ago1742446913
Wrapped Ether: WETH Token
0.008 ETH
116985492025-03-20 5:01:4841 secs ago1742446908
Wrapped Ether: WETH Token
0.00804163 ETH
116985482025-03-20 5:01:4742 secs ago1742446907
Wrapped Ether: WETH Token
0.04997533 ETH
116985462025-03-20 5:01:4544 secs ago1742446905
Wrapped Ether: WETH Token
0.29636584 ETH
116985402025-03-20 5:01:3950 secs ago1742446899
Wrapped Ether: WETH Token
0.0004 ETH
116985352025-03-20 5:01:3455 secs ago1742446894
Wrapped Ether: WETH Token
0.014 ETH
116985332025-03-20 5:01:3257 secs ago1742446892
Wrapped Ether: WETH Token
0.0002 ETH
116985262025-03-20 5:01:251 min ago1742446885
Wrapped Ether: WETH Token
0.0012 ETH
116985232025-03-20 5:01:221 min ago1742446882
Wrapped Ether: WETH Token
0.00539141 ETH
116985222025-03-20 5:01:211 min ago1742446881
Wrapped Ether: WETH Token
0.00000017 ETH
116985222025-03-20 5:01:211 min ago1742446881
Wrapped Ether: WETH Token
0.002 ETH
116985172025-03-20 5:01:161 min ago1742446876
Wrapped Ether: WETH Token
0.00014769 ETH
116985172025-03-20 5:01:161 min ago1742446876
Wrapped Ether: WETH Token
0.00014769 ETH
116985032025-03-20 5:01:021 min ago1742446862
Wrapped Ether: WETH Token
0.00868778 ETH
116985032025-03-20 5:01:021 min ago1742446862
Wrapped Ether: WETH Token
0.002 ETH
116985002025-03-20 5:00:591 min ago1742446859
Wrapped Ether: WETH Token
0.0001029 ETH
116985002025-03-20 5:00:591 min ago1742446859
Wrapped Ether: WETH Token
0.0000222 ETH
116984992025-03-20 5:00:581 min ago1742446858
Wrapped Ether: WETH Token
0.00000468 ETH
116984912025-03-20 5:00:501 min ago1742446850
Wrapped Ether: WETH Token
0.0139878 ETH
116984802025-03-20 5:00:391 min ago1742446839
Wrapped Ether: WETH Token
0.00001483 ETH
116984772025-03-20 5:00:361 min ago1742446836
Wrapped Ether: WETH Token
0.0002 ETH
116984762025-03-20 5:00:351 min ago1742446835
Wrapped Ether: WETH Token
0.00014763 ETH
116984742025-03-20 5:00:331 min ago1742446833
Wrapped Ether: WETH Token
0.00001562 ETH
116984742025-03-20 5:00:331 min ago1742446833
Wrapped Ether: WETH Token
0.00003124 ETH
View All Internal Transactions

Latest 25 Deposits

L2 Txn Hash L1 Deposit Txn Value Token
0x2985c105fe281ad5bd404f9ee31f73cda84c6bcbf7c3a095bdeb7e8617dcc5c62025-03-13 14:47:076 days ago17418772270.0004985 Ether (ETH)
0x4fa7960e9412f4ed11fb362375a0c3269835541a017fc0e58a4bd847d53edd5a2025-03-01 1:13:0319 days ago17407915830.5 Ether (ETH)
0x04fe096886e68910b4ba030d0acbb5dd1376ba669348008641edca2af99f360a2025-02-13 20:08:5134 days ago17394773310.00997 Ether (ETH)
0x8e35616157f1ee87004bad563d5115c9d9bb185f3c00f6b4ed7659c2f2bd33ff2025-02-12 19:02:1535 days ago17393869350.01 Ether (ETH)
0xba3fa41538f63e180fc3ee9183f0f8f256b5693a8edef089bde8e52699c4bcde2025-02-12 19:01:5235 days ago17393869120.03 Ether (ETH)
0x80f31d0f560ca3dd0c0ccf48563fb1a73d70a81fd070984dacc30e249dac969c2025-02-12 8:08:0335 days ago17393476830.01 Ether (ETH)
0x230e713d6aa48608ca2aa711277aa39136bbdf34dcd2f382e5c472798d5474f82025-02-12 3:40:5136 days ago17393316510.078 Ether (ETH)
0xb3a4e5d0ec7adf4e788096a1304858ebb2b125bff5c3f02c79e76c950e91b36d2025-02-11 19:28:0336 days ago17393020830.03 Ether (ETH)
0x1697ea5314e3bea380e19f6f90e3d1d4901be7514abe8ee09e89318a9bc7af352025-02-11 17:42:0336 days ago17392957230.29 Ether (ETH)
0xfe8544d64db6c654bdcdbeb5081834bbe4548d4477f73548182d0f2ba848f4712025-02-11 17:34:1436 days ago17392952543 Ether (ETH)
0x3a064c194491e3a11483b64b237a020ef0c24d14ac9c969c3d4e996d16c241a52025-02-11 17:33:0336 days ago17392951833 Ether (ETH)
0x01efc05e5bb21c8064cb5a43938bb8476592f37c628d2814147df48a2b00a8f42025-02-11 17:32:2736 days ago17392951473 Ether (ETH)
0x19e4389769cdc37c9617f91d570a1756eac4512152bf7294a6968dcc6a60a6652025-02-11 16:42:1536 days ago17392921350.01 Ether (ETH)
0xfc8c6827ee12846551f0897907f31e96ec7dd58d94fe228378009418fd74f5d62025-02-11 16:34:0336 days ago17392916430.05 Ether (ETH)
0x3a3772fb4ab56ba9a00f96ace02076aafa5f532f18be054e35bf1d49527983b22025-02-11 16:30:2736 days ago17392914270.47 Ether (ETH)
0x7e0c7d92cad0197ce420def005099e3b5aee4f73ac2d7cd64293f32e7f2569a82025-02-11 16:23:4036 days ago17392910200.03 Ether (ETH)
0xa76096a1c1edd9fa082fed7855f184163d348f090270f86b3f63bfdc864bf7b52025-02-11 16:05:1436 days ago17392899140.02 Ether (ETH)
0x6d8aeb9ec8218a4f86af99478fd34f2c7b8737dd1664d39dbcc6f80be0a265d92025-02-11 16:01:1536 days ago17392896750.080046737550113628 Ether (ETH)
0x5aa70f65db7a314dbdc4bfb6b99cb8dce7b77a993d188eecf8132138b17ff0bc2025-02-11 15:59:0336 days ago17392895430.015952 Ether (ETH)
0x1f8b2eabe0c4af7e15d45331314d9d5acf555d6af2031d7e499a5cb377b421592025-02-11 15:58:4036 days ago17392895200.3 Ether (ETH)
0x24db60ecf0e19bcf798859b97a3d048e4267f9878e11ed91a5cd86c9d533839b2025-02-11 15:52:0336 days ago17392891230.23 Ether (ETH)
0x1ab5fbf630d367a06a36ea930b3423acfbdeb82cc5fbb0d9700b7c86d771fe3f2025-02-11 15:51:0336 days ago17392890631 Ether (ETH)
0xbe713a410444d689c087a66ac43ef94fcb7b770c97703472cfcdf58c0cf2e2b62025-02-11 15:47:0336 days ago17392888230.05 Ether (ETH)
0xde335b8bfeef36a2b67573799beb86fe9dec1a7ef257dbe3c11a08cca3e72be22025-02-11 15:44:3936 days ago17392886790.1 Ether (ETH)
0x060d3d2ab72b389f02ed2bafa678bb87d28337d7fc16c5fe70a7b10f085a9c8f2025-02-11 15:40:3936 days ago17392884390.134595 Ether (ETH)
View All Deposits

Loading...
Loading

Contract Source Code Verified (Genesis Bytecode Match Only)

Contract Name:
WETH

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 999999 runs

Other Settings:
london EvmVersion, MIT license
File 1 of 12 : WETH.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import { WETH98 } from "src/dispute/weth/WETH98.sol";
import { Predeploys } from "src/libraries/Predeploys.sol";
import { L1Block } from "src/L2/L1Block.sol";
import { ISemver } from "src/universal/interfaces/ISemver.sol";

/// @title WETH contract that reads the name and symbol from the L1Block contract.
///        Allows for nice rendering of token names for chains using custom gas token.
contract WETH is WETH98, ISemver {
    /// @custom:semver 1.0.0-beta.1
    string public constant version = "1.0.0-beta.1";

    /// @notice Returns the name of the wrapped native asset. Will be "Wrapped Ether"
    ///         if the native asset is Ether.
    function name() external view override returns (string memory name_) {
        name_ = string.concat("Wrapped ", L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).gasPayingTokenName());
    }

    /// @notice Returns the symbol of the wrapped native asset. Will be "WETH" if the
    ///         native asset is Ether.
    function symbol() external view override returns (string memory symbol_) {
        symbol_ = string.concat("W", L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).gasPayingTokenSymbol());
    }
}

File 2 of 12 : WETH98.sol
// SPDX-License-Identifier: GPL-3.0
// Copyright (C) 2015, 2016, 2017 Dapphub

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// Based on WETH9 by Dapphub.
// Modified by OP Labs.

pragma solidity 0.8.15;

import { IWETH } from "src/dispute/interfaces/IWETH.sol";

/// @title WETH98
/// @notice WETH98 is a version of WETH9 upgraded for Solidity 0.8.x.
contract WETH98 is IWETH {
    uint8 public constant decimals = 18;

    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;

    /// @notice Pipes to deposit.
    receive() external payable {
        deposit();
    }

    /// @notice Pipes to deposit.
    fallback() external payable {
        deposit();
    }

    /// @inheritdoc IWETH
    function name() external view virtual override returns (string memory) {
        return "Wrapped Ether";
    }

    /// @inheritdoc IWETH
    function symbol() external view virtual override returns (string memory) {
        return "WETH";
    }

    /// @inheritdoc IWETH
    function deposit() public payable virtual {
        balanceOf[msg.sender] += msg.value;
        emit Deposit(msg.sender, msg.value);
    }

    /// @inheritdoc IWETH
    function withdraw(uint256 wad) public virtual {
        require(balanceOf[msg.sender] >= wad);
        balanceOf[msg.sender] -= wad;
        payable(msg.sender).transfer(wad);
        emit Withdrawal(msg.sender, wad);
    }

    /// @inheritdoc IWETH
    function totalSupply() external view returns (uint256) {
        return address(this).balance;
    }

    /// @inheritdoc IWETH
    function approve(address guy, uint256 wad) external returns (bool) {
        allowance[msg.sender][guy] = wad;
        emit Approval(msg.sender, guy, wad);
        return true;
    }

    /// @inheritdoc IWETH
    function transfer(address dst, uint256 wad) external returns (bool) {
        return transferFrom(msg.sender, dst, wad);
    }

    /// @inheritdoc IWETH
    function transferFrom(address src, address dst, uint256 wad) public returns (bool) {
        require(balanceOf[src] >= wad);

        if (src != msg.sender && allowance[src][msg.sender] != type(uint256).max) {
            require(allowance[src][msg.sender] >= wad);
            allowance[src][msg.sender] -= wad;
        }

        balanceOf[src] -= wad;
        balanceOf[dst] += wad;

        emit Transfer(src, dst, wad);

        return true;
    }
}

File 3 of 12 : Predeploys.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/// @title Predeploys
/// @notice Contains constant addresses for protocol contracts that are pre-deployed to the L2 system.
//          This excludes the preinstalls (non-protocol contracts).
library Predeploys {
    /// @notice Number of predeploy-namespace addresses reserved for protocol usage.
    uint256 internal constant PREDEPLOY_COUNT = 2048;

    /// @custom:legacy
    /// @notice Address of the LegacyMessagePasser predeploy. Deprecate. Use the updated
    ///         L2ToL1MessagePasser contract instead.
    address internal constant LEGACY_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000;

    /// @custom:legacy
    /// @notice Address of the L1MessageSender predeploy. Deprecated. Use L2CrossDomainMessenger
    ///         or access tx.origin (or msg.sender) in a L1 to L2 transaction instead.
    ///         Not embedded into new OP-Stack chains.
    address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001;

    /// @custom:legacy
    /// @notice Address of the DeployerWhitelist predeploy. No longer active.
    address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002;

    /// @notice Address of the canonical WETH contract.
    address internal constant WETH = 0x4200000000000000000000000000000000000006;

    /// @notice Address of the L2CrossDomainMessenger predeploy.
    address internal constant L2_CROSS_DOMAIN_MESSENGER = 0x4200000000000000000000000000000000000007;

    /// @notice Address of the GasPriceOracle predeploy. Includes fee information
    ///         and helpers for computing the L1 portion of the transaction fee.
    address internal constant GAS_PRICE_ORACLE = 0x420000000000000000000000000000000000000F;

    /// @notice Address of the L2StandardBridge predeploy.
    address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010;

    //// @notice Address of the SequencerFeeWallet predeploy.
    address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011;

    /// @notice Address of the OptimismMintableERC20Factory predeploy.
    address internal constant OPTIMISM_MINTABLE_ERC20_FACTORY = 0x4200000000000000000000000000000000000012;

    /// @custom:legacy
    /// @notice Address of the L1BlockNumber predeploy. Deprecated. Use the L1Block predeploy
    ///         instead, which exposes more information about the L1 state.
    address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013;

    /// @notice Address of the L2ERC721Bridge predeploy.
    address internal constant L2_ERC721_BRIDGE = 0x4200000000000000000000000000000000000014;

    /// @notice Address of the L1Block predeploy.
    address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000015;

    /// @notice Address of the L2ToL1MessagePasser predeploy.
    address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000016;

    /// @notice Address of the OptimismMintableERC721Factory predeploy.
    address internal constant OPTIMISM_MINTABLE_ERC721_FACTORY = 0x4200000000000000000000000000000000000017;

    /// @notice Address of the ProxyAdmin predeploy.
    address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000018;

    /// @notice Address of the BaseFeeVault predeploy.
    address internal constant BASE_FEE_VAULT = 0x4200000000000000000000000000000000000019;

    /// @notice Address of the L1FeeVault predeploy.
    address internal constant L1_FEE_VAULT = 0x420000000000000000000000000000000000001A;

    /// @notice Address of the SchemaRegistry predeploy.
    address internal constant SCHEMA_REGISTRY = 0x4200000000000000000000000000000000000020;

    /// @notice Address of the EAS predeploy.
    address internal constant EAS = 0x4200000000000000000000000000000000000021;

    /// @notice Address of the GovernanceToken predeploy.
    address internal constant GOVERNANCE_TOKEN = 0x4200000000000000000000000000000000000042;

    /// @custom:legacy
    /// @notice Address of the LegacyERC20ETH predeploy. Deprecated. Balances are migrated to the
    ///         state trie as of the Bedrock upgrade. Contract has been locked and write functions
    ///         can no longer be accessed.
    address internal constant LEGACY_ERC20_ETH = 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000;

    /// @notice Address of the CrossL2Inbox predeploy.
    address internal constant CROSS_L2_INBOX = 0x4200000000000000000000000000000000000022;

    /// @notice Address of the L2ToL2CrossDomainMessenger predeploy.
    address internal constant L2_TO_L2_CROSS_DOMAIN_MESSENGER = 0x4200000000000000000000000000000000000023;

    /// @notice Address of the SuperchainWETH predeploy.
    address internal constant SUPERCHAIN_WETH = 0x4200000000000000000000000000000000000024;

    /// @notice Address of the ETHLiquidity predeploy.
    address internal constant ETH_LIQUIDITY = 0x4200000000000000000000000000000000000025;

    /// @notice Address of the OptimismSuperchainERC20Factory predeploy.
    address internal constant OPTIMISM_SUPERCHAIN_ERC20_FACTORY = 0x4200000000000000000000000000000000000026;

    /// @notice Address of the OptimismSuperchainERC20Beacon predeploy.
    address internal constant OPTIMISM_SUPERCHAIN_ERC20_BEACON = 0x4200000000000000000000000000000000000027;

    // TODO: Precalculate the address of the implementation contract
    /// @notice Arbitrary address of the OptimismSuperchainERC20 implementation contract.
    address internal constant OPTIMISM_SUPERCHAIN_ERC20 = 0xB9415c6cA93bdC545D4c5177512FCC22EFa38F28;

    /// @notice Returns the name of the predeploy at the given address.
    function getName(address _addr) internal pure returns (string memory out_) {
        require(isPredeployNamespace(_addr), "Predeploys: address must be a predeploy");
        if (_addr == LEGACY_MESSAGE_PASSER) return "LegacyMessagePasser";
        if (_addr == L1_MESSAGE_SENDER) return "L1MessageSender";
        if (_addr == DEPLOYER_WHITELIST) return "DeployerWhitelist";
        if (_addr == WETH) return "WETH";
        if (_addr == L2_CROSS_DOMAIN_MESSENGER) return "L2CrossDomainMessenger";
        if (_addr == GAS_PRICE_ORACLE) return "GasPriceOracle";
        if (_addr == L2_STANDARD_BRIDGE) return "L2StandardBridge";
        if (_addr == SEQUENCER_FEE_WALLET) return "SequencerFeeVault";
        if (_addr == OPTIMISM_MINTABLE_ERC20_FACTORY) return "OptimismMintableERC20Factory";
        if (_addr == L1_BLOCK_NUMBER) return "L1BlockNumber";
        if (_addr == L2_ERC721_BRIDGE) return "L2ERC721Bridge";
        if (_addr == L1_BLOCK_ATTRIBUTES) return "L1Block";
        if (_addr == L2_TO_L1_MESSAGE_PASSER) return "L2ToL1MessagePasser";
        if (_addr == OPTIMISM_MINTABLE_ERC721_FACTORY) return "OptimismMintableERC721Factory";
        if (_addr == PROXY_ADMIN) return "ProxyAdmin";
        if (_addr == BASE_FEE_VAULT) return "BaseFeeVault";
        if (_addr == L1_FEE_VAULT) return "L1FeeVault";
        if (_addr == SCHEMA_REGISTRY) return "SchemaRegistry";
        if (_addr == EAS) return "EAS";
        if (_addr == GOVERNANCE_TOKEN) return "GovernanceToken";
        if (_addr == LEGACY_ERC20_ETH) return "LegacyERC20ETH";
        if (_addr == CROSS_L2_INBOX) return "CrossL2Inbox";
        if (_addr == L2_TO_L2_CROSS_DOMAIN_MESSENGER) return "L2ToL2CrossDomainMessenger";
        if (_addr == SUPERCHAIN_WETH) return "SuperchainWETH";
        if (_addr == ETH_LIQUIDITY) return "ETHLiquidity";
        if (_addr == OPTIMISM_SUPERCHAIN_ERC20_FACTORY) return "OptimismSuperchainERC20Factory";
        if (_addr == OPTIMISM_SUPERCHAIN_ERC20_BEACON) return "OptimismSuperchainERC20Beacon";
        revert("Predeploys: unnamed predeploy");
    }

    /// @notice Returns true if the predeploy is not proxied.
    function notProxied(address _addr) internal pure returns (bool) {
        return _addr == GOVERNANCE_TOKEN || _addr == WETH;
    }

    /// @notice Returns true if the address is a defined predeploy that is embedded into new OP-Stack chains.
    function isSupportedPredeploy(address _addr, bool _useInterop) internal pure returns (bool) {
        return _addr == LEGACY_MESSAGE_PASSER || _addr == DEPLOYER_WHITELIST || _addr == WETH
            || _addr == L2_CROSS_DOMAIN_MESSENGER || _addr == GAS_PRICE_ORACLE || _addr == L2_STANDARD_BRIDGE
            || _addr == SEQUENCER_FEE_WALLET || _addr == OPTIMISM_MINTABLE_ERC20_FACTORY || _addr == L1_BLOCK_NUMBER
            || _addr == L2_ERC721_BRIDGE || _addr == L1_BLOCK_ATTRIBUTES || _addr == L2_TO_L1_MESSAGE_PASSER
            || _addr == OPTIMISM_MINTABLE_ERC721_FACTORY || _addr == PROXY_ADMIN || _addr == BASE_FEE_VAULT
            || _addr == L1_FEE_VAULT || _addr == SCHEMA_REGISTRY || _addr == EAS || _addr == GOVERNANCE_TOKEN
            || (_useInterop && _addr == CROSS_L2_INBOX) || (_useInterop && _addr == L2_TO_L2_CROSS_DOMAIN_MESSENGER)
            || (_useInterop && _addr == SUPERCHAIN_WETH) || (_useInterop && _addr == ETH_LIQUIDITY)
            || (_useInterop && _addr == OPTIMISM_SUPERCHAIN_ERC20_FACTORY)
            || (_useInterop && _addr == OPTIMISM_SUPERCHAIN_ERC20_BEACON);
    }

    function isPredeployNamespace(address _addr) internal pure returns (bool) {
        return uint160(_addr) >> 11 == uint160(0x4200000000000000000000000000000000000000) >> 11;
    }

    /// @notice Function to compute the expected address of the predeploy implementation
    ///         in the genesis state.
    function predeployToCodeNamespace(address _addr) internal pure returns (address) {
        require(
            isPredeployNamespace(_addr), "Predeploys: can only derive code-namespace address for predeploy addresses"
        );
        return address(
            uint160(uint256(uint160(_addr)) & 0xffff | uint256(uint160(0xc0D3C0d3C0d3C0D3c0d3C0d3c0D3C0d3c0d30000)))
        );
    }
}

File 4 of 12 : L1Block.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import { ISemver } from "src/universal/interfaces/ISemver.sol";
import { Constants } from "src/libraries/Constants.sol";
import { GasPayingToken, IGasToken } from "src/libraries/GasPayingToken.sol";
import "src/libraries/L1BlockErrors.sol";

/// @custom:proxied true
/// @custom:predeploy 0x4200000000000000000000000000000000000015
/// @title L1Block
/// @notice The L1Block predeploy gives users access to information about the last known L1 block.
///         Values within this contract are updated once per epoch (every L1 block) and can only be
///         set by the "depositor" account, a special system address. Depositor account transactions
///         are created by the protocol whenever we move to a new epoch.
contract L1Block is ISemver, IGasToken {
    /// @notice Event emitted when the gas paying token is set.
    event GasPayingTokenSet(address indexed token, uint8 indexed decimals, bytes32 name, bytes32 symbol);

    /// @notice Address of the special depositor account.
    function DEPOSITOR_ACCOUNT() public pure returns (address addr_) {
        addr_ = Constants.DEPOSITOR_ACCOUNT;
    }

    /// @notice The latest L1 block number known by the L2 system.
    uint64 public number;

    /// @notice The latest L1 timestamp known by the L2 system.
    uint64 public timestamp;

    /// @notice The latest L1 base fee.
    uint256 public basefee;

    /// @notice The latest L1 blockhash.
    bytes32 public hash;

    /// @notice The number of L2 blocks in the same epoch.
    uint64 public sequenceNumber;

    /// @notice The scalar value applied to the L1 blob base fee portion of the blob-capable L1 cost func.
    uint32 public blobBaseFeeScalar;

    /// @notice The scalar value applied to the L1 base fee portion of the blob-capable L1 cost func.
    uint32 public baseFeeScalar;

    /// @notice The versioned hash to authenticate the batcher by.
    bytes32 public batcherHash;

    /// @notice The overhead value applied to the L1 portion of the transaction fee.
    /// @custom:legacy
    uint256 public l1FeeOverhead;

    /// @notice The scalar value applied to the L1 portion of the transaction fee.
    /// @custom:legacy
    uint256 public l1FeeScalar;

    /// @notice The latest L1 blob base fee.
    uint256 public blobBaseFee;

    /// @custom:semver 1.5.1-beta.1
    function version() public pure virtual returns (string memory) {
        return "1.5.1-beta.1";
    }

    /// @notice Returns the gas paying token, its decimals, name and symbol.
    ///         If nothing is set in state, then it means ether is used.
    function gasPayingToken() public view returns (address addr_, uint8 decimals_) {
        (addr_, decimals_) = GasPayingToken.getToken();
    }

    /// @notice Returns the gas paying token name.
    ///         If nothing is set in state, then it means ether is used.
    function gasPayingTokenName() public view returns (string memory name_) {
        name_ = GasPayingToken.getName();
    }

    /// @notice Returns the gas paying token symbol.
    ///         If nothing is set in state, then it means ether is used.
    function gasPayingTokenSymbol() public view returns (string memory symbol_) {
        symbol_ = GasPayingToken.getSymbol();
    }

    /// @notice Getter for custom gas token paying networks. Returns true if the
    ///         network uses a custom gas token.
    function isCustomGasToken() public view returns (bool) {
        (address token,) = gasPayingToken();
        return token != Constants.ETHER;
    }

    /// @custom:legacy
    /// @notice Updates the L1 block values.
    /// @param _number         L1 blocknumber.
    /// @param _timestamp      L1 timestamp.
    /// @param _basefee        L1 basefee.
    /// @param _hash           L1 blockhash.
    /// @param _sequenceNumber Number of L2 blocks since epoch start.
    /// @param _batcherHash    Versioned hash to authenticate batcher by.
    /// @param _l1FeeOverhead  L1 fee overhead.
    /// @param _l1FeeScalar    L1 fee scalar.
    function setL1BlockValues(
        uint64 _number,
        uint64 _timestamp,
        uint256 _basefee,
        bytes32 _hash,
        uint64 _sequenceNumber,
        bytes32 _batcherHash,
        uint256 _l1FeeOverhead,
        uint256 _l1FeeScalar
    )
        external
    {
        require(msg.sender == DEPOSITOR_ACCOUNT(), "L1Block: only the depositor account can set L1 block values");

        number = _number;
        timestamp = _timestamp;
        basefee = _basefee;
        hash = _hash;
        sequenceNumber = _sequenceNumber;
        batcherHash = _batcherHash;
        l1FeeOverhead = _l1FeeOverhead;
        l1FeeScalar = _l1FeeScalar;
    }

    /// @notice Updates the L1 block values for an Ecotone upgraded chain.
    /// Params are packed and passed in as raw msg.data instead of ABI to reduce calldata size.
    /// Params are expected to be in the following order:
    ///   1. _baseFeeScalar      L1 base fee scalar
    ///   2. _blobBaseFeeScalar  L1 blob base fee scalar
    ///   3. _sequenceNumber     Number of L2 blocks since epoch start.
    ///   4. _timestamp          L1 timestamp.
    ///   5. _number             L1 blocknumber.
    ///   6. _basefee            L1 base fee.
    ///   7. _blobBaseFee        L1 blob base fee.
    ///   8. _hash               L1 blockhash.
    ///   9. _batcherHash        Versioned hash to authenticate batcher by.
    function setL1BlockValuesEcotone() public {
        _setL1BlockValuesEcotone();
    }

    /// @notice Updates the L1 block values for an Ecotone upgraded chain.
    /// Params are packed and passed in as raw msg.data instead of ABI to reduce calldata size.
    /// Params are expected to be in the following order:
    ///   1. _baseFeeScalar      L1 base fee scalar
    ///   2. _blobBaseFeeScalar  L1 blob base fee scalar
    ///   3. _sequenceNumber     Number of L2 blocks since epoch start.
    ///   4. _timestamp          L1 timestamp.
    ///   5. _number             L1 blocknumber.
    ///   6. _basefee            L1 base fee.
    ///   7. _blobBaseFee        L1 blob base fee.
    ///   8. _hash               L1 blockhash.
    ///   9. _batcherHash        Versioned hash to authenticate batcher by.
    function _setL1BlockValuesEcotone() internal {
        address depositor = DEPOSITOR_ACCOUNT();
        assembly {
            // Revert if the caller is not the depositor account.
            if xor(caller(), depositor) {
                mstore(0x00, 0x3cc50b45) // 0x3cc50b45 is the 4-byte selector of "NotDepositor()"
                revert(0x1C, 0x04) // returns the stored 4-byte selector from above
            }
            // sequencenum (uint64), blobBaseFeeScalar (uint32), baseFeeScalar (uint32)
            sstore(sequenceNumber.slot, shr(128, calldataload(4)))
            // number (uint64) and timestamp (uint64)
            sstore(number.slot, shr(128, calldataload(20)))
            sstore(basefee.slot, calldataload(36)) // uint256
            sstore(blobBaseFee.slot, calldataload(68)) // uint256
            sstore(hash.slot, calldataload(100)) // bytes32
            sstore(batcherHash.slot, calldataload(132)) // bytes32
        }
    }

    /// @notice Sets the gas paying token for the L2 system. Can only be called by the special
    ///         depositor account. This function is not called on every L2 block but instead
    ///         only called by specially crafted L1 deposit transactions.
    function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external {
        if (msg.sender != DEPOSITOR_ACCOUNT()) revert NotDepositor();

        GasPayingToken.set({ _token: _token, _decimals: _decimals, _name: _name, _symbol: _symbol });

        emit GasPayingTokenSet({ token: _token, decimals: _decimals, name: _name, symbol: _symbol });
    }
}

File 5 of 12 : ISemver.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/// @title ISemver
/// @notice ISemver is a simple contract for ensuring that contracts are
///         versioned using semantic versioning.
interface ISemver {
    /// @notice Getter for the semantic version of the contract. This is not
    ///         meant to be used onchain but instead meant to be used by offchain
    ///         tooling.
    /// @return Semver contract version as a string.
    function version() external view returns (string memory);
}

File 6 of 12 : IWETH.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/// @title IWETH
/// @notice Interface for WETH9.
interface IWETH {
    /// @notice Emitted when an approval is made.
    /// @param src The address that approved the transfer.
    /// @param guy The address that was approved to transfer.
    /// @param wad The amount that was approved to transfer.
    event Approval(address indexed src, address indexed guy, uint256 wad);

    /// @notice Emitted when a transfer is made.
    /// @param src The address that transferred the WETH.
    /// @param dst The address that received the WETH.
    /// @param wad The amount of WETH that was transferred.
    event Transfer(address indexed src, address indexed dst, uint256 wad);

    /// @notice Emitted when a deposit is made.
    /// @param dst The address that deposited the WETH.
    /// @param wad The amount of WETH that was deposited.
    event Deposit(address indexed dst, uint256 wad);

    /// @notice Emitted when a withdrawal is made.
    /// @param src The address that withdrew the WETH.
    /// @param wad The amount of WETH that was withdrawn.
    event Withdrawal(address indexed src, uint256 wad);

    /// @notice Returns the name of the token.
    /// @return The name of the token.
    function name() external view returns (string memory);

    /// @notice Returns the symbol of the token.
    /// @return The symbol of the token.
    function symbol() external view returns (string memory);

    /// @notice Returns the number of decimals the token uses.
    /// @return The number of decimals the token uses.
    function decimals() external pure returns (uint8);

    /// @notice Returns the balance of the given address.
    /// @param owner The address to query the balance of.
    /// @return The balance of the given address.
    function balanceOf(address owner) external view returns (uint256);

    /// @notice Returns the amount of WETH that the spender can transfer on behalf of the owner.
    /// @param owner The address that owns the WETH.
    /// @param spender The address that is approved to transfer the WETH.
    /// @return The amount of WETH that the spender can transfer on behalf of the owner.
    function allowance(address owner, address spender) external view returns (uint256);

    /// @notice Allows WETH to be deposited by sending ether to the contract.
    function deposit() external payable;

    /// @notice Withdraws an amount of ETH.
    /// @param wad The amount of ETH to withdraw.
    function withdraw(uint256 wad) external;

    /// @notice Returns the total supply of WETH.
    /// @return The total supply of WETH.
    function totalSupply() external view returns (uint256);

    /// @notice Approves the given address to transfer the WETH on behalf of the caller.
    /// @param guy The address that is approved to transfer the WETH.
    /// @param wad The amount that is approved to transfer.
    /// @return True if the approval was successful.
    function approve(address guy, uint256 wad) external returns (bool);

    /// @notice Transfers the given amount of WETH to the given address.
    /// @param dst The address to transfer the WETH to.
    /// @param wad The amount of WETH to transfer.
    /// @return True if the transfer was successful.
    function transfer(address dst, uint256 wad) external returns (bool);

    /// @notice Transfers the given amount of WETH from the given address to the given address.
    /// @param src The address to transfer the WETH from.
    /// @param dst The address to transfer the WETH to.
    /// @param wad The amount of WETH to transfer.
    /// @return True if the transfer was successful.
    function transferFrom(address src, address dst, uint256 wad) external returns (bool);
}

File 7 of 12 : Constants.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol";

/// @title Constants
/// @notice Constants is a library for storing constants. Simple! Don't put everything in here, just
///         the stuff used in multiple contracts. Constants that only apply to a single contract
///         should be defined in that contract instead.
library Constants {
    /// @notice Special address to be used as the tx origin for gas estimation calls in the
    ///         OptimismPortal and CrossDomainMessenger calls. You only need to use this address if
    ///         the minimum gas limit specified by the user is not actually enough to execute the
    ///         given message and you're attempting to estimate the actual necessary gas limit. We
    ///         use address(1) because it's the ecrecover precompile and therefore guaranteed to
    ///         never have any code on any EVM chain.
    address internal constant ESTIMATION_ADDRESS = address(1);

    /// @notice Value used for the L2 sender storage slot in both the OptimismPortal and the
    ///         CrossDomainMessenger contracts before an actual sender is set. This value is
    ///         non-zero to reduce the gas cost of message passing transactions.
    address internal constant DEFAULT_L2_SENDER = 0x000000000000000000000000000000000000dEaD;

    /// @notice The storage slot that holds the address of a proxy implementation.
    /// @dev `bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)`
    bytes32 internal constant PROXY_IMPLEMENTATION_ADDRESS =
        0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;

    /// @notice The storage slot that holds the address of the owner.
    /// @dev `bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)`
    bytes32 internal constant PROXY_OWNER_ADDRESS = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;

    /// @notice The address that represents ether when dealing with ERC20 token addresses.
    address internal constant ETHER = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

    /// @notice The address that represents the system caller responsible for L1 attributes
    ///         transactions.
    address internal constant DEPOSITOR_ACCOUNT = 0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001;

    /// @notice Returns the default values for the ResourceConfig. These are the recommended values
    ///         for a production network.
    function DEFAULT_RESOURCE_CONFIG() internal pure returns (IResourceMetering.ResourceConfig memory) {
        IResourceMetering.ResourceConfig memory config = IResourceMetering.ResourceConfig({
            maxResourceLimit: 20_000_000,
            elasticityMultiplier: 10,
            baseFeeMaxChangeDenominator: 8,
            minimumBaseFee: 1 gwei,
            systemTxMaxGas: 1_000_000,
            maximumBaseFee: type(uint128).max
        });
        return config;
    }
}

File 8 of 12 : GasPayingToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { Storage } from "src/libraries/Storage.sol";
import { Constants } from "src/libraries/Constants.sol";
import { LibString } from "@solady/utils/LibString.sol";

/// @title IGasToken
/// @notice Implemented by contracts that are aware of the custom gas token used
///         by the L2 network.
interface IGasToken {
    /// @notice Getter for the ERC20 token address that is used to pay for gas and its decimals.
    function gasPayingToken() external view returns (address, uint8);
    /// @notice Returns the gas token name.
    function gasPayingTokenName() external view returns (string memory);
    /// @notice Returns the gas token symbol.
    function gasPayingTokenSymbol() external view returns (string memory);
    /// @notice Returns true if the network uses a custom gas token.
    function isCustomGasToken() external view returns (bool);
}

/// @title GasPayingToken
/// @notice Handles reading and writing the custom gas token to storage.
///         To be used in any place where gas token information is read or
///         written to state. If multiple contracts use this library, the
///         values in storage should be kept in sync between them.
library GasPayingToken {
    /// @notice The storage slot that contains the address and decimals of the gas paying token
    bytes32 internal constant GAS_PAYING_TOKEN_SLOT = bytes32(uint256(keccak256("opstack.gaspayingtoken")) - 1);

    /// @notice The storage slot that contains the ERC20 `name()` of the gas paying token
    bytes32 internal constant GAS_PAYING_TOKEN_NAME_SLOT = bytes32(uint256(keccak256("opstack.gaspayingtokenname")) - 1);

    /// @notice the storage slot that contains the ERC20 `symbol()` of the gas paying token
    bytes32 internal constant GAS_PAYING_TOKEN_SYMBOL_SLOT =
        bytes32(uint256(keccak256("opstack.gaspayingtokensymbol")) - 1);

    /// @notice Reads the gas paying token and its decimals from the magic
    ///         storage slot. If nothing is set in storage, then the ether
    ///         address is returned instead.
    function getToken() internal view returns (address addr_, uint8 decimals_) {
        bytes32 slot = Storage.getBytes32(GAS_PAYING_TOKEN_SLOT);
        addr_ = address(uint160(uint256(slot) & uint256(type(uint160).max)));
        if (addr_ == address(0)) {
            addr_ = Constants.ETHER;
            decimals_ = 18;
        } else {
            decimals_ = uint8(uint256(slot) >> 160);
        }
    }

    /// @notice Reads the gas paying token's name from the magic storage slot.
    ///         If nothing is set in storage, then the ether name, 'Ether', is returned instead.
    function getName() internal view returns (string memory name_) {
        (address addr,) = getToken();
        if (addr == Constants.ETHER) {
            name_ = "Ether";
        } else {
            name_ = LibString.fromSmallString(Storage.getBytes32(GAS_PAYING_TOKEN_NAME_SLOT));
        }
    }

    /// @notice Reads the gas paying token's symbol from the magic storage slot.
    ///         If nothing is set in storage, then the ether symbol, 'ETH', is returned instead.
    function getSymbol() internal view returns (string memory symbol_) {
        (address addr,) = getToken();
        if (addr == Constants.ETHER) {
            symbol_ = "ETH";
        } else {
            symbol_ = LibString.fromSmallString(Storage.getBytes32(GAS_PAYING_TOKEN_SYMBOL_SLOT));
        }
    }

    /// @notice Writes the gas paying token, its decimals, name and symbol to the magic storage slot.
    function set(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) internal {
        Storage.setBytes32(GAS_PAYING_TOKEN_SLOT, bytes32(uint256(_decimals) << 160 | uint256(uint160(_token))));
        Storage.setBytes32(GAS_PAYING_TOKEN_NAME_SLOT, _name);
        Storage.setBytes32(GAS_PAYING_TOKEN_SYMBOL_SLOT, _symbol);
    }

    /// @notice Maps a string to a normalized null-terminated small string.
    function sanitize(string memory _str) internal pure returns (bytes32) {
        require(bytes(_str).length <= 32, "GasPayingToken: string cannot be greater than 32 bytes");

        return LibString.toSmallString(_str);
    }
}

File 9 of 12 : L1BlockErrors.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/// @notice Error returns when a non-depositor account tries to set L1 block values.
error NotDepositor();

/// @notice Error when a non-cross L2 Inbox sender tries to call the `isDeposit()` method.
error NotCrossL2Inbox();

/// @notice Error when a chain ID is not in the interop dependency set.
error NotDependency();

/// @notice Error when the interop dependency set size is too large.
error DependencySetSizeTooLarge();

/// @notice Error when a chain ID already in the interop dependency set is attempted to be added.
error AlreadyDependency();

/// @notice Error when the chain's chain ID is attempted to be removed from the interop dependency set.
error CantRemovedDependency();

File 10 of 12 : IResourceMetering.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IResourceMetering {
    struct ResourceParams {
        uint128 prevBaseFee;
        uint64 prevBoughtGas;
        uint64 prevBlockNum;
    }

    struct ResourceConfig {
        uint32 maxResourceLimit;
        uint8 elasticityMultiplier;
        uint8 baseFeeMaxChangeDenominator;
        uint32 minimumBaseFee;
        uint32 systemTxMaxGas;
        uint128 maximumBaseFee;
    }

    error OutOfGas();

    event Initialized(uint8 version);

    function params() external view returns (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum);
}

File 11 of 12 : Storage.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/// @title Storage
/// @notice Storage handles reading and writing to arbitary storage locations
library Storage {
    /// @notice Returns an address stored in an arbitrary storage slot.
    ///         These storage slots decouple the storage layout from
    ///         solc's automation.
    /// @param _slot The storage slot to retrieve the address from.
    function getAddress(bytes32 _slot) internal view returns (address addr_) {
        assembly {
            addr_ := sload(_slot)
        }
    }

    /// @notice Stores an address in an arbitrary storage slot, `_slot`.
    /// @param _slot The storage slot to store the address in.
    /// @param _address The protocol version to store
    /// @dev WARNING! This function must be used cautiously, as it allows for overwriting addresses
    ///      in arbitrary storage slots.
    function setAddress(bytes32 _slot, address _address) internal {
        assembly {
            sstore(_slot, _address)
        }
    }

    /// @notice Returns a uint256 stored in an arbitrary storage slot.
    ///         These storage slots decouple the storage layout from
    ///         solc's automation.
    /// @param _slot The storage slot to retrieve the address from.
    function getUint(bytes32 _slot) internal view returns (uint256 value_) {
        assembly {
            value_ := sload(_slot)
        }
    }

    /// @notice Stores a value in an arbitrary storage slot, `_slot`.
    /// @param _slot The storage slot to store the address in.
    /// @param _value The protocol version to store
    /// @dev WARNING! This function must be used cautiously, as it allows for overwriting values
    ///      in arbitrary storage slots.
    function setUint(bytes32 _slot, uint256 _value) internal {
        assembly {
            sstore(_slot, _value)
        }
    }

    /// @notice Returns a bytes32 stored in an arbitrary storage slot.
    ///         These storage slots decouple the storage layout from
    ///         solc's automation.
    /// @param _slot The storage slot to retrieve the address from.
    function getBytes32(bytes32 _slot) internal view returns (bytes32 value_) {
        assembly {
            value_ := sload(_slot)
        }
    }

    /// @notice Stores a bytes32 value in an arbitrary storage slot, `_slot`.
    /// @param _slot The storage slot to store the address in.
    /// @param _value The bytes32 value to store.
    /// @dev WARNING! This function must be used cautiously, as it allows for overwriting values
    ///      in arbitrary storage slots.
    function setBytes32(bytes32 _slot, bytes32 _value) internal {
        assembly {
            sstore(_slot, _value)
        }
    }

    /// @notice Stores a bool value in an arbitrary storage slot, `_slot`.
    /// @param _slot The storage slot to store the bool in.
    /// @param _value The bool value to store
    /// @dev WARNING! This function must be used cautiously, as it allows for overwriting values
    ///      in arbitrary storage slots.
    function setBool(bytes32 _slot, bool _value) internal {
        assembly {
            sstore(_slot, _value)
        }
    }

    /// @notice Returns a bool stored in an arbitrary storage slot.
    /// @param _slot The storage slot to retrieve the bool from.
    function getBool(bytes32 _slot) internal view returns (bool value_) {
        assembly {
            value_ := sload(_slot)
        }
    }
}

File 12 of 12 : LibString.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Library for converting numbers into strings and other string operations.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibString.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol)
///
/// Note:
/// For performance and bytecode compactness, most of the string operations are restricted to
/// byte strings (7-bit ASCII), except where otherwise specified.
/// Usage of byte string operations on charsets with runes spanning two or more bytes
/// can lead to undefined behavior.
library LibString {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                        CUSTOM ERRORS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The length of the output is too small to contain all the hex digits.
    error HexLengthInsufficient();

    /// @dev The length of the string is more than 32 bytes.
    error TooBigForSmallString();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The constant returned when the `search` is not found in the string.
    uint256 internal constant NOT_FOUND = type(uint256).max;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     DECIMAL OPERATIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the base 10 decimal representation of `value`.
    function toString(uint256 value) internal pure returns (string memory str) {
        /// @solidity memory-safe-assembly
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit), but
            // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
            // We will need 1 word for the trailing zeros padding, 1 word for the length,
            // and 3 words for a maximum of 78 digits.
            str := add(mload(0x40), 0x80)
            // Update the free memory pointer to allocate.
            mstore(0x40, add(str, 0x20))
            // Zeroize the slot after the string.
            mstore(str, 0)

            // Cache the end of the memory to calculate the length later.
            let end := str

            let w := not(0) // Tsk.
            // We write the string from rightmost digit to leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            for { let temp := value } 1 {} {
                str := add(str, w) // `sub(str, 1)`.
                // Write the character to the pointer.
                // The ASCII index of the '0' character is 48.
                mstore8(str, add(48, mod(temp, 10)))
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
                if iszero(temp) { break }
            }

            let length := sub(end, str)
            // Move the pointer 32 bytes leftwards to make room for the length.
            str := sub(str, 0x20)
            // Store the length.
            mstore(str, length)
        }
    }

    /// @dev Returns the base 10 decimal representation of `value`.
    function toString(int256 value) internal pure returns (string memory str) {
        if (value >= 0) {
            return toString(uint256(value));
        }
        unchecked {
            str = toString(uint256(-value));
        }
        /// @solidity memory-safe-assembly
        assembly {
            // We still have some spare memory space on the left,
            // as we have allocated 3 words (96 bytes) for up to 78 digits.
            let length := mload(str) // Load the string length.
            mstore(str, 0x2d) // Store the '-' character.
            str := sub(str, 1) // Move back the string pointer by a byte.
            mstore(str, add(length, 1)) // Update the string length.
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   HEXADECIMAL OPERATIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the hexadecimal representation of `value`,
    /// left-padded to an input length of `length` bytes.
    /// The output is prefixed with "0x" encoded using 2 hexadecimal digits per byte,
    /// giving a total length of `length * 2 + 2` bytes.
    /// Reverts if `length` is too small for the output to contain all the digits.
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory str) {
        str = toHexStringNoPrefix(value, length);
        /// @solidity memory-safe-assembly
        assembly {
            let strLength := add(mload(str), 2) // Compute the length.
            mstore(str, 0x3078) // Write the "0x" prefix.
            str := sub(str, 2) // Move the pointer.
            mstore(str, strLength) // Write the length.
        }
    }

    /// @dev Returns the hexadecimal representation of `value`,
    /// left-padded to an input length of `length` bytes.
    /// The output is prefixed with "0x" encoded using 2 hexadecimal digits per byte,
    /// giving a total length of `length * 2` bytes.
    /// Reverts if `length` is too small for the output to contain all the digits.
    function toHexStringNoPrefix(uint256 value, uint256 length)
        internal
        pure
        returns (string memory str)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // We need 0x20 bytes for the trailing zeros padding, `length * 2` bytes
            // for the digits, 0x02 bytes for the prefix, and 0x20 bytes for the length.
            // We add 0x20 to the total and round down to a multiple of 0x20.
            // (0x20 + 0x20 + 0x02 + 0x20) = 0x62.
            str := add(mload(0x40), and(add(shl(1, length), 0x42), not(0x1f)))
            // Allocate the memory.
            mstore(0x40, add(str, 0x20))
            // Zeroize the slot after the string.
            mstore(str, 0)

            // Cache the end to calculate the length later.
            let end := str
            // Store "0123456789abcdef" in scratch space.
            mstore(0x0f, 0x30313233343536373839616263646566)

            let start := sub(str, add(length, length))
            let w := not(1) // Tsk.
            let temp := value
            // We write the string from rightmost digit to leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            for {} 1 {} {
                str := add(str, w) // `sub(str, 2)`.
                mstore8(add(str, 1), mload(and(temp, 15)))
                mstore8(str, mload(and(shr(4, temp), 15)))
                temp := shr(8, temp)
                if iszero(xor(str, start)) { break }
            }

            if temp {
                mstore(0x00, 0x2194895a) // `HexLengthInsufficient()`.
                revert(0x1c, 0x04)
            }

            // Compute the string's length.
            let strLength := sub(end, str)
            // Move the pointer and write the length.
            str := sub(str, 0x20)
            mstore(str, strLength)
        }
    }

    /// @dev Returns the hexadecimal representation of `value`.
    /// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte.
    /// As address are 20 bytes long, the output will left-padded to have
    /// a length of `20 * 2 + 2` bytes.
    function toHexString(uint256 value) internal pure returns (string memory str) {
        str = toHexStringNoPrefix(value);
        /// @solidity memory-safe-assembly
        assembly {
            let strLength := add(mload(str), 2) // Compute the length.
            mstore(str, 0x3078) // Write the "0x" prefix.
            str := sub(str, 2) // Move the pointer.
            mstore(str, strLength) // Write the length.
        }
    }

    /// @dev Returns the hexadecimal representation of `value`.
    /// The output is prefixed with "0x".
    /// The output excludes leading "0" from the `toHexString` output.
    /// `0x00: "0x0", 0x01: "0x1", 0x12: "0x12", 0x123: "0x123"`.
    function toMinimalHexString(uint256 value) internal pure returns (string memory str) {
        str = toHexStringNoPrefix(value);
        /// @solidity memory-safe-assembly
        assembly {
            let o := eq(byte(0, mload(add(str, 0x20))), 0x30) // Whether leading zero is present.
            let strLength := add(mload(str), 2) // Compute the length.
            mstore(add(str, o), 0x3078) // Write the "0x" prefix, accounting for leading zero.
            str := sub(add(str, o), 2) // Move the pointer, accounting for leading zero.
            mstore(str, sub(strLength, o)) // Write the length, accounting for leading zero.
        }
    }

    /// @dev Returns the hexadecimal representation of `value`.
    /// The output excludes leading "0" from the `toHexStringNoPrefix` output.
    /// `0x00: "0", 0x01: "1", 0x12: "12", 0x123: "123"`.
    function toMinimalHexStringNoPrefix(uint256 value) internal pure returns (string memory str) {
        str = toHexStringNoPrefix(value);
        /// @solidity memory-safe-assembly
        assembly {
            let o := eq(byte(0, mload(add(str, 0x20))), 0x30) // Whether leading zero is present.
            let strLength := mload(str) // Get the length.
            str := add(str, o) // Move the pointer, accounting for leading zero.
            mstore(str, sub(strLength, o)) // Write the length, accounting for leading zero.
        }
    }

    /// @dev Returns the hexadecimal representation of `value`.
    /// The output is encoded using 2 hexadecimal digits per byte.
    /// As address are 20 bytes long, the output will left-padded to have
    /// a length of `20 * 2` bytes.
    function toHexStringNoPrefix(uint256 value) internal pure returns (string memory str) {
        /// @solidity memory-safe-assembly
        assembly {
            // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,
            // 0x02 bytes for the prefix, and 0x40 bytes for the digits.
            // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x40) is 0xa0.
            str := add(mload(0x40), 0x80)
            // Allocate the memory.
            mstore(0x40, add(str, 0x20))
            // Zeroize the slot after the string.
            mstore(str, 0)

            // Cache the end to calculate the length later.
            let end := str
            // Store "0123456789abcdef" in scratch space.
            mstore(0x0f, 0x30313233343536373839616263646566)

            let w := not(1) // Tsk.
            // We write the string from rightmost digit to leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            for { let temp := value } 1 {} {
                str := add(str, w) // `sub(str, 2)`.
                mstore8(add(str, 1), mload(and(temp, 15)))
                mstore8(str, mload(and(shr(4, temp), 15)))
                temp := shr(8, temp)
                if iszero(temp) { break }
            }

            // Compute the string's length.
            let strLength := sub(end, str)
            // Move the pointer and write the length.
            str := sub(str, 0x20)
            mstore(str, strLength)
        }
    }

    /// @dev Returns the hexadecimal representation of `value`.
    /// The output is prefixed with "0x", encoded using 2 hexadecimal digits per byte,
    /// and the alphabets are capitalized conditionally according to
    /// https://eips.ethereum.org/EIPS/eip-55
    function toHexStringChecksummed(address value) internal pure returns (string memory str) {
        str = toHexString(value);
        /// @solidity memory-safe-assembly
        assembly {
            let mask := shl(6, div(not(0), 255)) // `0b010000000100000000 ...`
            let o := add(str, 0x22)
            let hashed := and(keccak256(o, 40), mul(34, mask)) // `0b10001000 ... `
            let t := shl(240, 136) // `0b10001000 << 240`
            for { let i := 0 } 1 {} {
                mstore(add(i, i), mul(t, byte(i, hashed)))
                i := add(i, 1)
                if eq(i, 20) { break }
            }
            mstore(o, xor(mload(o), shr(1, and(mload(0x00), and(mload(o), mask)))))
            o := add(o, 0x20)
            mstore(o, xor(mload(o), shr(1, and(mload(0x20), and(mload(o), mask)))))
        }
    }

    /// @dev Returns the hexadecimal representation of `value`.
    /// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte.
    function toHexString(address value) internal pure returns (string memory str) {
        str = toHexStringNoPrefix(value);
        /// @solidity memory-safe-assembly
        assembly {
            let strLength := add(mload(str), 2) // Compute the length.
            mstore(str, 0x3078) // Write the "0x" prefix.
            str := sub(str, 2) // Move the pointer.
            mstore(str, strLength) // Write the length.
        }
    }

    /// @dev Returns the hexadecimal representation of `value`.
    /// The output is encoded using 2 hexadecimal digits per byte.
    function toHexStringNoPrefix(address value) internal pure returns (string memory str) {
        /// @solidity memory-safe-assembly
        assembly {
            str := mload(0x40)

            // Allocate the memory.
            // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,
            // 0x02 bytes for the prefix, and 0x28 bytes for the digits.
            // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x28) is 0x80.
            mstore(0x40, add(str, 0x80))

            // Store "0123456789abcdef" in scratch space.
            mstore(0x0f, 0x30313233343536373839616263646566)

            str := add(str, 2)
            mstore(str, 40)

            let o := add(str, 0x20)
            mstore(add(o, 40), 0)

            value := shl(96, value)

            // We write the string from rightmost digit to leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            for { let i := 0 } 1 {} {
                let p := add(o, add(i, i))
                let temp := byte(i, value)
                mstore8(add(p, 1), mload(and(temp, 15)))
                mstore8(p, mload(shr(4, temp)))
                i := add(i, 1)
                if eq(i, 20) { break }
            }
        }
    }

    /// @dev Returns the hex encoded string from the raw bytes.
    /// The output is encoded using 2 hexadecimal digits per byte.
    function toHexString(bytes memory raw) internal pure returns (string memory str) {
        str = toHexStringNoPrefix(raw);
        /// @solidity memory-safe-assembly
        assembly {
            let strLength := add(mload(str), 2) // Compute the length.
            mstore(str, 0x3078) // Write the "0x" prefix.
            str := sub(str, 2) // Move the pointer.
            mstore(str, strLength) // Write the length.
        }
    }

    /// @dev Returns the hex encoded string from the raw bytes.
    /// The output is encoded using 2 hexadecimal digits per byte.
    function toHexStringNoPrefix(bytes memory raw) internal pure returns (string memory str) {
        /// @solidity memory-safe-assembly
        assembly {
            let length := mload(raw)
            str := add(mload(0x40), 2) // Skip 2 bytes for the optional prefix.
            mstore(str, add(length, length)) // Store the length of the output.

            // Store "0123456789abcdef" in scratch space.
            mstore(0x0f, 0x30313233343536373839616263646566)

            let o := add(str, 0x20)
            let end := add(raw, length)

            for {} iszero(eq(raw, end)) {} {
                raw := add(raw, 1)
                mstore8(add(o, 1), mload(and(mload(raw), 15)))
                mstore8(o, mload(and(shr(4, mload(raw)), 15)))
                o := add(o, 2)
            }
            mstore(o, 0) // Zeroize the slot after the string.
            mstore(0x40, add(o, 0x20)) // Allocate the memory.
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   RUNE STRING OPERATIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the number of UTF characters in the string.
    function runeCount(string memory s) internal pure returns (uint256 result) {
        /// @solidity memory-safe-assembly
        assembly {
            if mload(s) {
                mstore(0x00, div(not(0), 255))
                mstore(0x20, 0x0202020202020202020202020202020202020202020202020303030304040506)
                let o := add(s, 0x20)
                let end := add(o, mload(s))
                for { result := 1 } 1 { result := add(result, 1) } {
                    o := add(o, byte(0, mload(shr(250, mload(o)))))
                    if iszero(lt(o, end)) { break }
                }
            }
        }
    }

    /// @dev Returns if this string is a 7-bit ASCII string.
    /// (i.e. all characters codes are in [0..127])
    function is7BitASCII(string memory s) internal pure returns (bool result) {
        /// @solidity memory-safe-assembly
        assembly {
            let mask := shl(7, div(not(0), 255))
            result := 1
            let n := mload(s)
            if n {
                let o := add(s, 0x20)
                let end := add(o, n)
                let last := mload(end)
                mstore(end, 0)
                for {} 1 {} {
                    if and(mask, mload(o)) {
                        result := 0
                        break
                    }
                    o := add(o, 0x20)
                    if iszero(lt(o, end)) { break }
                }
                mstore(end, last)
            }
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   BYTE STRING OPERATIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // For performance and bytecode compactness, byte string operations are restricted
    // to 7-bit ASCII strings. All offsets are byte offsets, not UTF character offsets.
    // Usage of byte string operations on charsets with runes spanning two or more bytes
    // can lead to undefined behavior.

    /// @dev Returns `subject` all occurrences of `search` replaced with `replacement`.
    function replace(string memory subject, string memory search, string memory replacement)
        internal
        pure
        returns (string memory result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let subjectLength := mload(subject)
            let searchLength := mload(search)
            let replacementLength := mload(replacement)

            subject := add(subject, 0x20)
            search := add(search, 0x20)
            replacement := add(replacement, 0x20)
            result := add(mload(0x40), 0x20)

            let subjectEnd := add(subject, subjectLength)
            if iszero(gt(searchLength, subjectLength)) {
                let subjectSearchEnd := add(sub(subjectEnd, searchLength), 1)
                let h := 0
                if iszero(lt(searchLength, 0x20)) { h := keccak256(search, searchLength) }
                let m := shl(3, sub(0x20, and(searchLength, 0x1f)))
                let s := mload(search)
                for {} 1 {} {
                    let t := mload(subject)
                    // Whether the first `searchLength % 32` bytes of
                    // `subject` and `search` matches.
                    if iszero(shr(m, xor(t, s))) {
                        if h {
                            if iszero(eq(keccak256(subject, searchLength), h)) {
                                mstore(result, t)
                                result := add(result, 1)
                                subject := add(subject, 1)
                                if iszero(lt(subject, subjectSearchEnd)) { break }
                                continue
                            }
                        }
                        // Copy the `replacement` one word at a time.
                        for { let o := 0 } 1 {} {
                            mstore(add(result, o), mload(add(replacement, o)))
                            o := add(o, 0x20)
                            if iszero(lt(o, replacementLength)) { break }
                        }
                        result := add(result, replacementLength)
                        subject := add(subject, searchLength)
                        if searchLength {
                            if iszero(lt(subject, subjectSearchEnd)) { break }
                            continue
                        }
                    }
                    mstore(result, t)
                    result := add(result, 1)
                    subject := add(subject, 1)
                    if iszero(lt(subject, subjectSearchEnd)) { break }
                }
            }

            let resultRemainder := result
            result := add(mload(0x40), 0x20)
            let k := add(sub(resultRemainder, result), sub(subjectEnd, subject))
            // Copy the rest of the string one word at a time.
            for {} lt(subject, subjectEnd) {} {
                mstore(resultRemainder, mload(subject))
                resultRemainder := add(resultRemainder, 0x20)
                subject := add(subject, 0x20)
            }
            result := sub(result, 0x20)
            let last := add(add(result, 0x20), k) // Zeroize the slot after the string.
            mstore(last, 0)
            mstore(0x40, add(last, 0x20)) // Allocate the memory.
            mstore(result, k) // Store the length.
        }
    }

    /// @dev Returns the byte index of the first location of `search` in `subject`,
    /// searching from left to right, starting from `from`.
    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
    function indexOf(string memory subject, string memory search, uint256 from)
        internal
        pure
        returns (uint256 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            for { let subjectLength := mload(subject) } 1 {} {
                if iszero(mload(search)) {
                    if iszero(gt(from, subjectLength)) {
                        result := from
                        break
                    }
                    result := subjectLength
                    break
                }
                let searchLength := mload(search)
                let subjectStart := add(subject, 0x20)

                result := not(0) // Initialize to `NOT_FOUND`.

                subject := add(subjectStart, from)
                let end := add(sub(add(subjectStart, subjectLength), searchLength), 1)

                let m := shl(3, sub(0x20, and(searchLength, 0x1f)))
                let s := mload(add(search, 0x20))

                if iszero(and(lt(subject, end), lt(from, subjectLength))) { break }

                if iszero(lt(searchLength, 0x20)) {
                    for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} {
                        if iszero(shr(m, xor(mload(subject), s))) {
                            if eq(keccak256(subject, searchLength), h) {
                                result := sub(subject, subjectStart)
                                break
                            }
                        }
                        subject := add(subject, 1)
                        if iszero(lt(subject, end)) { break }
                    }
                    break
                }
                for {} 1 {} {
                    if iszero(shr(m, xor(mload(subject), s))) {
                        result := sub(subject, subjectStart)
                        break
                    }
                    subject := add(subject, 1)
                    if iszero(lt(subject, end)) { break }
                }
                break
            }
        }
    }

    /// @dev Returns the byte index of the first location of `search` in `subject`,
    /// searching from left to right.
    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
    function indexOf(string memory subject, string memory search)
        internal
        pure
        returns (uint256 result)
    {
        result = indexOf(subject, search, 0);
    }

    /// @dev Returns the byte index of the first location of `search` in `subject`,
    /// searching from right to left, starting from `from`.
    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
    function lastIndexOf(string memory subject, string memory search, uint256 from)
        internal
        pure
        returns (uint256 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            for {} 1 {} {
                result := not(0) // Initialize to `NOT_FOUND`.
                let searchLength := mload(search)
                if gt(searchLength, mload(subject)) { break }
                let w := result

                let fromMax := sub(mload(subject), searchLength)
                if iszero(gt(fromMax, from)) { from := fromMax }

                let end := add(add(subject, 0x20), w)
                subject := add(add(subject, 0x20), from)
                if iszero(gt(subject, end)) { break }
                // As this function is not too often used,
                // we shall simply use keccak256 for smaller bytecode size.
                for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} {
                    if eq(keccak256(subject, searchLength), h) {
                        result := sub(subject, add(end, 1))
                        break
                    }
                    subject := add(subject, w) // `sub(subject, 1)`.
                    if iszero(gt(subject, end)) { break }
                }
                break
            }
        }
    }

    /// @dev Returns the byte index of the first location of `search` in `subject`,
    /// searching from right to left.
    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
    function lastIndexOf(string memory subject, string memory search)
        internal
        pure
        returns (uint256 result)
    {
        result = lastIndexOf(subject, search, uint256(int256(-1)));
    }

    /// @dev Returns true if `search` is found in `subject`, false otherwise.
    function contains(string memory subject, string memory search) internal pure returns (bool) {
        return indexOf(subject, search) != NOT_FOUND;
    }

    /// @dev Returns whether `subject` starts with `search`.
    function startsWith(string memory subject, string memory search)
        internal
        pure
        returns (bool result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let searchLength := mload(search)
            // Just using keccak256 directly is actually cheaper.
            // forgefmt: disable-next-item
            result := and(
                iszero(gt(searchLength, mload(subject))),
                eq(
                    keccak256(add(subject, 0x20), searchLength),
                    keccak256(add(search, 0x20), searchLength)
                )
            )
        }
    }

    /// @dev Returns whether `subject` ends with `search`.
    function endsWith(string memory subject, string memory search)
        internal
        pure
        returns (bool result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let searchLength := mload(search)
            let subjectLength := mload(subject)
            // Whether `search` is not longer than `subject`.
            let withinRange := iszero(gt(searchLength, subjectLength))
            // Just using keccak256 directly is actually cheaper.
            // forgefmt: disable-next-item
            result := and(
                withinRange,
                eq(
                    keccak256(
                        // `subject + 0x20 + max(subjectLength - searchLength, 0)`.
                        add(add(subject, 0x20), mul(withinRange, sub(subjectLength, searchLength))),
                        searchLength
                    ),
                    keccak256(add(search, 0x20), searchLength)
                )
            )
        }
    }

    /// @dev Returns `subject` repeated `times`.
    function repeat(string memory subject, uint256 times)
        internal
        pure
        returns (string memory result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let subjectLength := mload(subject)
            if iszero(or(iszero(times), iszero(subjectLength))) {
                subject := add(subject, 0x20)
                result := mload(0x40)
                let output := add(result, 0x20)
                for {} 1 {} {
                    // Copy the `subject` one word at a time.
                    for { let o := 0 } 1 {} {
                        mstore(add(output, o), mload(add(subject, o)))
                        o := add(o, 0x20)
                        if iszero(lt(o, subjectLength)) { break }
                    }
                    output := add(output, subjectLength)
                    times := sub(times, 1)
                    if iszero(times) { break }
                }
                mstore(output, 0) // Zeroize the slot after the string.
                let resultLength := sub(output, add(result, 0x20))
                mstore(result, resultLength) // Store the length.
                // Allocate the memory.
                mstore(0x40, add(result, add(resultLength, 0x20)))
            }
        }
    }

    /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive).
    /// `start` and `end` are byte offsets.
    function slice(string memory subject, uint256 start, uint256 end)
        internal
        pure
        returns (string memory result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let subjectLength := mload(subject)
            if iszero(gt(subjectLength, end)) { end := subjectLength }
            if iszero(gt(subjectLength, start)) { start := subjectLength }
            if lt(start, end) {
                result := mload(0x40)
                let resultLength := sub(end, start)
                mstore(result, resultLength)
                subject := add(subject, start)
                let w := not(0x1f)
                // Copy the `subject` one word at a time, backwards.
                for { let o := and(add(resultLength, 0x1f), w) } 1 {} {
                    mstore(add(result, o), mload(add(subject, o)))
                    o := add(o, w) // `sub(o, 0x20)`.
                    if iszero(o) { break }
                }
                // Zeroize the slot after the string.
                mstore(add(add(result, 0x20), resultLength), 0)
                // Allocate memory for the length and the bytes,
                // rounded up to a multiple of 32.
                mstore(0x40, add(result, and(add(resultLength, 0x3f), w)))
            }
        }
    }

    /// @dev Returns a copy of `subject` sliced from `start` to the end of the string.
    /// `start` is a byte offset.
    function slice(string memory subject, uint256 start)
        internal
        pure
        returns (string memory result)
    {
        result = slice(subject, start, uint256(int256(-1)));
    }

    /// @dev Returns all the indices of `search` in `subject`.
    /// The indices are byte offsets.
    function indicesOf(string memory subject, string memory search)
        internal
        pure
        returns (uint256[] memory result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let subjectLength := mload(subject)
            let searchLength := mload(search)

            if iszero(gt(searchLength, subjectLength)) {
                subject := add(subject, 0x20)
                search := add(search, 0x20)
                result := add(mload(0x40), 0x20)

                let subjectStart := subject
                let subjectSearchEnd := add(sub(add(subject, subjectLength), searchLength), 1)
                let h := 0
                if iszero(lt(searchLength, 0x20)) { h := keccak256(search, searchLength) }
                let m := shl(3, sub(0x20, and(searchLength, 0x1f)))
                let s := mload(search)
                for {} 1 {} {
                    let t := mload(subject)
                    // Whether the first `searchLength % 32` bytes of
                    // `subject` and `search` matches.
                    if iszero(shr(m, xor(t, s))) {
                        if h {
                            if iszero(eq(keccak256(subject, searchLength), h)) {
                                subject := add(subject, 1)
                                if iszero(lt(subject, subjectSearchEnd)) { break }
                                continue
                            }
                        }
                        // Append to `result`.
                        mstore(result, sub(subject, subjectStart))
                        result := add(result, 0x20)
                        // Advance `subject` by `searchLength`.
                        subject := add(subject, searchLength)
                        if searchLength {
                            if iszero(lt(subject, subjectSearchEnd)) { break }
                            continue
                        }
                    }
                    subject := add(subject, 1)
                    if iszero(lt(subject, subjectSearchEnd)) { break }
                }
                let resultEnd := result
                // Assign `result` to the free memory pointer.
                result := mload(0x40)
                // Store the length of `result`.
                mstore(result, shr(5, sub(resultEnd, add(result, 0x20))))
                // Allocate memory for result.
                // We allocate one more word, so this array can be recycled for {split}.
                mstore(0x40, add(resultEnd, 0x20))
            }
        }
    }

    /// @dev Returns a arrays of strings based on the `delimiter` inside of the `subject` string.
    function split(string memory subject, string memory delimiter)
        internal
        pure
        returns (string[] memory result)
    {
        uint256[] memory indices = indicesOf(subject, delimiter);
        /// @solidity memory-safe-assembly
        assembly {
            let w := not(0x1f)
            let indexPtr := add(indices, 0x20)
            let indicesEnd := add(indexPtr, shl(5, add(mload(indices), 1)))
            mstore(add(indicesEnd, w), mload(subject))
            mstore(indices, add(mload(indices), 1))
            let prevIndex := 0
            for {} 1 {} {
                let index := mload(indexPtr)
                mstore(indexPtr, 0x60)
                if iszero(eq(index, prevIndex)) {
                    let element := mload(0x40)
                    let elementLength := sub(index, prevIndex)
                    mstore(element, elementLength)
                    // Copy the `subject` one word at a time, backwards.
                    for { let o := and(add(elementLength, 0x1f), w) } 1 {} {
                        mstore(add(element, o), mload(add(add(subject, prevIndex), o)))
                        o := add(o, w) // `sub(o, 0x20)`.
                        if iszero(o) { break }
                    }
                    // Zeroize the slot after the string.
                    mstore(add(add(element, 0x20), elementLength), 0)
                    // Allocate memory for the length and the bytes,
                    // rounded up to a multiple of 32.
                    mstore(0x40, add(element, and(add(elementLength, 0x3f), w)))
                    // Store the `element` into the array.
                    mstore(indexPtr, element)
                }
                prevIndex := add(index, mload(delimiter))
                indexPtr := add(indexPtr, 0x20)
                if iszero(lt(indexPtr, indicesEnd)) { break }
            }
            result := indices
            if iszero(mload(delimiter)) {
                result := add(indices, 0x20)
                mstore(result, sub(mload(indices), 2))
            }
        }
    }

    /// @dev Returns a concatenated string of `a` and `b`.
    /// Cheaper than `string.concat()` and does not de-align the free memory pointer.
    function concat(string memory a, string memory b)
        internal
        pure
        returns (string memory result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let w := not(0x1f)
            result := mload(0x40)
            let aLength := mload(a)
            // Copy `a` one word at a time, backwards.
            for { let o := and(add(aLength, 0x20), w) } 1 {} {
                mstore(add(result, o), mload(add(a, o)))
                o := add(o, w) // `sub(o, 0x20)`.
                if iszero(o) { break }
            }
            let bLength := mload(b)
            let output := add(result, aLength)
            // Copy `b` one word at a time, backwards.
            for { let o := and(add(bLength, 0x20), w) } 1 {} {
                mstore(add(output, o), mload(add(b, o)))
                o := add(o, w) // `sub(o, 0x20)`.
                if iszero(o) { break }
            }
            let totalLength := add(aLength, bLength)
            let last := add(add(result, 0x20), totalLength)
            // Zeroize the slot after the string.
            mstore(last, 0)
            // Stores the length.
            mstore(result, totalLength)
            // Allocate memory for the length and the bytes,
            // rounded up to a multiple of 32.
            mstore(0x40, and(add(last, 0x1f), w))
        }
    }

    /// @dev Returns a copy of the string in either lowercase or UPPERCASE.
    /// WARNING! This function is only compatible with 7-bit ASCII strings.
    function toCase(string memory subject, bool toUpper)
        internal
        pure
        returns (string memory result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let length := mload(subject)
            if length {
                result := add(mload(0x40), 0x20)
                subject := add(subject, 1)
                let flags := shl(add(70, shl(5, toUpper)), 0x3ffffff)
                let w := not(0)
                for { let o := length } 1 {} {
                    o := add(o, w)
                    let b := and(0xff, mload(add(subject, o)))
                    mstore8(add(result, o), xor(b, and(shr(b, flags), 0x20)))
                    if iszero(o) { break }
                }
                result := mload(0x40)
                mstore(result, length) // Store the length.
                let last := add(add(result, 0x20), length)
                mstore(last, 0) // Zeroize the slot after the string.
                mstore(0x40, add(last, 0x20)) // Allocate the memory.
            }
        }
    }

    /// @dev Returns a string from a small bytes32 string.
    /// `s` must be null-terminated, or behavior will be undefined.
    function fromSmallString(bytes32 s) internal pure returns (string memory result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := mload(0x40)
            let n := 0
            for {} byte(n, s) { n := add(n, 1) } {} // Scan for '\0'.
            mstore(result, n)
            let o := add(result, 0x20)
            mstore(o, s)
            mstore(add(o, n), 0)
            mstore(0x40, add(result, 0x40))
        }
    }

    /// @dev Returns the small string, with all bytes after the first null byte zeroized.
    function normalizeSmallString(bytes32 s) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            for {} byte(result, s) { result := add(result, 1) } {} // Scan for '\0'.
            mstore(0x00, s)
            mstore(result, 0x00)
            result := mload(0x00)
        }
    }

    /// @dev Returns the string as a normalized null-terminated small string.
    function toSmallString(string memory s) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := mload(s)
            if iszero(lt(result, 33)) {
                mstore(0x00, 0xec92f9a3) // `TooBigForSmallString()`.
                revert(0x1c, 0x04)
            }
            result := shl(shl(3, sub(32, result)), mload(add(s, result)))
        }
    }

    /// @dev Returns a lowercased copy of the string.
    /// WARNING! This function is only compatible with 7-bit ASCII strings.
    function lower(string memory subject) internal pure returns (string memory result) {
        result = toCase(subject, false);
    }

    /// @dev Returns an UPPERCASED copy of the string.
    /// WARNING! This function is only compatible with 7-bit ASCII strings.
    function upper(string memory subject) internal pure returns (string memory result) {
        result = toCase(subject, true);
    }

    /// @dev Escapes the string to be used within HTML tags.
    function escapeHTML(string memory s) internal pure returns (string memory result) {
        /// @solidity memory-safe-assembly
        assembly {
            let end := add(s, mload(s))
            result := add(mload(0x40), 0x20)
            // Store the bytes of the packed offsets and strides into the scratch space.
            // `packed = (stride << 5) | offset`. Max offset is 20. Max stride is 6.
            mstore(0x1f, 0x900094)
            mstore(0x08, 0xc0000000a6ab)
            // Store "&quot;&amp;&#39;&lt;&gt;" into the scratch space.
            mstore(0x00, shl(64, 0x2671756f743b26616d703b262333393b266c743b2667743b))
            for {} iszero(eq(s, end)) {} {
                s := add(s, 1)
                let c := and(mload(s), 0xff)
                // Not in `["\"","'","&","<",">"]`.
                if iszero(and(shl(c, 1), 0x500000c400000000)) {
                    mstore8(result, c)
                    result := add(result, 1)
                    continue
                }
                let t := shr(248, mload(c))
                mstore(result, mload(and(t, 0x1f)))
                result := add(result, shr(5, t))
            }
            let last := result
            mstore(last, 0) // Zeroize the slot after the string.
            result := mload(0x40)
            mstore(result, sub(last, add(result, 0x20))) // Store the length.
            mstore(0x40, add(last, 0x20)) // Allocate the memory.
        }
    }

    /// @dev Escapes the string to be used within double-quotes in a JSON.
    /// If `addDoubleQuotes` is true, the result will be enclosed in double-quotes.
    function escapeJSON(string memory s, bool addDoubleQuotes)
        internal
        pure
        returns (string memory result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let end := add(s, mload(s))
            result := add(mload(0x40), 0x20)
            if addDoubleQuotes {
                mstore8(result, 34)
                result := add(1, result)
            }
            // Store "\\u0000" in scratch space.
            // Store "0123456789abcdef" in scratch space.
            // Also, store `{0x08:"b", 0x09:"t", 0x0a:"n", 0x0c:"f", 0x0d:"r"}`.
            // into the scratch space.
            mstore(0x15, 0x5c75303030303031323334353637383961626364656662746e006672)
            // Bitmask for detecting `["\"","\\"]`.
            let e := or(shl(0x22, 1), shl(0x5c, 1))
            for {} iszero(eq(s, end)) {} {
                s := add(s, 1)
                let c := and(mload(s), 0xff)
                if iszero(lt(c, 0x20)) {
                    if iszero(and(shl(c, 1), e)) {
                        // Not in `["\"","\\"]`.
                        mstore8(result, c)
                        result := add(result, 1)
                        continue
                    }
                    mstore8(result, 0x5c) // "\\".
                    mstore8(add(result, 1), c)
                    result := add(result, 2)
                    continue
                }
                if iszero(and(shl(c, 1), 0x3700)) {
                    // Not in `["\b","\t","\n","\f","\d"]`.
                    mstore8(0x1d, mload(shr(4, c))) // Hex value.
                    mstore8(0x1e, mload(and(c, 15))) // Hex value.
                    mstore(result, mload(0x19)) // "\\u00XX".
                    result := add(result, 6)
                    continue
                }
                mstore8(result, 0x5c) // "\\".
                mstore8(add(result, 1), mload(add(c, 8)))
                result := add(result, 2)
            }
            if addDoubleQuotes {
                mstore8(result, 34)
                result := add(1, result)
            }
            let last := result
            mstore(last, 0) // Zeroize the slot after the string.
            result := mload(0x40)
            mstore(result, sub(last, add(result, 0x20))) // Store the length.
            mstore(0x40, add(last, 0x20)) // Allocate the memory.
        }
    }

    /// @dev Escapes the string to be used within double-quotes in a JSON.
    function escapeJSON(string memory s) internal pure returns (string memory result) {
        result = escapeJSON(s, false);
    }

    /// @dev Returns whether `a` equals `b`.
    function eq(string memory a, string memory b) internal pure returns (bool result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := eq(keccak256(add(a, 0x20), mload(a)), keccak256(add(b, 0x20), mload(b)))
        }
    }

    /// @dev Returns whether `a` equals `b`, where `b` is a null-terminated small string.
    function eqs(string memory a, bytes32 b) internal pure returns (bool result) {
        /// @solidity memory-safe-assembly
        assembly {
            // These should be evaluated on compile time, as far as possible.
            let m := not(shl(7, div(not(iszero(b)), 255))) // `0x7f7f ...`.
            let x := not(or(m, or(b, add(m, and(b, m)))))
            let r := shl(7, iszero(iszero(shr(128, x))))
            r := or(r, shl(6, iszero(iszero(shr(64, shr(r, x))))))
            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
            r := or(r, shl(4, lt(0xffff, shr(r, x))))
            r := or(r, shl(3, lt(0xff, shr(r, x))))
            // forgefmt: disable-next-item
            result := gt(eq(mload(a), add(iszero(x), xor(31, shr(3, r)))),
                xor(shr(add(8, r), b), shr(add(8, r), mload(add(a, 0x20)))))
        }
    }

    /// @dev Packs a single string with its length into a single word.
    /// Returns `bytes32(0)` if the length is zero or greater than 31.
    function packOne(string memory a) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            // We don't need to zero right pad the string,
            // since this is our own custom non-standard packing scheme.
            result :=
                mul(
                    // Load the length and the bytes.
                    mload(add(a, 0x1f)),
                    // `length != 0 && length < 32`. Abuses underflow.
                    // Assumes that the length is valid and within the block gas limit.
                    lt(sub(mload(a), 1), 0x1f)
                )
        }
    }

    /// @dev Unpacks a string packed using {packOne}.
    /// Returns the empty string if `packed` is `bytes32(0)`.
    /// If `packed` is not an output of {packOne}, the output behavior is undefined.
    function unpackOne(bytes32 packed) internal pure returns (string memory result) {
        /// @solidity memory-safe-assembly
        assembly {
            // Grab the free memory pointer.
            result := mload(0x40)
            // Allocate 2 words (1 for the length, 1 for the bytes).
            mstore(0x40, add(result, 0x40))
            // Zeroize the length slot.
            mstore(result, 0)
            // Store the length and bytes.
            mstore(add(result, 0x1f), packed)
            // Right pad with zeroes.
            mstore(add(add(result, 0x20), mload(result)), 0)
        }
    }

    /// @dev Packs two strings with their lengths into a single word.
    /// Returns `bytes32(0)` if combined length is zero or greater than 30.
    function packTwo(string memory a, string memory b) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let aLength := mload(a)
            // We don't need to zero right pad the strings,
            // since this is our own custom non-standard packing scheme.
            result :=
                mul(
                    // Load the length and the bytes of `a` and `b`.
                    or(
                        shl(shl(3, sub(0x1f, aLength)), mload(add(a, aLength))),
                        mload(sub(add(b, 0x1e), aLength))
                    ),
                    // `totalLength != 0 && totalLength < 31`. Abuses underflow.
                    // Assumes that the lengths are valid and within the block gas limit.
                    lt(sub(add(aLength, mload(b)), 1), 0x1e)
                )
        }
    }

    /// @dev Unpacks strings packed using {packTwo}.
    /// Returns the empty strings if `packed` is `bytes32(0)`.
    /// If `packed` is not an output of {packTwo}, the output behavior is undefined.
    function unpackTwo(bytes32 packed)
        internal
        pure
        returns (string memory resultA, string memory resultB)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Grab the free memory pointer.
            resultA := mload(0x40)
            resultB := add(resultA, 0x40)
            // Allocate 2 words for each string (1 for the length, 1 for the byte). Total 4 words.
            mstore(0x40, add(resultB, 0x40))
            // Zeroize the length slots.
            mstore(resultA, 0)
            mstore(resultB, 0)
            // Store the lengths and bytes.
            mstore(add(resultA, 0x1f), packed)
            mstore(add(resultB, 0x1f), mload(add(add(resultA, 0x20), mload(resultA))))
            // Right pad with zeroes.
            mstore(add(add(resultA, 0x20), mload(resultA)), 0)
            mstore(add(add(resultB, 0x20), mload(resultB)), 0)
        }
    }

    /// @dev Directly returns `a` without copying.
    function directReturn(string memory a) internal pure {
        assembly {
            // Assumes that the string does not start from the scratch space.
            let retStart := sub(a, 0x20)
            let retSize := add(mload(a), 0x40)
            // Right pad with zeroes. Just in case the string is produced
            // by a method that doesn't zero right pad.
            mstore(add(retStart, retSize), 0)
            // Store the return offset.
            mstore(retStart, 0x20)
            // End the transaction, returning the string.
            return(retStart, retSize)
        }
    }
}

Settings
{
  "remappings": [
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "@openzeppelin/contracts-v5/=lib/openzeppelin-contracts-v5/contracts/",
    "@rari-capital/solmate/=lib/solmate/",
    "@lib-keccak/=lib/lib-keccak/contracts/lib/",
    "@solady/=lib/solady/src/",
    "forge-std/=lib/forge-std/src/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "safe-contracts/=lib/safe-contracts/contracts/",
    "kontrol-cheatcodes/=lib/kontrol-cheatcodes/src/",
    "gelato/=lib/automate/contracts/",
    "@solady-test/=lib/lib-keccak/lib/solady/test/",
    "automate/=lib/automate/contracts/",
    "erc4626-tests/=lib/openzeppelin-contracts-v5/lib/erc4626-tests/",
    "hardhat/=lib/automate/node_modules/hardhat/",
    "lib-keccak/=lib/lib-keccak/contracts/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts-v5/=lib/openzeppelin-contracts-v5/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "prb-test/=lib/automate/lib/prb-test/src/",
    "prb/-est/=lib/automate/lib/prb-test/src/",
    "solady/=lib/solady/",
    "solmate/=lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 999999
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "none"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":true,"internalType":"address","name":"guy","type":"address"},{"indexed":false,"internalType":"uint256","name":"wad","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"dst","type":"address"},{"indexed":false,"internalType":"uint256","name":"wad","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":true,"internalType":"address","name":"dst","type":"address"},{"indexed":false,"internalType":"uint256","name":"wad","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":false,"internalType":"uint256","name":"wad","type":"uint256"}],"name":"Withdrawal","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"name_","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"symbol_","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6080604052600436106100cb5760003560e01c806354fd4d5011610074578063a9059cbb1161004e578063a9059cbb1461024c578063d0e30db0146100da578063dd62ed3e1461026c576100da565b806354fd4d50146101c157806370a082311461020a57806395d89b4114610237576100da565b806323b872dd116100a557806323b872dd1461015a5780632e1a7d4d1461017a578063313ce5671461019a576100da565b806306fdde03146100e2578063095ea7b31461010d57806318160ddd1461013d576100da565b366100da576100d86102a4565b005b6100d86102a4565b3480156100ee57600080fd5b506100f76102ff565b60405161010491906107fb565b60405180910390f35b34801561011957600080fd5b5061012d610128366004610875565b6103ca565b6040519015158152602001610104565b34801561014957600080fd5b50475b604051908152602001610104565b34801561016657600080fd5b5061012d61017536600461089f565b610443565b34801561018657600080fd5b506100d86101953660046108db565b61065a565b3480156101a657600080fd5b506101af601281565b60405160ff9091168152602001610104565b3480156101cd57600080fd5b506100f76040518060400160405280600c81526020017f312e302e302d626574612e31000000000000000000000000000000000000000081525081565b34801561021657600080fd5b5061014c6102253660046108f4565b60006020819052908152604090205481565b34801561024357600080fd5b506100f7610700565b34801561025857600080fd5b5061012d610267366004610875565b6107b7565b34801561027857600080fd5b5061014c61028736600461090f565b600160209081526000928352604080842090915290825290205481565b33600090815260208190526040812080543492906102c3908490610971565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b606073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663d84447156040518163ffffffff1660e01b8152600401600060405180830381865afa158015610360573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103a691908101906109b8565b6040516020016103b69190610a83565b604051602081830303815290604052905090565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906104329086815260200190565b60405180910390a350600192915050565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081205482111561047557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841633148015906104eb575073ffffffffffffffffffffffffffffffffffffffff841660009081526001602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105735773ffffffffffffffffffffffffffffffffffffffff8416600090815260016020908152604080832033845290915290205482111561052d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526001602090815260408083203384529091528120805484929061056d908490610ac8565b90915550505b73ffffffffffffffffffffffffffffffffffffffff8416600090815260208190526040812080548492906105a8908490610ac8565b909155505073ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812080548492906105e2908490610971565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161064891815260200190565b60405180910390a35060019392505050565b3360009081526020819052604090205481111561067657600080fd5b3360009081526020819052604081208054839290610695908490610ac8565b9091555050604051339082156108fc029083906000818181858888f193505050501580156106c7573d6000803e3d6000fd5b5060405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a250565b606073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663550fcdc96040518163ffffffff1660e01b8152600401600060405180830381865afa158015610761573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526107a791908101906109b8565b6040516020016103b69190610adf565b60006107c4338484610443565b9392505050565b60005b838110156107e65781810151838201526020016107ce565b838111156107f5576000848401525b50505050565b602081526000825180602084015261081a8160408501602087016107cb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461087057600080fd5b919050565b6000806040838503121561088857600080fd5b6108918361084c565b946020939093013593505050565b6000806000606084860312156108b457600080fd5b6108bd8461084c565b92506108cb6020850161084c565b9150604084013590509250925092565b6000602082840312156108ed57600080fd5b5035919050565b60006020828403121561090657600080fd5b6107c48261084c565b6000806040838503121561092257600080fd5b61092b8361084c565b91506109396020840161084c565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561098457610984610942565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156109ca57600080fd5b815167ffffffffffffffff808211156109e257600080fd5b818401915084601f8301126109f657600080fd5b815181811115610a0857610a08610989565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610a4e57610a4e610989565b81604052828152876020848701011115610a6757600080fd5b610a788360208301602088016107cb565b979650505050505050565b7f5772617070656420000000000000000000000000000000000000000000000000815260008251610abb8160088501602087016107cb565b9190910160080192915050565b600082821015610ada57610ada610942565b500390565b7f5700000000000000000000000000000000000000000000000000000000000000815260008251610b178160018501602087016107cb565b919091016001019291505056fea164736f6c634300080f000a

Deployed Bytecode

0x6080604052600436106100cb5760003560e01c806354fd4d5011610074578063a9059cbb1161004e578063a9059cbb1461024c578063d0e30db0146100da578063dd62ed3e1461026c576100da565b806354fd4d50146101c157806370a082311461020a57806395d89b4114610237576100da565b806323b872dd116100a557806323b872dd1461015a5780632e1a7d4d1461017a578063313ce5671461019a576100da565b806306fdde03146100e2578063095ea7b31461010d57806318160ddd1461013d576100da565b366100da576100d86102a4565b005b6100d86102a4565b3480156100ee57600080fd5b506100f76102ff565b60405161010491906107fb565b60405180910390f35b34801561011957600080fd5b5061012d610128366004610875565b6103ca565b6040519015158152602001610104565b34801561014957600080fd5b50475b604051908152602001610104565b34801561016657600080fd5b5061012d61017536600461089f565b610443565b34801561018657600080fd5b506100d86101953660046108db565b61065a565b3480156101a657600080fd5b506101af601281565b60405160ff9091168152602001610104565b3480156101cd57600080fd5b506100f76040518060400160405280600c81526020017f312e302e302d626574612e31000000000000000000000000000000000000000081525081565b34801561021657600080fd5b5061014c6102253660046108f4565b60006020819052908152604090205481565b34801561024357600080fd5b506100f7610700565b34801561025857600080fd5b5061012d610267366004610875565b6107b7565b34801561027857600080fd5b5061014c61028736600461090f565b600160209081526000928352604080842090915290825290205481565b33600090815260208190526040812080543492906102c3908490610971565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b606073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663d84447156040518163ffffffff1660e01b8152600401600060405180830381865afa158015610360573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103a691908101906109b8565b6040516020016103b69190610a83565b604051602081830303815290604052905090565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906104329086815260200190565b60405180910390a350600192915050565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081205482111561047557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841633148015906104eb575073ffffffffffffffffffffffffffffffffffffffff841660009081526001602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105735773ffffffffffffffffffffffffffffffffffffffff8416600090815260016020908152604080832033845290915290205482111561052d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526001602090815260408083203384529091528120805484929061056d908490610ac8565b90915550505b73ffffffffffffffffffffffffffffffffffffffff8416600090815260208190526040812080548492906105a8908490610ac8565b909155505073ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812080548492906105e2908490610971565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161064891815260200190565b60405180910390a35060019392505050565b3360009081526020819052604090205481111561067657600080fd5b3360009081526020819052604081208054839290610695908490610ac8565b9091555050604051339082156108fc029083906000818181858888f193505050501580156106c7573d6000803e3d6000fd5b5060405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a250565b606073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663550fcdc96040518163ffffffff1660e01b8152600401600060405180830381865afa158015610761573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526107a791908101906109b8565b6040516020016103b69190610adf565b60006107c4338484610443565b9392505050565b60005b838110156107e65781810151838201526020016107ce565b838111156107f5576000848401525b50505050565b602081526000825180602084015261081a8160408501602087016107cb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461087057600080fd5b919050565b6000806040838503121561088857600080fd5b6108918361084c565b946020939093013593505050565b6000806000606084860312156108b457600080fd5b6108bd8461084c565b92506108cb6020850161084c565b9150604084013590509250925092565b6000602082840312156108ed57600080fd5b5035919050565b60006020828403121561090657600080fd5b6107c48261084c565b6000806040838503121561092257600080fd5b61092b8361084c565b91506109396020840161084c565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561098457610984610942565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156109ca57600080fd5b815167ffffffffffffffff808211156109e257600080fd5b818401915084601f8301126109f657600080fd5b815181811115610a0857610a08610989565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610a4e57610a4e610989565b81604052828152876020848701011115610a6757600080fd5b610a788360208301602088016107cb565b979650505050505050565b7f5772617070656420000000000000000000000000000000000000000000000000815260008251610abb8160088501602087016107cb565b9190910160080192915050565b600082821015610ada57610ada610942565b500390565b7f5700000000000000000000000000000000000000000000000000000000000000815260008251610b178160018501602087016107cb565b919091016001019291505056fea164736f6c634300080f000a

Deployed Bytecode Sourcemap

451:757:3:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1214:9:5;:7;:9::i;:::-;451:757:3;;1308:9:5;:7;:9::i;712:181:3:-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2190:182:5;;;;;;;;;;-1:-1:-1;2190:182:5;;;;;:::i;:::-;;:::i;:::-;;;1349:14:12;;1342:22;1324:41;;1312:2;1297:18;2190:182:5;1184:187:12;2058:100:5;;;;;;;;;;-1:-1:-1;2130:21:5;2058:100;;;1522:25:12;;;1510:2;1495:18;2058:100:5;1376:177:12;2562:452:5;;;;;;;;;;-1:-1:-1;2562:452:5;;;;;:::i;:::-;;:::i;1803:223::-;;;;;;;;;;-1:-1:-1;1803:223:5;;;;;:::i;:::-;;:::i;980:35::-;;;;;;;;;;;;1013:2;980:35;;;;;2248:4:12;2236:17;;;2218:36;;2206:2;2191:18;980:35:5;2076:184:12;526:47:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1022:44:5;;;;;;;;;;-1:-1:-1;1022:44:5;;;;;:::i;:::-;;;;;;;;;;;;;;;1024:182:3;;;;;;;;;;;;;:::i;2404:126:5:-;;;;;;;;;;-1:-1:-1;2404:126:5;;;;;:::i;:::-;;:::i;1072:64::-;;;;;;;;;;-1:-1:-1;1072:64:5;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;1633:138;1695:10;1685:9;:21;;;;;;;;;;:34;;1710:9;;1685;:34;;1710:9;;1685:34;:::i;:::-;;;;-1:-1:-1;;1734:30:5;;1754:9;1522:25:12;;1742:10:5;;1734:30;;1510:2:12;1495:18;1734:30:5;;;;;;;1633:138::o;712:181:3:-;760:19;2827:42:9;825:58:3;;;:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;799:87;;;;;;;;:::i;:::-;;;;;;;;;;;;;791:95;;712:181;:::o;2190:182:5:-;2277:10;2251:4;2267:21;;;:9;:21;;;;;;;;;:26;;;;;;;;;;:32;;;2314:30;2251:4;;2267:26;;2314:30;;;;2296:3;1522:25:12;;1510:2;1495:18;;1376:177;2314:30:5;;;;;;;;-1:-1:-1;2361:4:5;2190:182;;;;:::o;2562:452::-;2663:14;;;2639:4;2663:14;;;;;;;;;;;:21;-1:-1:-1;2663:21:5;2655:30;;;;;;2700:17;;;2707:10;2700:17;;;;:68;;-1:-1:-1;2721:14:5;;;;;;;:9;:14;;;;;;;;2736:10;2721:26;;;;;;;;2751:17;2721:47;;2700:68;2696:188;;;2792:14;;;;;;;:9;:14;;;;;;;;2807:10;2792:26;;;;;;;;:33;-1:-1:-1;2792:33:5;2784:42;;;;;;2840:14;;;;;;;:9;:14;;;;;;;;2855:10;2840:26;;;;;;;:33;;2870:3;;2840:14;:33;;2870:3;;2840:33;:::i;:::-;;;;-1:-1:-1;;2696:188:5;2894:14;;;:9;:14;;;;;;;;;;:21;;2912:3;;2894:9;:21;;2912:3;;2894:21;:::i;:::-;;;;-1:-1:-1;;2925:14:5;;;:9;:14;;;;;;;;;;:21;;2943:3;;2925:9;:21;;2943:3;;2925:21;:::i;:::-;;;;;;;;2976:3;2962:23;;2971:3;2962:23;;;2981:3;2962:23;;;;1522:25:12;;1510:2;1495:18;;1376:177;2962:23:5;;;;;;;;-1:-1:-1;3003:4:5;2562:452;;;;;:::o;1803:223::-;1877:10;1867:9;:21;;;;;;;;;;;:28;-1:-1:-1;1867:28:5;1859:37;;;;;;1916:10;1906:9;:21;;;;;;;;;;:28;;1931:3;;1906:9;:28;;1931:3;;1906:28;:::i;:::-;;;;-1:-1:-1;;1944:33:5;;1952:10;;1944:33;;;;;1973:3;;1944:33;;;;1973:3;1952:10;1944:33;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1992:27:5;;1522:25:12;;;2003:10:5;;1992:27;;1510:2:12;1495:18;1992:27:5;;;;;;;1803:223;:::o;1024:182:3:-;1074:21;2827:42:9;1136:60:3;;;:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1117:82;;;;;;;;:::i;2404:126:5:-;2466:4;2489:34;2502:10;2514:3;2519;2489:12;:34::i;:::-;2482:41;2404:126;-1:-1:-1;;;2404:126:5:o;14:258:12:-;86:1;96:113;110:6;107:1;104:13;96:113;;;186:11;;;180:18;167:11;;;160:39;132:2;125:10;96:113;;;227:6;224:1;221:13;218:48;;;262:1;253:6;248:3;244:16;237:27;218:48;;14:258;;;:::o;277:442::-;426:2;415:9;408:21;389:4;458:6;452:13;501:6;496:2;485:9;481:18;474:34;517:66;576:6;571:2;560:9;556:18;551:2;543:6;539:15;517:66;:::i;:::-;635:2;623:15;640:66;619:88;604:104;;;;710:2;600:113;;277:442;-1:-1:-1;;277:442:12:o;724:196::-;792:20;;852:42;841:54;;831:65;;821:93;;910:1;907;900:12;821:93;724:196;;;:::o;925:254::-;993:6;1001;1054:2;1042:9;1033:7;1029:23;1025:32;1022:52;;;1070:1;1067;1060:12;1022:52;1093:29;1112:9;1093:29;:::i;:::-;1083:39;1169:2;1154:18;;;;1141:32;;-1:-1:-1;;;925:254:12:o;1558:328::-;1635:6;1643;1651;1704:2;1692:9;1683:7;1679:23;1675:32;1672:52;;;1720:1;1717;1710:12;1672:52;1743:29;1762:9;1743:29;:::i;:::-;1733:39;;1791:38;1825:2;1814:9;1810:18;1791:38;:::i;:::-;1781:48;;1876:2;1865:9;1861:18;1848:32;1838:42;;1558:328;;;;;:::o;1891:180::-;1950:6;2003:2;1991:9;1982:7;1978:23;1974:32;1971:52;;;2019:1;2016;2009:12;1971:52;-1:-1:-1;2042:23:12;;1891:180;-1:-1:-1;1891:180:12:o;2265:186::-;2324:6;2377:2;2365:9;2356:7;2352:23;2348:32;2345:52;;;2393:1;2390;2383:12;2345:52;2416:29;2435:9;2416:29;:::i;2456:260::-;2524:6;2532;2585:2;2573:9;2564:7;2560:23;2556:32;2553:52;;;2601:1;2598;2591:12;2553:52;2624:29;2643:9;2624:29;:::i;:::-;2614:39;;2672:38;2706:2;2695:9;2691:18;2672:38;:::i;:::-;2662:48;;2456:260;;;;;:::o;2721:184::-;2773:77;2770:1;2763:88;2870:4;2867:1;2860:15;2894:4;2891:1;2884:15;2910:128;2950:3;2981:1;2977:6;2974:1;2971:13;2968:39;;;2987:18;;:::i;:::-;-1:-1:-1;3023:9:12;;2910:128::o;3043:184::-;3095:77;3092:1;3085:88;3192:4;3189:1;3182:15;3216:4;3213:1;3206:15;3232:943;3312:6;3365:2;3353:9;3344:7;3340:23;3336:32;3333:52;;;3381:1;3378;3371:12;3333:52;3414:9;3408:16;3443:18;3484:2;3476:6;3473:14;3470:34;;;3500:1;3497;3490:12;3470:34;3538:6;3527:9;3523:22;3513:32;;3583:7;3576:4;3572:2;3568:13;3564:27;3554:55;;3605:1;3602;3595:12;3554:55;3634:2;3628:9;3656:2;3652;3649:10;3646:36;;;3662:18;;:::i;:::-;3796:2;3790:9;3858:4;3850:13;;3701:66;3846:22;;;3870:2;3842:31;3838:40;3826:53;;;3894:18;;;3914:22;;;3891:46;3888:72;;;3940:18;;:::i;:::-;3980:10;3976:2;3969:22;4015:2;4007:6;4000:18;4055:7;4050:2;4045;4041;4037:11;4033:20;4030:33;4027:53;;;4076:1;4073;4066:12;4027:53;4089:55;4141:2;4136;4128:6;4124:15;4119:2;4115;4111:11;4089:55;:::i;:::-;4163:6;3232:943;-1:-1:-1;;;;;;;3232:943:12:o;4180:414::-;4431:10;4426:3;4419:23;4401:3;4471:6;4465:13;4487:61;4541:6;4537:1;4532:3;4528:11;4521:4;4513:6;4509:17;4487:61;:::i;:::-;4568:16;;;;4586:1;4564:24;;4180:414;-1:-1:-1;;4180:414:12:o;4599:125::-;4639:4;4667:1;4664;4661:8;4658:34;;;4672:18;;:::i;:::-;-1:-1:-1;4709:9:12;;4599:125::o;4729:407::-;4980:3;4975;4968:16;4950:3;5013:6;5007:13;5029:61;5083:6;5079:1;5074:3;5070:11;5063:4;5055:6;5051:17;5029:61;:::i;:::-;5110:16;;;;5128:1;5106:24;;4729:407;-1:-1:-1;;4729:407:12:o

Swarm Source

none

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading

OVERVIEW

WETH is "wrapped ETH".

Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Chain Token Portfolio % Price Amount Value
BASE83.75%$2,020.6230,675.0306$466,102,987.21
BASE<0.01%$2,023.871.5015$3,038.8
BASE<0.01%$0.99987238.9553$38.95
BASE<0.01%$0.0011578,379.14$9.69
BASE<0.01%$0.00702201.7972$1.42
BASE<0.01%$10.7487$0.7494
BASE<0.01%$2,205.810.00020242$0.4465
BASE<0.01%$0.4283881$0.4283
BASE<0.01%$0.00728421$0.1529
BASE<0.01%$0.0001391,000$0.1387
OP13.73%$2,020.7637,825.6667$76,436,493.99
OP<0.01%$2,024.170.0998$202.11
OP<0.01%$0.99985965.9312$65.92
OP<0.01%$0.87932172.1404$63.43
OP<0.01%$0.87779127.6337$24.26
OP<0.01%$0.90436319.0258$17.21
OP<0.01%$115.4765$15.48
OP<0.01%$85,4240.0000998$8.53
SWELL1.21%$2,020.453,339.053$6,746,389.07
UNI
Ether (ETH)
0.81%$2,020.722,228.9778$4,504,133.75
WORLD0.25%$2,020.6686.7802$1,387,711.03
WORLD<0.01%$0.8783852.4869$46.1
WORLD<0.01%$2,024.010.014$28.35
WORLD<0.01%$85,4140.000002$0.1708
OPBNB0.22%$626.041,943.8537$1,216,927.78
OPBNB<0.01%$625.640.0036$2.25
ETH0.02%$2,021.7749.7108$100,503.62
ETH<0.01%$2,021.772.0291$4,102.38
ETH<0.01%$0.9998726.2973$6.3
ARB<0.01%$2,020.911.8279$3,693.96
ARB<0.01%$2,023.920.005$10.12
BSC<0.01%$625.911.5206$951.75
BSC<0.01%$2,020.490.0504$101.76
BSC<0.01%$110$10
BSC<0.01%$626.720.007505$4.7
BSC<0.01%$1.060.2$0.2112
ZKSYNC<0.01%$2,021.770.5052$1,021.35
TAIKO<0.01%$2,021.770.2227$450.18
LINEA<0.01%$2,021.770.1244$251.52
SCROLL<0.01%$2,021.770.0871$176.18
SONIC<0.01%$0.532305236.4946$125.89
AVAX<0.01%$19.194.2158$80.9
FRAXTAL<0.01%$2,017.450.014$28.24
POL<0.01%$0.21784557.1062$12.44
POL<0.01%$2,020.490.00266218$5.38
POL<0.01%$11.03$1.03
POL<0.01%$177.80.00328178$0.5835
ZKEVM<0.01%$2,021.770.00879758$17.79
FTM<0.01%$0.53270.03$0.015992
CELO<0.01%$0.3612640.0201$0.007257
GNO<0.01%$10.0001$0.0001
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.