{
  "contractName": "OTGTestToken",
  "compiler": "0.8.24+commit.e11b9ed9.Emscripten.clang",
  "testOnly": true,
  "standardInput": {
    "language": "Solidity",
    "sources": {
      "OTGTestToken.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.24;\n\ncontract OTGTestToken {\n    string public constant name = \"Own The Grid Test Token\";\n    string public constant symbol = \"tOTG\";\n    uint8 public constant decimals = 18;\n    uint256 public constant FAUCET_AMOUNT = 1_000_000 ether;\n    uint256 public constant FAUCET_COOLDOWN = 12 hours;\n\n    address public owner;\n    uint256 public totalSupply;\n\n    mapping(address => uint256) public balanceOf;\n    mapping(address => mapping(address => uint256)) public allowance;\n    mapping(address => uint256) public lastFaucetClaim;\n\n    event Transfer(address indexed from, address indexed to, uint256 value);\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    modifier onlyOwner() {\n        require(msg.sender == owner, \"not owner\");\n        _;\n    }\n\n    constructor() {\n        owner = msg.sender;\n        _mint(msg.sender, 100_000_000 ether);\n    }\n\n    function faucet() external {\n        require(block.timestamp >= lastFaucetClaim[msg.sender] + FAUCET_COOLDOWN, \"cooldown\");\n        lastFaucetClaim[msg.sender] = block.timestamp;\n        _mint(msg.sender, FAUCET_AMOUNT);\n    }\n\n    function mint(address to, uint256 value) external onlyOwner {\n        _mint(to, value);\n    }\n\n    function transfer(address to, uint256 value) external returns (bool) {\n        _transfer(msg.sender, to, value);\n        return true;\n    }\n\n    function approve(address spender, uint256 value) external returns (bool) {\n        allowance[msg.sender][spender] = value;\n        emit Approval(msg.sender, spender, value);\n        return true;\n    }\n\n    function transferFrom(address from, address to, uint256 value) external returns (bool) {\n        uint256 allowed = allowance[from][msg.sender];\n        require(allowed >= value, \"allowance\");\n        if (allowed != type(uint256).max) {\n            allowance[from][msg.sender] = allowed - value;\n        }\n        _transfer(from, to, value);\n        return true;\n    }\n\n    function _transfer(address from, address to, uint256 value) internal {\n        require(to != address(0), \"bad recipient\");\n        uint256 balance = balanceOf[from];\n        require(balance >= value, \"balance\");\n        balanceOf[from] = balance - value;\n        balanceOf[to] += value;\n        emit Transfer(from, to, value);\n    }\n\n    function _mint(address to, uint256 value) internal {\n        require(to != address(0), \"bad recipient\");\n        totalSupply += value;\n        balanceOf[to] += value;\n        emit Transfer(address(0), to, value);\n    }\n}\n"
      },
      "OwnTheGridBoardV5.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.24;\n\ninterface IERC20BoardV5 {\n    function transfer(address to, uint256 value) external returns (bool);\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n    function balanceOf(address account) external view returns (uint256);\n}\n\ncontract OwnTheGridBoardV5 {\n    uint16 public constant SLOT_COUNT = 400;\n    uint16 public constant MAX_BATCH = 40;\n    uint256 public constant SLOT_LOCK = 250_000 ether;\n    uint256 public constant MAX_BOARD_LOCK = 100_000_000 ether;\n    uint64 public constant DEFAULT_TERM = 30 days;\n\n    struct TileData {\n        string name;\n        string url;\n        string message;\n        uint24 backgroundColor;\n        uint24 accentColor;\n        uint24 textColor;\n    }\n\n    struct Slot {\n        address owner;\n        uint72 colors;\n        bool hidden;\n        uint16 priceRank;\n        uint128 lockedAmount;\n        uint64 expiresAt;\n        uint64 reservedAtBlock;\n        uint64 updatedAtBlock;\n        string name;\n        string url;\n        string message;\n    }\n\n    IERC20BoardV5 public immutable token;\n    address public owner;\n    address public moderator;\n    uint16 public occupiedCount;\n    uint256 public totalLocked;\n    mapping(uint16 => Slot) private slotRecords;\n    mapping(address => uint256) public pendingWithdrawals;\n    bool private entered;\n\n    event SlotReserved(uint16 indexed slotId, address indexed account, uint256 lockedAmount, uint64 expiresAt);\n    event SlotBatchReserved(address indexed account, uint16 count, uint256 totalLockedAmount);\n    event SlotMetadataUpdated(uint16 indexed slotId, address indexed account);\n    event SlotReleased(uint16 indexed slotId, address indexed account, uint256 unlockedAmount);\n    event SlotBatchReleased(address indexed account, uint16 count, uint256 unlockedAmount);\n    event SlotHidden(uint16 indexed slotId, bool hidden, bytes32 reasonHash);\n    event ModeratorUpdated(address indexed moderator);\n    event OwnershipTransferred(address indexed previousOwner, address indexed nextOwner);\n\n    modifier onlyOwner() {\n        require(msg.sender == owner, \"not owner\");\n        _;\n    }\n\n    modifier nonReentrant() {\n        require(!entered, \"reentrant\");\n        entered = true;\n        _;\n        entered = false;\n    }\n\n    constructor(address acceptedToken, address initialModerator) {\n        require(acceptedToken.code.length > 0, \"token required\");\n        token = IERC20BoardV5(acceptedToken);\n        owner = msg.sender;\n        moderator = initialModerator == address(0) ? msg.sender : initialModerator;\n        emit OwnershipTransferred(address(0), msg.sender);\n        emit ModeratorUpdated(moderator);\n    }\n\n    function version() external pure returns (uint256) { return 5; }\n\n    function getSlot(uint16 slotId) external view returns (Slot memory) {\n        require(slotId < SLOT_COUNT, \"bad slot\");\n        return slotRecords[slotId];\n    }\n\n    function getSlots(uint16 start, uint16 count) external view returns (Slot[] memory result) {\n        require(count > 0 && count <= MAX_BATCH && uint256(start) + count <= SLOT_COUNT, \"bad page\");\n        result = new Slot[](count);\n        for (uint16 i = 0; i < count; i++) result[i] = slotRecords[start + i];\n    }\n\n    // Kept for backwards-compatible integrations; every valid slot has the same price in V5.\n    function requiredLockForRank(uint256 rank) public pure returns (uint256) {\n        require(rank > 0 && rank <= SLOT_COUNT, \"bad rank\");\n        return SLOT_LOCK;\n    }\n\n    function nextRequiredLock() external view returns (uint256) {\n        if (occupiedCount < SLOT_COUNT) return SLOT_LOCK;\n        for (uint16 slotId = 0; slotId < SLOT_COUNT; slotId++) {\n            if (block.timestamp >= slotRecords[slotId].expiresAt) return SLOT_LOCK;\n        }\n        return 0;\n    }\n\n    function isAvailable(uint16 slotId) public view returns (bool) {\n        require(slotId < SLOT_COUNT, \"bad slot\");\n        return slotRecords[slotId].owner == address(0) || block.timestamp >= slotRecords[slotId].expiresAt;\n    }\n\n    function quoteReserve(uint16[] calldata slotIds) external view returns (uint256[] memory amounts, uint256 totalAmount) {\n        _validateSlotIds(slotIds);\n        amounts = new uint256[](slotIds.length);\n        for (uint256 i = 0; i < slotIds.length; i++) {\n            require(isAvailable(slotIds[i]), \"slot taken\");\n            amounts[i] = SLOT_LOCK;\n        }\n        totalAmount = SLOT_LOCK * slotIds.length;\n    }\n\n    function reserve(uint16 slotId, TileData calldata data, uint256 maxAmount) external nonReentrant {\n        require(slotId < SLOT_COUNT, \"bad slot\");\n        _validateData(data);\n        _clearExpired(slotId);\n        require(slotRecords[slotId].owner == address(0), \"slot taken\");\n        require(SLOT_LOCK <= maxAmount, \"price changed\");\n        _checkCap(SLOT_LOCK);\n        _collect(SLOT_LOCK);\n        _writeSlot(slotId, data);\n        occupiedCount++;\n        totalLocked += SLOT_LOCK;\n    }\n\n    function reserveBatch(uint16[] calldata slotIds, TileData[] calldata data, uint256 maxAmount) external nonReentrant {\n        _validateSlotIds(slotIds);\n        require(data.length == slotIds.length, \"length mismatch\");\n        for (uint256 i = 0; i < slotIds.length; i++) {\n            _validateData(data[i]);\n            _clearExpired(slotIds[i]);\n            require(slotRecords[slotIds[i]].owner == address(0), \"slot taken\");\n        }\n        uint256 totalAmount = SLOT_LOCK * slotIds.length;\n        require(totalAmount <= maxAmount, \"price changed\");\n        _checkCap(totalAmount);\n        _collect(totalAmount);\n        for (uint256 i = 0; i < slotIds.length; i++) _writeSlot(slotIds[i], data[i]);\n        occupiedCount += uint16(slotIds.length);\n        totalLocked += totalAmount;\n        emit SlotBatchReserved(msg.sender, uint16(slotIds.length), totalAmount);\n    }\n\n    function updateMetadata(uint16 slotId, TileData calldata data) external {\n        require(slotId < SLOT_COUNT, \"bad slot\");\n        _validateData(data);\n        Slot storage slot = slotRecords[slotId];\n        require(slot.owner == msg.sender, \"not slot owner\");\n        require(block.timestamp < slot.expiresAt, \"expired\");\n        _writeData(slot, data);\n        slot.updatedAtBlock = _chainBlockNumber();\n        emit SlotMetadataUpdated(slotId, msg.sender);\n    }\n\n    function release(uint16 slotId) external nonReentrant {\n        require(slotId < SLOT_COUNT, \"bad slot\");\n        Slot memory slot = slotRecords[slotId];\n        require(slot.owner == msg.sender, \"not slot owner\");\n        _deleteSlot(slotId, slot.owner, slot.lockedAmount);\n        require(token.transfer(slot.owner, slot.lockedAmount), \"transfer failed\");\n    }\n\n    function releaseBatch(uint16[] calldata slotIds) external nonReentrant {\n        _validateSlotIds(slotIds);\n        uint256 amount;\n        for (uint256 i = 0; i < slotIds.length; i++) {\n            Slot storage slot = slotRecords[slotIds[i]];\n            require(slot.owner == msg.sender, \"not slot owner\");\n            uint256 deposit = slot.lockedAmount;\n            amount += deposit;\n            _deleteSlot(slotIds[i], msg.sender, deposit);\n        }\n        require(token.transfer(msg.sender, amount), \"transfer failed\");\n        emit SlotBatchReleased(msg.sender, uint16(slotIds.length), amount);\n    }\n\n    function withdraw() external nonReentrant {\n        uint256 amount = pendingWithdrawals[msg.sender];\n        require(amount > 0, \"nothing to withdraw\");\n        pendingWithdrawals[msg.sender] = 0;\n        require(token.transfer(msg.sender, amount), \"transfer failed\");\n    }\n\n    function clearExpiredBatch(uint16[] calldata slotIds) external nonReentrant {\n        _validateSlotIds(slotIds);\n        for (uint256 i = 0; i < slotIds.length; i++) _clearExpired(slotIds[i]);\n    }\n\n    function hideSlot(uint16 slotId, bool hidden, bytes32 reasonHash) external {\n        require(msg.sender == owner || msg.sender == moderator, \"not moderator\");\n        require(slotId < SLOT_COUNT && slotRecords[slotId].owner != address(0), \"empty slot\");\n        slotRecords[slotId].hidden = hidden;\n        emit SlotHidden(slotId, hidden, reasonHash);\n    }\n\n    function setModerator(address nextModerator) external onlyOwner {\n        moderator = nextModerator == address(0) ? owner : nextModerator;\n        emit ModeratorUpdated(moderator);\n    }\n\n    function transferOwnership(address nextOwner) external onlyOwner {\n        require(nextOwner != address(0), \"owner required\");\n        emit OwnershipTransferred(owner, nextOwner);\n        owner = nextOwner;\n    }\n\n    function _validateSlotIds(uint16[] calldata slotIds) private pure {\n        require(slotIds.length > 0 && slotIds.length <= MAX_BATCH, \"bad batch\");\n        for (uint256 i = 0; i < slotIds.length; i++) {\n            require(slotIds[i] < SLOT_COUNT, \"bad slot\");\n            for (uint256 j = 0; j < i; j++) require(slotIds[j] != slotIds[i], \"duplicate slot\");\n        }\n    }\n\n    function _validateData(TileData calldata data) private pure {\n        bytes calldata name = bytes(data.name);\n        require(name.length > 0 && name.length <= 96, \"bad name\");\n        bool visible;\n        for (uint256 i = 0; i < name.length; i++) if (uint8(name[i]) > 32) visible = true;\n        require(visible, \"bad name\");\n        bytes calldata url = bytes(data.url);\n        require(url.length > 0 && url.length <= 256, \"bad url\");\n        bool http = url.length >= 7 && url[0] == \"h\" && url[1] == \"t\" && url[2] == \"t\" && url[3] == \"p\" &&\n            ((url[4] == \":\" && url[5] == \"/\" && url[6] == \"/\") ||\n            (url.length >= 8 && url[4] == \"s\" && url[5] == \":\" && url[6] == \"/\" && url[7] == \"/\"));\n        require(http, \"bad url\");\n        require(bytes(data.message).length <= 336, \"message too long\");\n    }\n\n    function _checkCap(uint256 amount) private view {\n        require(totalLocked + amount <= MAX_BOARD_LOCK, \"board cap\");\n    }\n\n    function _chainBlockNumber() private view returns (uint64) {\n        (bool ok, bytes memory result) = address(0x64).staticcall{gas: 10000}(abi.encodeWithSignature(\"arbBlockNumber()\"));\n        return uint64(ok && result.length == 32 ? abi.decode(result, (uint256)) : block.number);\n    }\n\n    function _collect(uint256 amount) private {\n        uint256 beforeBalance = token.balanceOf(address(this));\n        require(token.transferFrom(msg.sender, address(this), amount), \"transfer failed\");\n        require(token.balanceOf(address(this)) == beforeBalance + amount, \"unsupported transfer fee\");\n    }\n\n    function _writeSlot(uint16 slotId, TileData calldata data) private {\n        Slot storage slot = slotRecords[slotId];\n        slot.owner = msg.sender;\n        slot.hidden = false;\n        slot.priceRank = 0;\n        slot.lockedAmount = uint128(SLOT_LOCK);\n        slot.expiresAt = uint64(block.timestamp + DEFAULT_TERM);\n        slot.reservedAtBlock = _chainBlockNumber();\n        slot.updatedAtBlock = _chainBlockNumber();\n        _writeData(slot, data);\n        emit SlotReserved(slotId, msg.sender, SLOT_LOCK, slot.expiresAt);\n    }\n\n    function _writeData(Slot storage slot, TileData calldata data) private {\n        slot.name = data.name;\n        slot.url = data.url;\n        slot.message = data.message;\n        slot.colors = uint72(data.backgroundColor) << 48 | uint72(data.accentColor) << 24 | uint72(data.textColor);\n    }\n\n    function _clearExpired(uint16 slotId) private {\n        Slot storage slot = slotRecords[slotId];\n        if (slot.owner != address(0) && block.timestamp >= slot.expiresAt) {\n            address account = slot.owner;\n            uint256 amount = slot.lockedAmount;\n            pendingWithdrawals[account] += amount;\n            _deleteSlot(slotId, account, amount);\n        }\n    }\n\n    function _deleteSlot(uint16 slotId, address account, uint256 amount) private {\n        delete slotRecords[slotId];\n        occupiedCount--;\n        totalLocked -= amount;\n        emit SlotReleased(slotId, account, amount);\n    }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "evmVersion": "paris",
      "outputSelection": {
        "*": {
          "*": [
            "abi",
            "evm.bytecode.object",
            "evm.deployedBytecode.object",
            "evm.deployedBytecode.immutableReferences"
          ]
        }
      }
    }
  },
  "abi": [
    {
      "inputs": [],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "owner",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "spender",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "value",
          "type": "uint256"
        }
      ],
      "name": "Approval",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "from",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "to",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "value",
          "type": "uint256"
        }
      ],
      "name": "Transfer",
      "type": "event"
    },
    {
      "inputs": [],
      "name": "FAUCET_AMOUNT",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "FAUCET_COOLDOWN",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "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": "spender",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "value",
          "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": "faucet",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "name": "lastFaucetClaim",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "to",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "value",
          "type": "uint256"
        }
      ],
      "name": "mint",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "name",
      "outputs": [
        {
          "internalType": "string",
          "name": "",
          "type": "string"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "owner",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "symbol",
      "outputs": [
        {
          "internalType": "string",
          "name": "",
          "type": "string"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "totalSupply",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "to",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "value",
          "type": "uint256"
        }
      ],
      "name": "transfer",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "from",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "to",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "value",
          "type": "uint256"
        }
      ],
      "name": "transferFrom",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    }
  ],
  "bytecode": "0x608060405234801561001057600080fd5b50600080546001600160a01b0319163390811790915561003b906a52b7d2dcc80cd2e4000000610040565b61013a565b6001600160a01b03821661008a5760405162461bcd60e51b815260206004820152600d60248201526c189859081c9958da5c1a595b9d609a1b604482015260640160405180910390fd5b806001600082825461009c9190610113565b90915550506001600160a01b038216600090815260026020526040812080548392906100c9908490610113565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b8082018082111561013457634e487b7160e01b600052601160045260246000fd5b92915050565b610859806101496000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c8063766976401161009757806395d89b411161006657806395d89b411461024d578063a9059cbb14610270578063dd62ed3e14610283578063de5f72fd146102ae57600080fd5b806376697640146101e85780637d1d5d19146101f95780638a877205146102025780638da5cb5b1461022257600080fd5b806323b872dd116100d357806323b872dd14610186578063313ce5671461019957806340c10f19146101b357806370a08231146101c857600080fd5b806306fdde03146100fa578063095ea7b31461014c57806318160ddd1461016f575b600080fd5b6101366040518060400160405280601781526020017f4f776e205468652047726964205465737420546f6b656e00000000000000000081525081565b60405161014391906106c1565b60405180910390f35b61015f61015a36600461072c565b6102b6565b6040519015158152602001610143565b61017860015481565b604051908152602001610143565b61015f610194366004610756565b610323565b6101a1601281565b60405160ff9091168152602001610143565b6101c66101c136600461072c565b6103d6565b005b6101786101d6366004610792565b60026020526000908152604090205481565b61017869d3c21bcecceda100000081565b61017861a8c081565b610178610210366004610792565b60046020526000908152604090205481565b600054610235906001600160a01b031681565b6040516001600160a01b039091168152602001610143565b61013660405180604001604052806004815260200163744f544760e01b81525081565b61015f61027e36600461072c565b61042a565b6101786102913660046107b4565b600360209081526000928352604080842090915290825290205481565b6101c6610440565b3360008181526003602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906103119086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383166000908152600360209081526040808320338452909152812054828110156103885760405162461bcd60e51b8152602060048201526009602482015268616c6c6f77616e636560b81b60448201526064015b60405180910390fd5b60001981146103c05761039b83826107fd565b6001600160a01b03861660009081526003602090815260408083203384529091529020555b6103cb8585856104bf565b506001949350505050565b6000546001600160a01b0316331461041c5760405162461bcd60e51b81526020600482015260096024820152683737ba1037bbb732b960b91b604482015260640161037f565b61042682826105f2565b5050565b60006104373384846104bf565b50600192915050565b3360009081526004602052604090205461045d9061a8c090610810565b4210156104975760405162461bcd60e51b815260206004820152600860248201526731b7b7b63237bbb760c11b604482015260640161037f565b3360008181526004602052604090204290556104bd9069d3c21bcecceda10000006105f2565b565b6001600160a01b0382166105055760405162461bcd60e51b815260206004820152600d60248201526c189859081c9958da5c1a595b9d609a1b604482015260640161037f565b6001600160a01b038316600090815260026020526040902054818110156105585760405162461bcd60e51b815260206004820152600760248201526662616c616e636560c81b604482015260640161037f565b61056282826107fd565b6001600160a01b038086166000908152600260205260408082209390935590851681529081208054849290610598908490610810565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516105e491815260200190565b60405180910390a350505050565b6001600160a01b0382166106385760405162461bcd60e51b815260206004820152600d60248201526c189859081c9958da5c1a595b9d609a1b604482015260640161037f565b806001600082825461064a9190610810565b90915550506001600160a01b03821660009081526002602052604081208054839290610677908490610810565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60006020808352835180602085015260005b818110156106ef578581018301518582016040015282016106d3565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b038116811461072757600080fd5b919050565b6000806040838503121561073f57600080fd5b61074883610710565b946020939093013593505050565b60008060006060848603121561076b57600080fd5b61077484610710565b925061078260208501610710565b9150604084013590509250925092565b6000602082840312156107a457600080fd5b6107ad82610710565b9392505050565b600080604083850312156107c757600080fd5b6107d083610710565b91506107de60208401610710565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561031d5761031d6107e7565b8082018082111561031d5761031d6107e756fea26469706673582212203b5fda7a006064d40ead0493f1e75cd2a5b8804b3d3369cf2de006f87070a7cb64736f6c63430008180033",
  "runtimeBytecode": "0x608060405234801561001057600080fd5b50600436106100f55760003560e01c8063766976401161009757806395d89b411161006657806395d89b411461024d578063a9059cbb14610270578063dd62ed3e14610283578063de5f72fd146102ae57600080fd5b806376697640146101e85780637d1d5d19146101f95780638a877205146102025780638da5cb5b1461022257600080fd5b806323b872dd116100d357806323b872dd14610186578063313ce5671461019957806340c10f19146101b357806370a08231146101c857600080fd5b806306fdde03146100fa578063095ea7b31461014c57806318160ddd1461016f575b600080fd5b6101366040518060400160405280601781526020017f4f776e205468652047726964205465737420546f6b656e00000000000000000081525081565b60405161014391906106c1565b60405180910390f35b61015f61015a36600461072c565b6102b6565b6040519015158152602001610143565b61017860015481565b604051908152602001610143565b61015f610194366004610756565b610323565b6101a1601281565b60405160ff9091168152602001610143565b6101c66101c136600461072c565b6103d6565b005b6101786101d6366004610792565b60026020526000908152604090205481565b61017869d3c21bcecceda100000081565b61017861a8c081565b610178610210366004610792565b60046020526000908152604090205481565b600054610235906001600160a01b031681565b6040516001600160a01b039091168152602001610143565b61013660405180604001604052806004815260200163744f544760e01b81525081565b61015f61027e36600461072c565b61042a565b6101786102913660046107b4565b600360209081526000928352604080842090915290825290205481565b6101c6610440565b3360008181526003602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906103119086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383166000908152600360209081526040808320338452909152812054828110156103885760405162461bcd60e51b8152602060048201526009602482015268616c6c6f77616e636560b81b60448201526064015b60405180910390fd5b60001981146103c05761039b83826107fd565b6001600160a01b03861660009081526003602090815260408083203384529091529020555b6103cb8585856104bf565b506001949350505050565b6000546001600160a01b0316331461041c5760405162461bcd60e51b81526020600482015260096024820152683737ba1037bbb732b960b91b604482015260640161037f565b61042682826105f2565b5050565b60006104373384846104bf565b50600192915050565b3360009081526004602052604090205461045d9061a8c090610810565b4210156104975760405162461bcd60e51b815260206004820152600860248201526731b7b7b63237bbb760c11b604482015260640161037f565b3360008181526004602052604090204290556104bd9069d3c21bcecceda10000006105f2565b565b6001600160a01b0382166105055760405162461bcd60e51b815260206004820152600d60248201526c189859081c9958da5c1a595b9d609a1b604482015260640161037f565b6001600160a01b038316600090815260026020526040902054818110156105585760405162461bcd60e51b815260206004820152600760248201526662616c616e636560c81b604482015260640161037f565b61056282826107fd565b6001600160a01b038086166000908152600260205260408082209390935590851681529081208054849290610598908490610810565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516105e491815260200190565b60405180910390a350505050565b6001600160a01b0382166106385760405162461bcd60e51b815260206004820152600d60248201526c189859081c9958da5c1a595b9d609a1b604482015260640161037f565b806001600082825461064a9190610810565b90915550506001600160a01b03821660009081526002602052604081208054839290610677908490610810565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60006020808352835180602085015260005b818110156106ef578581018301518582016040015282016106d3565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b038116811461072757600080fd5b919050565b6000806040838503121561073f57600080fd5b61074883610710565b946020939093013593505050565b60008060006060848603121561076b57600080fd5b61077484610710565b925061078260208501610710565b9150604084013590509250925092565b6000602082840312156107a457600080fd5b6107ad82610710565b9392505050565b600080604083850312156107c757600080fd5b6107d083610710565b91506107de60208401610710565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561031d5761031d6107e7565b8082018082111561031d5761031d6107e756fea26469706673582212203b5fda7a006064d40ead0493f1e75cd2a5b8804b3d3369cf2de006f87070a7cb64736f6c63430008180033",
  "immutableReferences": {},
  "selectors": {
    "FAUCET_AMOUNT": "0x76697640",
    "FAUCET_COOLDOWN": "0x7d1d5d19",
    "allowance": "0xdd62ed3e",
    "approve": "0x095ea7b3",
    "balanceOf": "0x70a08231",
    "decimals": "0x313ce567",
    "faucet": "0xde5f72fd",
    "lastFaucetClaim": "0x8a877205",
    "mint": "0x40c10f19",
    "name": "0x06fdde03",
    "owner": "0x8da5cb5b",
    "symbol": "0x95d89b41",
    "totalSupply": "0x18160ddd",
    "transfer": "0xa9059cbb",
    "transferFrom": "0x23b872dd"
  },
  "eventTopics": {
    "Approval": "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925",
    "Transfer": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
  }
}
