ETH Price: $4,002.54 (-2.26%)
Gas: 0.1 Gwei

Contract

0x686E7d01C7BFCB563721333A007699F154C04eb4
 

Overview

ETH Balance

0.15 ETH

Eth Value

$600.38 (@ $4,002.54/ETH)

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Resolve Proposal236791172025-10-28 23:15:234 hrs ago1761693323IN
0x686E7d01...154C04eb4
0 ETH0.000008180.08439423
Submit Proposal236791152025-10-28 23:14:594 hrs ago1761693299IN
0x686E7d01...154C04eb4
0.005 ETH0.000008150.09145808
Resolve Proposal236773402025-10-28 17:15:3510 hrs ago1761671735IN
0x686E7d01...154C04eb4
0 ETH0.000025060.21967778
Submit Proposal236773372025-10-28 17:14:5910 hrs ago1761671699IN
0x686E7d01...154C04eb4
0.005 ETH0.000018930.21227834
Claim Credit236755662025-10-28 11:16:1116 hrs ago1761650171IN
0x686E7d01...154C04eb4
0 ETH0.00000560.17780564
Resolve Proposal236755642025-10-28 11:15:4716 hrs ago1761650147IN
0x686E7d01...154C04eb4
0 ETH0.00001680.17323696
Submit Proposal236755582025-10-28 11:14:3516 hrs ago1761650075IN
0x686E7d01...154C04eb4
0.005 ETH0.000014710.16495315
Submit Proposal236737732025-10-28 5:14:3522 hrs ago1761628475IN
0x686E7d01...154C04eb4
0.005 ETH0.000008260.09273357
Resolve Proposal236737452025-10-28 5:08:5922 hrs ago1761628139IN
0x686E7d01...154C04eb4
0 ETH0.00000850.0877201
Resolve Proposal236719962025-10-27 23:16:4728 hrs ago1761607007IN
0x686E7d01...154C04eb4
0 ETH0.000011330.09935702
Submit Proposal236719842025-10-27 23:14:2328 hrs ago1761606863IN
0x686E7d01...154C04eb4
0.005 ETH0.000007310.0819756
Claim Credit236702142025-10-27 17:17:2334 hrs ago1761585443IN
0x686E7d01...154C04eb4
0 ETH0.000015130.47959889
Resolve Proposal236702082025-10-27 17:16:1134 hrs ago1761585371IN
0x686E7d01...154C04eb4
0 ETH0.000044620.46001824
Submit Proposal236702002025-10-27 17:14:3534 hrs ago1761585275IN
0x686E7d01...154C04eb4
0.005 ETH0.000043110.48342702
Resolve Proposal236684332025-10-27 11:18:1140 hrs ago1761563891IN
0x686E7d01...154C04eb4
0 ETH0.000009390.09682766
Submit Proposal236684202025-10-27 11:15:3540 hrs ago1761563735IN
0x686E7d01...154C04eb4
0.005 ETH0.000008570.0961094
Resolve Proposal236665982025-10-27 5:08:3546 hrs ago1761541715IN
0x686E7d01...154C04eb4
0 ETH0.000012350.10827223
Submit Proposal236665952025-10-27 5:07:5946 hrs ago1761541679IN
0x686E7d01...154C04eb4
0.005 ETH0.000009160.10275466
Submit Proposal236648582025-10-26 23:17:112 days ago1761520631IN
0x686E7d01...154C04eb4
0.005 ETH0.000012670.14218245
Claim Credit236648532025-10-26 23:16:112 days ago1761520571IN
0x686E7d01...154C04eb4
0 ETH0.00000390.12377154
Resolve Proposal236648502025-10-26 23:15:352 days ago1761520535IN
0x686E7d01...154C04eb4
0 ETH0.000010670.11000803
Resolve Proposal236630612025-10-26 17:15:232 days ago1761498923IN
0x686E7d01...154C04eb4
0 ETH0.000012190.12570438
Submit Proposal236630562025-10-26 17:14:232 days ago1761498863IN
0x686E7d01...154C04eb4
0.005 ETH0.000010290.11540805
Resolve Proposal236612672025-10-26 11:15:112 days ago1761477311IN
0x686E7d01...154C04eb4
0 ETH0.000014310.12545793
Submit Proposal236612662025-10-26 11:14:592 days ago1761477299IN
0x686E7d01...154C04eb4
0.005 ETH0.00001020.11441074
View all transactions

Latest 25 internal transactions

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer236755662025-10-28 11:16:1116 hrs ago1761650171
0x686E7d01...154C04eb4
0.015 ETH
Transfer236702142025-10-27 17:17:2334 hrs ago1761585443
0x686E7d01...154C04eb4
0.015 ETH
Transfer236648532025-10-26 23:16:112 days ago1761520571
0x686E7d01...154C04eb4
0.015 ETH
Transfer236594862025-10-26 5:15:592 days ago1761455759
0x686E7d01...154C04eb4
0.015 ETH
Transfer236541112025-10-25 11:15:353 days ago1761390935
0x686E7d01...154C04eb4
0.015 ETH
Transfer236487502025-10-24 17:15:354 days ago1761326135
0x686E7d01...154C04eb4
0.015 ETH
Transfer236434032025-10-23 23:16:355 days ago1761261395
0x686E7d01...154C04eb4
0.015 ETH
Transfer236380612025-10-23 5:15:355 days ago1761196535
0x686E7d01...154C04eb4
0.015 ETH
Transfer236327072025-10-22 11:15:236 days ago1761131723
0x686E7d01...154C04eb4
0.015 ETH
Transfer236273592025-10-21 17:16:117 days ago1761066971
0x686E7d01...154C04eb4
0.015 ETH
Transfer236220332025-10-20 23:18:478 days ago1761002327
0x686E7d01...154C04eb4
0.015 ETH
Transfer236166752025-10-20 5:15:238 days ago1760937323
0x686E7d01...154C04eb4
0.015 ETH
Transfer236113282025-10-19 11:16:359 days ago1760872595
0x686E7d01...154C04eb4
0.015 ETH
Transfer236059592025-10-18 17:15:5910 days ago1760807759
0x686E7d01...154C04eb4
0.015 ETH
Transfer236006112025-10-17 23:17:5911 days ago1760743079
0x686E7d01...154C04eb4
0.015 ETH
Transfer235952352025-10-17 5:16:2311 days ago1760678183
0x686E7d01...154C04eb4
0.015 ETH
Transfer235898802025-10-16 11:18:5912 days ago1760613539
0x686E7d01...154C04eb4
0.015 ETH
Transfer235845152025-10-15 17:15:5913 days ago1760548559
0x686E7d01...154C04eb4
0.015 ETH
Transfer235791712025-10-14 23:19:1114 days ago1760483951
0x686E7d01...154C04eb4
0.015 ETH
Transfer235737972025-10-14 5:16:3514 days ago1760418995
0x686E7d01...154C04eb4
0.015 ETH
Transfer235684322025-10-13 11:15:5915 days ago1760354159
0x686E7d01...154C04eb4
0.015 ETH
Transfer235630862025-10-12 17:18:1116 days ago1760289491
0x686E7d01...154C04eb4
0.015 ETH
Transfer235577022025-10-11 23:15:5917 days ago1760224559
0x686E7d01...154C04eb4
0.015 ETH
Transfer235523322025-10-11 5:15:3517 days ago1760159735
0x686E7d01...154C04eb4
0.015 ETH
Transfer235469692025-10-10 11:15:2318 days ago1760094923
0x686E7d01...154C04eb4
0.015 ETH
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x8EdadcEA...eb9d2aB29
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
Rollup

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 200 runs

Other Settings:
cancun EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 6 : Rollup.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import { ISP1Verifier } from "@sp1-contracts/src/ISP1Verifier.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import { SafeCastLib } from "solady/src/utils/SafeCastLib.sol";

/// @title Rollup
/// @notice Dual-track ZK fault validity proof system
/// @dev Supports two tracks:
/// @dev 1. Fault proofs: Optimistic proposals that can be challenged (low cost)
/// @dev 2. Validity proofs: Direct ZK proofs that bypass challenges (instant finality)
/// @dev 
/// @dev Key features:
/// @dev - Single-round dispute resolution.
/// @dev - Bulk invalidation: Validity proofs invalidate all conflicting fault proofs
/// @dev - Censorship resistance: Fallback window allows anyone to propose after timeout
contract Rollup is Ownable, ReentrancyGuard {
    using SafeCastLib for uint256;
    
    /*//////////////////////////////////////////////////////////////
                               CONSTANTS
    //////////////////////////////////////////////////////////////*/

    uint256 public immutable MAX_CHALLENGE_SECS;
    uint256 public immutable MAX_PROVE_SECS;
    uint256 public immutable CHALLENGER_BOND;
    uint256 public immutable PROPOSER_BOND;
    uint256 public immutable FALLBACK_TIMEOUT_SECS;
    uint256 public immutable PROPOSAL_INTERVAL;
    uint256 public immutable L2_START_TIMESTAMP;
    uint256 public immutable L2_BLOCK_TIME;

    ISP1Verifier public immutable VERIFIER;
    bytes32 public immutable ROLLUP_CONFIG_HASH;
    bytes32 public immutable AGG_VKEY;
    bytes32 public immutable RANGE_VKEY_COMMITMENT;

    string public constant version = "1.0.0";

    /*//////////////////////////////////////////////////////////////
                               ENUMS
    //////////////////////////////////////////////////////////////*/

    enum ResolutionStatus { IN_PROGRESS, DEFENDER_WINS, CHALLENGER_WINS }

    enum ProposalStatus {
        Unchallenged,
        Challenged,
        UnchallengedAndProven,
        ChallengedAndProven,
        Resolved
    }
    
    /*//////////////////////////////////////////////////////////////
                               EVENTS
    //////////////////////////////////////////////////////////////*/

    event ProposalSubmitted(
        uint256 indexed proposalId,
        uint256 indexed parentId,
        address indexed proposer,
        bytes32 root,
        uint256 l2BlockNumber);
    
    event ProposalChallenged(uint256 indexed proposalId, address indexed challenger);
    event ProposalProven(uint256 indexed proposalId, address indexed prover);
    event ProposalResolved(uint256 indexed proposalId, ResolutionStatus status);
    event AnchorUpdated(uint256 indexed proposalId, bytes32 root, uint256 l2BlockNumber);
    event ProposalClosed(uint256 indexed proposalId);
    event ProposerPermissionUpdated(address indexed proposer, bool allowed);
    event BlockProven(uint256 indexed l2BlockNumber, bytes32 root, address indexed prover);
    event L1BlockHashCheckpointed(uint256 indexed l1BlockNumber, bytes32 blockHash);

    /*//////////////////////////////////////////////////////////////
                               ERRORS
    //////////////////////////////////////////////////////////////*/

    error BadAuth();
    error IncorrectBondAmount();
    error AlreadyChallenged();
    error GameNotOver();
    error GameOver();
    error AlreadyResolved();
    error NoCredit();
    error TransferFailed();
    error InvalidParentGame();
    error BadCadence();
    error ParentGameNotResolved();
    error ProposingBackwards();
    error ProposingFutureBlock();
    error BlockAlreadyProven();
    error L1BlockHashNotAvailable();
    error L1BlockHashNotCheckpointed();
    error NoCanonicalProposal();
    error InvalidL2BlockNumber();

    /*//////////////////////////////////////////////////////////////
                               STRUCTS
    //////////////////////////////////////////////////////////////*/

    struct Proposal {
        bytes32 rootClaim;

        // packed slot
        address proposer;
        uint32  l2BlockNumber;
        uint32  parentIndex;
        uint32  deadline;

        uint32  resolvedAt;
        ProposalStatus proposalStatus;
        ResolutionStatus resolutionStatus;
        address challenger;
        address prover;  // Who proved this specific proposal
    }
    
    // No struct needed - just store the prover address directly
    
    struct AggregationOutputs {
        bytes32 l1Head;
        bytes32 l2PreRoot;
        bytes32 claimRoot;
        uint256 claimBlockNum;
        bytes32 rollupConfigHash;
        bytes32 rangeVkeyCommitment;
        address proverAddress;
    }

    /*//////////////////////////////////////////////////////////////
                               STORAGE
    //////////////////////////////////////////////////////////////*/

    Proposal[] proposals; // index == proposalId

    mapping(address => uint256) public credit;

    mapping(address => bool) public whitelistedProposer;

    // The anchor tracks the latest accepted block
    uint256 public anchorL2BlockNumber;
    
    // Checkpointed L1 block hashes for proof verification
    mapping(uint256 => bytes32) public l1BlockHashes;

    // Maps L2 block number to the canonical proposal ID
    // 0 means no canonical proposal exists (uninitialized storage)
    // type(uint256).max means proposal 0 (genesis) is canonical
    uint256 private constant GENESIS_SENTINEL = type(uint256).max;
    mapping(uint256 => uint256) private _canonical;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(
        uint256 _challengeSecs,
        uint256 _proveSecs,
        uint256 _challengerBond,
        uint256 _proposerBond,
        uint256 _fallbackTimeout,
        uint256 _proposalInterval,
        bytes32 _startRoot,
        uint256 _startBlock,
        uint256 _l2StartTimestamp,
        uint256 _l2BlockTime,
        ISP1Verifier _verifier,
        bytes32 _rollupHash,
        bytes32 _aggVkey,
        bytes32 _rangeCommit
    ) {
        MAX_CHALLENGE_SECS    = _challengeSecs;
        MAX_PROVE_SECS        = _proveSecs;
        CHALLENGER_BOND       = _challengerBond;
        PROPOSER_BOND         = _proposerBond;
        FALLBACK_TIMEOUT_SECS = _fallbackTimeout;
        PROPOSAL_INTERVAL     = _proposalInterval;
        L2_START_TIMESTAMP    = _l2StartTimestamp;
        L2_BLOCK_TIME         = _l2BlockTime;
        
        VERIFIER              = _verifier;
        ROLLUP_CONFIG_HASH    = _rollupHash;
        AGG_VKEY              = _aggVkey;
        RANGE_VKEY_COMMITMENT = _rangeCommit;

        anchorL2BlockNumber = _startBlock;
        
        // Create genesis proposal representing the starting anchor
        Proposal memory genesis = Proposal({
            rootClaim: _startRoot,
            l2BlockNumber: _startBlock.toUint32(),
            parentIndex: 0,
            deadline: 0,
            proposer: address(0),
            challenger: address(0),
            resolvedAt: 0,
            proposalStatus: ProposalStatus.Resolved,
            resolutionStatus: ResolutionStatus.DEFENDER_WINS,
            prover: address(0)
        });
        
        proposals.push(genesis);

        _trySetCanonical(_startBlock, 0);
    }

    /*//////////////////////////////////////////////////////////////
                               ACTIONS
    //////////////////////////////////////////////////////////////*/

    /// @notice Creates a proposal with validation common to both fault proofs and validity proofs
    /// @param root L2 output root being proposed
    /// @param l2BlockNumber L2 block number (must be parentBlock + PROPOSAL_INTERVAL)
    /// @param parentId Parent proposal ID (must be valid and not invalidated)
    /// @param proposer Proposer address (address(0) for validity proofs, actual address for fault proofs)
    /// @return proposalId ID of the created proposal
    function _createProposal(
        bytes32 root,
        uint256 l2BlockNumber,
        uint256 parentId,
        address proposer
    ) internal returns (uint256 proposalId) {
        if (parentId >= proposals.length) revert InvalidParentGame();
        Proposal storage parent = proposals[parentId];
        
        if (l2BlockNumber <= anchorL2BlockNumber) revert ProposingBackwards();
        if (computeL2Timestamp(l2BlockNumber) >= block.timestamp) revert ProposingFutureBlock();
        
        if (_canonicalExistsFor(l2BlockNumber)) revert BlockAlreadyProven();
        
        // Proposals must follow the exact interval cadence from their parent
        if (l2BlockNumber != parent.l2BlockNumber + PROPOSAL_INTERVAL) {
            revert BadCadence();
        }
        
        // Cannot build on top of invalidated proposals
        if (parent.resolutionStatus == ResolutionStatus.CHALLENGER_WINS) {
            revert InvalidParentGame();
        }
        proposals.push();
        proposalId = proposals.length - 1;
        
        Proposal storage p = proposals[proposalId];
        p.rootClaim = root;
        p.l2BlockNumber = l2BlockNumber.toUint32();
        p.parentIndex = parentId.toUint32();
        p.deadline = (block.timestamp + MAX_CHALLENGE_SECS).toUint32();
        p.proposer = proposer;
        
        emit ProposalSubmitted(proposalId, parentId, proposer, root, l2BlockNumber);
    }

    /// @notice Submit a fault proof proposal that can be challenged
    /// @param root Output root claim for the L2 block
    /// @param l2BlockNumber L2 block number being proposed
    /// @param parentId Parent proposal to build upon
    /// @return proposalId ID of created proposal
    /// @dev Requires PROPOSER_BOND and proposer must be whitelisted or in fallback window
    function submitProposal(
        bytes32 root,
        uint256 l2BlockNumber,
        uint256  parentId
    ) external payable returns (uint256 proposalId) {
        if (msg.value != PROPOSER_BOND) revert IncorrectBondAmount();
        
        // Authorization: whitelist OR 2-week fallback (censorship resistance)
        if (!isWhitelistedProposer(msg.sender) && !isInFallbackWindow(l2BlockNumber)) {
            revert BadAuth();
        }
        proposalId = _createProposal({
            root: root,
            l2BlockNumber: l2BlockNumber,
            parentId: parentId,
            proposer: msg.sender
        });
    }
    
    /// @notice Challenge a proposal claiming it has the wrong root
    /// @param id Proposal ID to challenge
    /// @dev Requires CHALLENGER_BOND, starts proof countdown
    function challengeProposal(uint256 id) external payable onlyIfGameNotOver(id) {
        if (msg.value != CHALLENGER_BOND) revert IncorrectBondAmount();
        
        Proposal storage p = proposals[id];
        if (p.proposalStatus != ProposalStatus.Unchallenged) revert AlreadyChallenged();

        p.challenger = msg.sender;
        p.proposalStatus = ProposalStatus.Challenged;
        p.deadline = (block.timestamp + MAX_PROVE_SECS).toUint32();

        emit ProposalChallenged(id, msg.sender);
    }

    /// @notice Submit a validity proof that bypasses the optimistic flow
    /// @param l2BlockNumber L2 block to prove (must be anchorBlock + PROPOSAL_INTERVAL)
    /// @param root Correct output root for this block
    /// @param l1BlockNumber L1 block used in proof (for L1 data availability)
    /// @param proof ZK proof of state transition from anchor to this block
    /// @dev Creates, proves, and resolves a proposal atomically. No bond required.
    function proveBlock(
        uint256 l2BlockNumber,
        bytes32 root,
        uint256 l1BlockNumber,
        bytes calldata proof
    ) external {
        // Validity proofs must build directly on the anchor to ensure linear progression
        // Anchor always has a canonical (genesis at minimum)
        uint256 parentProposalId = anchorProposalId();
        
        // address(0) proposer indicates no bond was collected
        uint256 proposalId = _createProposal({
            root: root,
            l2BlockNumber: l2BlockNumber,
            parentId: parentProposalId,
            proposer: address(0)
        });
        
        proveProposal(proposalId, l1BlockNumber, proof);
        resolveProposal(proposalId);
        
        emit BlockProven(l2BlockNumber, root, msg.sender);
    }

    /// @notice Submit ZK proof defending a proposal
    /// @param id Proposal to prove
    /// @param l1BlockNumber L1 block for data availability context
    /// @param proof ZK proof of state transition from parent to this proposal
    /// @dev Parent must be valid for proof to be useful, but that's checked in resolution
    function proveProposal(
        uint256 id, 
        uint256 l1BlockNumber,
        bytes calldata proof
    ) public onlyIfGameNotOver(id) {
        Proposal storage p = proposals[id];
        
        bytes32 parentRoot = proposals[p.parentIndex].rootClaim;
        bytes32 l1BlockHash = getCheckpointedL1BlockHash(l1BlockNumber);
        AggregationOutputs memory pub = AggregationOutputs({
            l1Head: l1BlockHash,
            l2PreRoot: parentRoot,
            claimRoot: p.rootClaim,
            claimBlockNum: p.l2BlockNumber,
            rollupConfigHash: ROLLUP_CONFIG_HASH,
            rangeVkeyCommitment: RANGE_VKEY_COMMITMENT,
            proverAddress: msg.sender
        });
        
        VERIFIER.verifyProof(AGG_VKEY, abi.encode(pub), proof);
        
        p.prover = msg.sender;
        p.proposalStatus = (p.proposalStatus == ProposalStatus.Challenged) 
            ? ProposalStatus.ChallengedAndProven 
            : ProposalStatus.UnchallengedAndProven;
        
        emit ProposalProven(id, msg.sender);
    }

    /*//////////////////////////////////////////////////////////////
                               MODIFIERS
    //////////////////////////////////////////////////////////////*/

    modifier onlyIfGameOver(uint256 proposalId) {
        if (!gameOver(proposalId)) revert GameNotOver();
        _;
    }
    
    modifier onlyIfGameNotOver(uint256 proposalId) {
        if (gameOver(proposalId)) revert GameOver();
        _;
    }

    /*//////////////////////////////////////////////////////////////
                          GAME STATE LOGIC
    //////////////////////////////////////////////////////////////*/

    /// @notice Check if a proposal's game has ended (ready for resolution)
    /// @param proposalId Proposal to check
    /// @return True if deadline passed, proven locally, or canonical exists for block
    function gameOver(uint256 proposalId) public view returns (bool) {
        Proposal storage p = proposals[proposalId];
        return p.deadline < block.timestamp || 
               p.prover != address(0) ||
               _canonicalExistsFor(p.l2BlockNumber);
    }

    /// @notice Calculate how long ago an L2 block should have been created
    /// @param l2BlockNumber L2 block number
    /// @return Age in seconds since the block's expected timestamp
    function l2BlockAge(uint256 l2BlockNumber) public view returns (uint256) {
        return block.timestamp - computeL2Timestamp(l2BlockNumber);
    }
    
    /// @notice Returns the L2 timestamp corresponding to a given L2 block number.
    /// @notice Compute the expected timestamp for an L2 block
    /// @param _l2BlockNumber L2 block number
    /// @return Expected timestamp based on L2_BLOCK_TIME and genesis
    function computeL2Timestamp(uint256 _l2BlockNumber) public view returns (uint256) {
        if (_l2BlockNumber < proposals[0].l2BlockNumber) {
            revert InvalidL2BlockNumber();
        }
        
        return L2_START_TIMESTAMP + ((_l2BlockNumber - proposals[0].l2BlockNumber) * L2_BLOCK_TIME);
    }
    
    /// @notice Get L1 block hash from checkpoint or EVM history
    /// @param l1BlockNumber L1 block number
    /// @return l1BlockHash Block hash (reverts if too old and not checkpointed)
    function getCheckpointedL1BlockHash(uint256 l1BlockNumber) internal view returns (bytes32 l1BlockHash) {
        l1BlockHash = l1BlockHashes[l1BlockNumber];
        if (l1BlockHash == bytes32(0)) {
            revert L1BlockHashNotCheckpointed();
        }
    }

    /// @notice Resolve a proposal determining if defender or challenger wins
    /// @param id Proposal to resolve
    /// @dev Resolution hierarchy:
    /// @dev 1. Parent invalid → challenger wins (cascading invalidation)
    /// @dev 2. Conflicts with canonical → challenger wins (bulk invalidation) 
    /// @dev 3. Has valid proof → defender wins
    /// @dev 4. Timeout: challenged → challenger wins, unchallenged → defender wins
    function resolveProposal(uint256 id) public onlyIfGameOver(id) {
        Proposal storage p = proposals[id];
        Proposal storage parent = proposals[p.parentIndex];
        
        if (parent.resolutionStatus == ResolutionStatus.IN_PROGRESS) {
            revert ParentGameNotResolved();
        }
        if (p.resolutionStatus != ResolutionStatus.IN_PROGRESS) {
            revert AlreadyResolved();
        }

        // Resolution hierarchy (order matters!)
        if (parent.resolutionStatus == ResolutionStatus.CHALLENGER_WINS) {
            p.resolutionStatus = ResolutionStatus.CHALLENGER_WINS;
        }
        else if (_proposalConflictsWithCanonical(p)) {
            p.resolutionStatus = ResolutionStatus.CHALLENGER_WINS;
        }
        else if (_getProposalProver(p) != address(0)) {
            p.resolutionStatus = ResolutionStatus.DEFENDER_WINS;
        }
        else if (p.proposalStatus == ProposalStatus.Challenged) {
            p.resolutionStatus = ResolutionStatus.CHALLENGER_WINS;
        } else {
            p.resolutionStatus = ResolutionStatus.DEFENDER_WINS;
        }
        
        if (p.resolutionStatus == ResolutionStatus.DEFENDER_WINS) {
            _trySetCanonical(p.l2BlockNumber, id);
            
            // Advance anchor only if this directly extends it
            if (p.l2BlockNumber == anchorL2BlockNumber + PROPOSAL_INTERVAL) {
                anchorL2BlockNumber = p.l2BlockNumber;
                emit AnchorUpdated(id, p.rootClaim, p.l2BlockNumber);
            }
            
            _pay(p.proposer, _proposerBond(p));
            _pay(_getProposalProver(p), _challengerBond(p));
        } else if (p.resolutionStatus == ResolutionStatus.CHALLENGER_WINS) {
            address recipient = p.challenger;
            if (recipient == address(0)) {
                // Bulk invalidation case: pay canonical prover who proved correct root
                // If no canonical exists yet, bond is burned (recipient remains address(0))
                if (_canonicalExistsFor(p.l2BlockNumber)) {
                    recipient = _getProposalProver(_canonicalProposalFor(p.l2BlockNumber));
                }
            }
            _pay(recipient, _totalBond(p));
        }
        
        p.proposalStatus = ProposalStatus.Resolved;
        p.resolvedAt = (block.timestamp).toUint32();
        emit ProposalResolved(id, p.resolutionStatus);
        emit ProposalClosed(id);
    }

    /*//////////////////////////////////////////////////////////////
                           INTERNAL PAY-OUT HELPERS
    //////////////////////////////////////////////////////////////*/

    /// @dev Credits account
    function _pay(address to, uint256 amount) internal {
        if (to != address(0) && amount != 0) credit[to] += amount;
    }

    /// @dev Returns proposer bond amount (0 for validity proofs)
    function _proposerBond(Proposal storage p) internal view returns (uint256) {
        return p.proposer != address(0) ? PROPOSER_BOND : 0;
    }

    /// @dev Returns challenger bond amount (0 if unchallenged)
    function _challengerBond(Proposal storage p) internal view returns (uint256) {
        return p.challenger != address(0) ? CHALLENGER_BOND : 0;
    }

    /// @dev Total bonds at stake for this proposal
    function _totalBond(Proposal storage p) internal view returns (uint256) {
        return _proposerBond(p) + _challengerBond(p);
    }

    /// @dev Find who proved this proposal (considering canonical fallback)
    /// @return Prover address or address(0) if conflicts with canonical
    function _getProposalProver(Proposal storage p) internal view returns (address) {
        if (_proposalConflictsWithCanonical(p)) {
            return address(0);
        }
        
        // Prefer local prover, fall back to canonical proposal's prover
        if (p.prover != address(0)) {
            return p.prover;
        }
        
        if (_canonicalExistsFor(p.l2BlockNumber)) {
            Proposal storage canonical = _canonicalProposalFor(p.l2BlockNumber);
            return canonical.prover != address(0) ? canonical.prover : canonical.proposer;
        }
        
        return address(0);
    }
    
    /// @dev Check if proposal has wrong root compared to canonical
    function _proposalConflictsWithCanonical(Proposal storage p) internal view returns (bool) {
        return _canonicalExistsFor(p.l2BlockNumber) && 
               _canonicalProposalFor(p.l2BlockNumber).rootClaim != p.rootClaim;
    }


    /*//////////////////////////////////////////////////////////////
                         CREDIT WITHDRAWAL
    //////////////////////////////////////////////////////////////*/

    /// @notice Withdraw accumulated credit from bonds
    /// @param recipient Address to withdraw credit for
    /// @dev Uses pull pattern to prevent reentrancy
    function claimCredit(address recipient) public nonReentrant {
        uint256 amount = credit[recipient];
        if (amount == 0) revert NoCredit();
        
        credit[recipient] = 0;
        (bool ok,) = recipient.call{ value: amount }("");
        if (!ok) revert TransferFailed();
    }
    
    /*//////////////////////////////////////////////////////////////
                    PERMISSIONS & AUTHORIZATION
    //////////////////////////////////////////////////////////////*/

    /// @notice Update proposer whitelist
    /// @param proposer Address to update
    /// @param allowed Whether address can propose
    function setProposer(address proposer, bool allowed) external onlyOwner {
        whitelistedProposer[proposer] = allowed;
        emit ProposerPermissionUpdated(proposer, allowed);
    }

    /// @notice Check if address can submit proposals
    /// @param proposer Address to check
    /// @return True if whitelisted or wildcard enabled
    function isWhitelistedProposer(address proposer) public view returns (bool) {
        return whitelistedProposer[proposer] || whitelistedProposer[address(0)];
    }
    
    /// @notice Check if fallback window is active (anyone can propose)
    /// @param l2BlockNumber Block to check
    /// @return True if block is old enough for fallback
    function isInFallbackWindow(uint256 l2BlockNumber) public view returns (bool) {
        return l2BlockAge(l2BlockNumber) > FALLBACK_TIMEOUT_SECS;
    }

    /// @notice Store L1 block hash for proofs requiring old blocks
    /// @param l1BlockNumber L1 block to checkpoint (must be recent)
    /// @dev Only needed for blocks older than 256 blocks
    function checkpointL1BlockHash(uint256 l1BlockNumber) external {
        bytes32 blockHash = blockhash(l1BlockNumber);
        if (blockHash == bytes32(0)) {
            revert L1BlockHashNotAvailable();
        }
        l1BlockHashes[l1BlockNumber] = blockHash;
        
        emit L1BlockHashCheckpointed(l1BlockNumber, blockHash);
    }
    
    /*//////////////////////////////////////////////////////////////
                                GETTERS
    //////////////////////////////////////////////////////////////*/

    /// @notice Get the current anchor's output root
    /// @return Output root of the anchor block
    function anchorRoot() public view returns (bytes32) {
        // Anchor always has a canonical proposal (genesis at minimum)
        return _canonicalProposalFor(anchorL2BlockNumber).rootClaim;
    }

    /// @notice Get a single proposal
    /// @param id Proposal ID
    /// @return The proposal struct
    function getProposal(uint256 id) external view returns (Proposal memory) {
        return proposals[id];
    }
    
    /// @notice Get current anchor root and block number
    /// @return root Output root
    /// @return blockNumber L2 block number
    function getAnchorRoot() external view returns (bytes32, uint256) {
        return (anchorRoot(), anchorL2BlockNumber);
    }

    /// @notice Batch get proposals by IDs
    /// @param ids Array of proposal IDs
    /// @return out Array of proposals
    function getProposals(uint256[] calldata ids) external view returns (Proposal[] memory out) {
        out = new Proposal[](ids.length);
        for (uint256 i; i < ids.length; ++i) out[i] = proposals[ids[i]];
    }

    /// @notice Get most recent proposal IDs
    /// @param count Number of proposals to return
    /// @return ids Array of proposal IDs (newest first)
    function latestProposals(uint256 count) external view returns (uint256[] memory ids) {
        uint256 total = proposals.length;
        if (count > total) count = total;
        ids = new uint256[](count);
        for (uint256 i; i < count; ++i) ids[i] = total - 1 - i;
    }

    /// @notice Get total number of proposals
    /// @return Number of proposals created
    function getProposalsLength() external view returns (uint256) {
        return proposals.length;
    }
    
    /// @notice Check if proposal can be resolved
    /// @param proposalId Proposal to check
    /// @return True if game over and not yet resolved
    function isResolvable(uint256 proposalId) external view returns (bool) {
        if (proposalId >= proposals.length) return false;
        Proposal storage p = proposals[proposalId];
        return gameOver(proposalId) && p.resolutionStatus == ResolutionStatus.IN_PROGRESS;
    }
    
    /// @notice Check if proposal needs a proof
    /// @param proposalId Proposal to check  
    /// @return True if challenged and deadline not passed
    function needsDefense(uint256 proposalId) external view returns (bool) {
        if (proposalId >= proposals.length) return false;
        return !gameOver(proposalId) && proposals[proposalId].proposalStatus == ProposalStatus.Challenged;
    }
    
    /// @notice Get the canonical proposal ID for the anchor block
    /// @return Proposal ID of current anchor
    function anchorProposalId() public view returns (uint256) {
        return canonicalProposalIdFor(anchorL2BlockNumber);
    }

    /*//////////////////////////////////////////////////////////////
                     CANONICAL PROPOSAL HELPERS
    //////////////////////////////////////////////////////////////*/

    /// @notice Get the canonical proposal for an L2 block
    /// @param l2BlockNumber The L2 block number
    /// @return The canonical proposal, or empty proposal if none exists
    function canonicalProposalFor(uint256 l2BlockNumber) public view returns (Proposal memory) {
        if (!_canonicalExistsFor(l2BlockNumber)) revert NoCanonicalProposal();
        
        uint256 canonicalId = canonicalProposalIdFor(l2BlockNumber);
        return proposals[canonicalId];
    }

    /// @notice Get the canonical proposal ID for an L2 block
    /// @param l2BlockNumber The L2 block number
    /// @return The canonical proposal ID, or 0 if none exists
    function canonicalProposalIdFor(uint256 l2BlockNumber) public view returns (uint256) {
        if (!_canonicalExistsFor(l2BlockNumber)) revert NoCanonicalProposal();
        
        return _canonical[l2BlockNumber] == GENESIS_SENTINEL ? 0 : _canonical[l2BlockNumber];
    }
    
    function proposalIsCanonical(uint256 proposalId) public view returns (bool) {
        if (proposalId >= proposals.length) return false;
        Proposal storage p = proposals[proposalId];
        return _canonicalExistsFor(p.l2BlockNumber) && proposalId == canonicalProposalIdFor(p.l2BlockNumber);
    }

    /// @dev Get the canonical proposal storage reference (reverts if doesn't exist)
    function _canonicalProposalFor(uint256 l2BlockNumber) internal view returns (Proposal storage) {
        uint256 canonicalId = canonicalProposalIdFor(l2BlockNumber);
        
        return proposals[canonicalId];
    }

    /// @dev Check if a canonical proposal exists for an L2 block
    function _canonicalExistsFor(uint256 l2BlockNumber) internal view returns (bool) {
        return _canonical[l2BlockNumber] != 0;
    }

    /// @dev Try to set the canonical proposal for an L2 block (only sets if not already set)
    function _trySetCanonical(uint256 l2BlockNumber, uint256 proposalId) internal {
        if (!_canonicalExistsFor(l2BlockNumber)) {
            _canonical[l2BlockNumber] = proposalId == 0 ? GENESIS_SENTINEL : proposalId;
        }
    }
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

/// @title SP1 Verifier Interface
/// @author Succinct Labs
/// @notice This contract is the interface for the SP1 Verifier.
interface ISP1Verifier {
    /// @notice Verifies a proof with given public values and vkey.
    /// @dev It is expected that the first 4 bytes of proofBytes must match the first 4 bytes of
    /// target verifier's VERIFIER_HASH.
    /// @param programVKey The verification key for the RISC-V program.
    /// @param publicValues The public values encoded as bytes.
    /// @param proofBytes The proof of the program execution the SP1 zkVM encoded as bytes.
    function verifyProof(
        bytes32 programVKey,
        bytes calldata publicValues,
        bytes calldata proofBytes
    ) external view;
}

interface ISP1VerifierWithHash is ISP1Verifier {
    /// @notice Returns the hash of the verifier.
    function VERIFIER_HASH() external pure returns (bytes32);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

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

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

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

File 4 of 6 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 5 of 6 : SafeCastLib.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Safe integer casting library that reverts on overflow.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeCastLib.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeCast.sol)
library SafeCastLib {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    error Overflow();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*          UNSIGNED INTEGER SAFE CASTING OPERATIONS          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    function toUint8(uint256 x) internal pure returns (uint8) {
        if (x >= 1 << 8) _revertOverflow();
        return uint8(x);
    }

    function toUint16(uint256 x) internal pure returns (uint16) {
        if (x >= 1 << 16) _revertOverflow();
        return uint16(x);
    }

    function toUint24(uint256 x) internal pure returns (uint24) {
        if (x >= 1 << 24) _revertOverflow();
        return uint24(x);
    }

    function toUint32(uint256 x) internal pure returns (uint32) {
        if (x >= 1 << 32) _revertOverflow();
        return uint32(x);
    }

    function toUint40(uint256 x) internal pure returns (uint40) {
        if (x >= 1 << 40) _revertOverflow();
        return uint40(x);
    }

    function toUint48(uint256 x) internal pure returns (uint48) {
        if (x >= 1 << 48) _revertOverflow();
        return uint48(x);
    }

    function toUint56(uint256 x) internal pure returns (uint56) {
        if (x >= 1 << 56) _revertOverflow();
        return uint56(x);
    }

    function toUint64(uint256 x) internal pure returns (uint64) {
        if (x >= 1 << 64) _revertOverflow();
        return uint64(x);
    }

    function toUint72(uint256 x) internal pure returns (uint72) {
        if (x >= 1 << 72) _revertOverflow();
        return uint72(x);
    }

    function toUint80(uint256 x) internal pure returns (uint80) {
        if (x >= 1 << 80) _revertOverflow();
        return uint80(x);
    }

    function toUint88(uint256 x) internal pure returns (uint88) {
        if (x >= 1 << 88) _revertOverflow();
        return uint88(x);
    }

    function toUint96(uint256 x) internal pure returns (uint96) {
        if (x >= 1 << 96) _revertOverflow();
        return uint96(x);
    }

    function toUint104(uint256 x) internal pure returns (uint104) {
        if (x >= 1 << 104) _revertOverflow();
        return uint104(x);
    }

    function toUint112(uint256 x) internal pure returns (uint112) {
        if (x >= 1 << 112) _revertOverflow();
        return uint112(x);
    }

    function toUint120(uint256 x) internal pure returns (uint120) {
        if (x >= 1 << 120) _revertOverflow();
        return uint120(x);
    }

    function toUint128(uint256 x) internal pure returns (uint128) {
        if (x >= 1 << 128) _revertOverflow();
        return uint128(x);
    }

    function toUint136(uint256 x) internal pure returns (uint136) {
        if (x >= 1 << 136) _revertOverflow();
        return uint136(x);
    }

    function toUint144(uint256 x) internal pure returns (uint144) {
        if (x >= 1 << 144) _revertOverflow();
        return uint144(x);
    }

    function toUint152(uint256 x) internal pure returns (uint152) {
        if (x >= 1 << 152) _revertOverflow();
        return uint152(x);
    }

    function toUint160(uint256 x) internal pure returns (uint160) {
        if (x >= 1 << 160) _revertOverflow();
        return uint160(x);
    }

    function toUint168(uint256 x) internal pure returns (uint168) {
        if (x >= 1 << 168) _revertOverflow();
        return uint168(x);
    }

    function toUint176(uint256 x) internal pure returns (uint176) {
        if (x >= 1 << 176) _revertOverflow();
        return uint176(x);
    }

    function toUint184(uint256 x) internal pure returns (uint184) {
        if (x >= 1 << 184) _revertOverflow();
        return uint184(x);
    }

    function toUint192(uint256 x) internal pure returns (uint192) {
        if (x >= 1 << 192) _revertOverflow();
        return uint192(x);
    }

    function toUint200(uint256 x) internal pure returns (uint200) {
        if (x >= 1 << 200) _revertOverflow();
        return uint200(x);
    }

    function toUint208(uint256 x) internal pure returns (uint208) {
        if (x >= 1 << 208) _revertOverflow();
        return uint208(x);
    }

    function toUint216(uint256 x) internal pure returns (uint216) {
        if (x >= 1 << 216) _revertOverflow();
        return uint216(x);
    }

    function toUint224(uint256 x) internal pure returns (uint224) {
        if (x >= 1 << 224) _revertOverflow();
        return uint224(x);
    }

    function toUint232(uint256 x) internal pure returns (uint232) {
        if (x >= 1 << 232) _revertOverflow();
        return uint232(x);
    }

    function toUint240(uint256 x) internal pure returns (uint240) {
        if (x >= 1 << 240) _revertOverflow();
        return uint240(x);
    }

    function toUint248(uint256 x) internal pure returns (uint248) {
        if (x >= 1 << 248) _revertOverflow();
        return uint248(x);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*           SIGNED INTEGER SAFE CASTING OPERATIONS           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    function toInt8(int256 x) internal pure returns (int8) {
        int8 y = int8(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt16(int256 x) internal pure returns (int16) {
        int16 y = int16(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt24(int256 x) internal pure returns (int24) {
        int24 y = int24(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt32(int256 x) internal pure returns (int32) {
        int32 y = int32(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt40(int256 x) internal pure returns (int40) {
        int40 y = int40(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt48(int256 x) internal pure returns (int48) {
        int48 y = int48(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt56(int256 x) internal pure returns (int56) {
        int56 y = int56(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt64(int256 x) internal pure returns (int64) {
        int64 y = int64(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt72(int256 x) internal pure returns (int72) {
        int72 y = int72(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt80(int256 x) internal pure returns (int80) {
        int80 y = int80(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt88(int256 x) internal pure returns (int88) {
        int88 y = int88(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt96(int256 x) internal pure returns (int96) {
        int96 y = int96(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt104(int256 x) internal pure returns (int104) {
        int104 y = int104(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt112(int256 x) internal pure returns (int112) {
        int112 y = int112(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt120(int256 x) internal pure returns (int120) {
        int120 y = int120(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt128(int256 x) internal pure returns (int128) {
        int128 y = int128(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt136(int256 x) internal pure returns (int136) {
        int136 y = int136(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt144(int256 x) internal pure returns (int144) {
        int144 y = int144(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt152(int256 x) internal pure returns (int152) {
        int152 y = int152(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt160(int256 x) internal pure returns (int160) {
        int160 y = int160(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt168(int256 x) internal pure returns (int168) {
        int168 y = int168(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt176(int256 x) internal pure returns (int176) {
        int176 y = int176(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt184(int256 x) internal pure returns (int184) {
        int184 y = int184(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt192(int256 x) internal pure returns (int192) {
        int192 y = int192(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt200(int256 x) internal pure returns (int200) {
        int200 y = int200(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt208(int256 x) internal pure returns (int208) {
        int208 y = int208(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt216(int256 x) internal pure returns (int216) {
        int216 y = int216(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt224(int256 x) internal pure returns (int224) {
        int224 y = int224(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt232(int256 x) internal pure returns (int232) {
        int232 y = int232(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt240(int256 x) internal pure returns (int240) {
        int240 y = int240(x);
        if (x != y) _revertOverflow();
        return y;
    }

    function toInt248(int256 x) internal pure returns (int248) {
        int248 y = int248(x);
        if (x != y) _revertOverflow();
        return y;
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*               OTHER SAFE CASTING OPERATIONS                */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    function toInt256(uint256 x) internal pure returns (int256) {
        if (x >= 1 << 255) _revertOverflow();
        return int256(x);
    }

    function toUint256(int256 x) internal pure returns (uint256) {
        if (x < 0) _revertOverflow();
        return uint256(x);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      PRIVATE HELPERS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    function _revertOverflow() private pure {
        /// @solidity memory-safe-assembly
        assembly {
            // Store the function selector of `Overflow()`.
            mstore(0x00, 0x35278d12)
            // Revert with (offset, size).
            revert(0x1c, 0x04)
        }
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

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

Settings
{
  "remappings": [
    "0xFacet/facet-sol-1.0.0/=dependencies/0xFacet-facet-sol-1.0.0/",
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "@optimism/=lib/optimism/packages/contracts-bedrock/",
    "@forge-std/=lib/forge-std/src/",
    "@solady/=lib/solady/src/",
    "@sp1-contracts/=lib/sp1-contracts/contracts/",
    "@rari-capital/=lib/optimism/packages/contracts-bedrock/lib/",
    "src/libraries/=lib/optimism/packages/contracts-bedrock/src/libraries/",
    "src/L1/=lib/optimism/packages/contracts-bedrock/src/L1/",
    "src/L2/=lib/optimism/packages/contracts-bedrock/src/L2/",
    "src/dispute/=lib/optimism/packages/contracts-bedrock/src/dispute/",
    "interfaces/=lib/optimism/packages/contracts-bedrock/interfaces/",
    "@lib-keccak/=lib/lib-keccak/contracts/lib/",
    "src/cannon/libraries/=lib/optimism/packages/contracts-bedrock/src/cannon/libraries/",
    "facet-sol/=lib/facet-sol/",
    "optimism/=lib/optimism/",
    "@solady-test/=lib/lib-keccak/lib/solady/test/",
    "ds-test/=lib/solady/lib/ds-test/src/",
    "erc4626-tests/=lib/optimism/packages/contracts-bedrock/lib/openzeppelin-contracts-v5/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "kontrol-cheatcodes/=lib/optimism/packages/contracts-bedrock/lib/kontrol-cheatcodes/src/",
    "lib-keccak/=lib/lib-keccak/contracts/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts-v5/=lib/optimism/packages/contracts-bedrock/lib/openzeppelin-contracts-v5/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "safe-contracts/=lib/optimism/packages/contracts-bedrock/lib/safe-contracts/contracts/",
    "solady-v0.0.245/=lib/optimism/packages/contracts-bedrock/lib/solady-v0.0.245/src/",
    "solady/=lib/solady/",
    "solmate/=lib/optimism/packages/contracts-bedrock/lib/solmate/src/",
    "sp1-contracts/=lib/sp1-contracts/contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": true,
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"uint256","name":"_challengeSecs","type":"uint256"},{"internalType":"uint256","name":"_proveSecs","type":"uint256"},{"internalType":"uint256","name":"_challengerBond","type":"uint256"},{"internalType":"uint256","name":"_proposerBond","type":"uint256"},{"internalType":"uint256","name":"_fallbackTimeout","type":"uint256"},{"internalType":"uint256","name":"_proposalInterval","type":"uint256"},{"internalType":"bytes32","name":"_startRoot","type":"bytes32"},{"internalType":"uint256","name":"_startBlock","type":"uint256"},{"internalType":"uint256","name":"_l2StartTimestamp","type":"uint256"},{"internalType":"uint256","name":"_l2BlockTime","type":"uint256"},{"internalType":"contract ISP1Verifier","name":"_verifier","type":"address"},{"internalType":"bytes32","name":"_rollupHash","type":"bytes32"},{"internalType":"bytes32","name":"_aggVkey","type":"bytes32"},{"internalType":"bytes32","name":"_rangeCommit","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyChallenged","type":"error"},{"inputs":[],"name":"AlreadyResolved","type":"error"},{"inputs":[],"name":"BadAuth","type":"error"},{"inputs":[],"name":"BadCadence","type":"error"},{"inputs":[],"name":"BlockAlreadyProven","type":"error"},{"inputs":[],"name":"GameNotOver","type":"error"},{"inputs":[],"name":"GameOver","type":"error"},{"inputs":[],"name":"IncorrectBondAmount","type":"error"},{"inputs":[],"name":"InvalidL2BlockNumber","type":"error"},{"inputs":[],"name":"InvalidParentGame","type":"error"},{"inputs":[],"name":"L1BlockHashNotAvailable","type":"error"},{"inputs":[],"name":"L1BlockHashNotCheckpointed","type":"error"},{"inputs":[],"name":"NoCanonicalProposal","type":"error"},{"inputs":[],"name":"NoCredit","type":"error"},{"inputs":[],"name":"ParentGameNotResolved","type":"error"},{"inputs":[],"name":"ProposingBackwards","type":"error"},{"inputs":[],"name":"ProposingFutureBlock","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"l2BlockNumber","type":"uint256"}],"name":"AnchorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"l2BlockNumber","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":true,"internalType":"address","name":"prover","type":"address"}],"name":"BlockProven","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"l1BlockNumber","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"blockHash","type":"bytes32"}],"name":"L1BlockHashCheckpointed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":true,"internalType":"address","name":"challenger","type":"address"}],"name":"ProposalChallenged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"ProposalClosed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":true,"internalType":"address","name":"prover","type":"address"}],"name":"ProposalProven","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"enum Rollup.ResolutionStatus","name":"status","type":"uint8"}],"name":"ProposalResolved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"parentId","type":"uint256"},{"indexed":true,"internalType":"address","name":"proposer","type":"address"},{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"l2BlockNumber","type":"uint256"}],"name":"ProposalSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"proposer","type":"address"},{"indexed":false,"internalType":"bool","name":"allowed","type":"bool"}],"name":"ProposerPermissionUpdated","type":"event"},{"inputs":[],"name":"AGG_VKEY","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CHALLENGER_BOND","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FALLBACK_TIMEOUT_SECS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"L2_BLOCK_TIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"L2_START_TIMESTAMP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_CHALLENGE_SECS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PROVE_SECS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PROPOSAL_INTERVAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PROPOSER_BOND","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RANGE_VKEY_COMMITMENT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROLLUP_CONFIG_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERIFIER","outputs":[{"internalType":"contract ISP1Verifier","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"anchorL2BlockNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"anchorProposalId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"anchorRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"l2BlockNumber","type":"uint256"}],"name":"canonicalProposalFor","outputs":[{"components":[{"internalType":"bytes32","name":"rootClaim","type":"bytes32"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint32","name":"l2BlockNumber","type":"uint32"},{"internalType":"uint32","name":"parentIndex","type":"uint32"},{"internalType":"uint32","name":"deadline","type":"uint32"},{"internalType":"uint32","name":"resolvedAt","type":"uint32"},{"internalType":"enum Rollup.ProposalStatus","name":"proposalStatus","type":"uint8"},{"internalType":"enum Rollup.ResolutionStatus","name":"resolutionStatus","type":"uint8"},{"internalType":"address","name":"challenger","type":"address"},{"internalType":"address","name":"prover","type":"address"}],"internalType":"struct Rollup.Proposal","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"l2BlockNumber","type":"uint256"}],"name":"canonicalProposalIdFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"challengeProposal","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"l1BlockNumber","type":"uint256"}],"name":"checkpointL1BlockHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"claimCredit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_l2BlockNumber","type":"uint256"}],"name":"computeL2Timestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"credit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"gameOver","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAnchorRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getProposal","outputs":[{"components":[{"internalType":"bytes32","name":"rootClaim","type":"bytes32"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint32","name":"l2BlockNumber","type":"uint32"},{"internalType":"uint32","name":"parentIndex","type":"uint32"},{"internalType":"uint32","name":"deadline","type":"uint32"},{"internalType":"uint32","name":"resolvedAt","type":"uint32"},{"internalType":"enum Rollup.ProposalStatus","name":"proposalStatus","type":"uint8"},{"internalType":"enum Rollup.ResolutionStatus","name":"resolutionStatus","type":"uint8"},{"internalType":"address","name":"challenger","type":"address"},{"internalType":"address","name":"prover","type":"address"}],"internalType":"struct Rollup.Proposal","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"getProposals","outputs":[{"components":[{"internalType":"bytes32","name":"rootClaim","type":"bytes32"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint32","name":"l2BlockNumber","type":"uint32"},{"internalType":"uint32","name":"parentIndex","type":"uint32"},{"internalType":"uint32","name":"deadline","type":"uint32"},{"internalType":"uint32","name":"resolvedAt","type":"uint32"},{"internalType":"enum Rollup.ProposalStatus","name":"proposalStatus","type":"uint8"},{"internalType":"enum Rollup.ResolutionStatus","name":"resolutionStatus","type":"uint8"},{"internalType":"address","name":"challenger","type":"address"},{"internalType":"address","name":"prover","type":"address"}],"internalType":"struct Rollup.Proposal[]","name":"out","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProposalsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"l2BlockNumber","type":"uint256"}],"name":"isInFallbackWindow","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"isResolvable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"proposer","type":"address"}],"name":"isWhitelistedProposer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"l1BlockHashes","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"l2BlockNumber","type":"uint256"}],"name":"l2BlockAge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"latestProposals","outputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"needsDefense","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalIsCanonical","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"l2BlockNumber","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"uint256","name":"l1BlockNumber","type":"uint256"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"proveBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"l1BlockNumber","type":"uint256"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"proveProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"resolveProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"proposer","type":"address"},{"internalType":"bool","name":"allowed","type":"bool"}],"name":"setProposer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"uint256","name":"l2BlockNumber","type":"uint256"},{"internalType":"uint256","name":"parentId","type":"uint256"}],"name":"submitProposal","outputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistedProposer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

0x34620004225762002c9938819003610200601f8201601f19168101906001600160401b0382119082101762000401576101c09282916040526102003912620004225761020051610220516102405161026051610280516102a0516102c0516102e051610300516103205161034051929893979396939592949093919290916001600160a01b0386168603620004225761036051610380516103a0515f8054336001600160a01b0319821681178355929f939c949b949392916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a36001805560805260a05260c05260e05261010052610120526101405261016052610180526101a0526101c0526101e09283528160055564010000000082101562000415576040519063ffffffff9061014083016001600160401b038111848210176200040157604052825260208201915f83526040810191808516835260608201925f8452608083015f815260a08401925f845260c08501926004845260e0860192600184526101008701975f89526101208801995f8b526002546801000000000000000081101562000401576001810180600255811015620003ed5760025f5260205f209060021b019851895560018060a01b039051169263ffffffff60a01b905160a01b169063ffffffff60c01b905160c01b169163ffffffff60e01b905160e01b169217171760018601556002850193511683549251916005831015620003d95751916003831015620003d95764ff0000000065ff0000000000926003986601000000000000600160d01b03905160301b169560018060d01b031916179160201b16179160281b1617179055019060018060a01b0390511660018060a01b03198254161790555f52600760205260405f20805415620003ce575b506040516128729182620004278339608051828181610a72015281816115ee0152611862015260a0518281816113d401526116a4015260c0518281816108610152818161134c01526127a0015260e051828181611703015281816119d601526127630152610100518281816103d9015281816118f30152611a210152610120518281816102630152818161099f01528181610e76015281816117940152611e3b0152610140518281816108ba015261257b0152610160518281816120720152612545015261018051828181610c2201528181610ccb01528181611a5b0152611b9f01526101a051828181610b760152818161199b0152611b4401526101c051828181610c6d015281816114830152611c1e01525181818161050001528181610b9c0152611b6e0152f35b5f1990555f620002a4565b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52604160045260245ffd5b6335278d125f526004601cfd5b5f80fdfe6080806040526004361015610012575f80fd5b5f905f3560e01c9081622134cc1461205d5750806262804e14611d1557806275552a14611a8a57806308c84e7014611a455780631c1d5335146119f95780631ef7a1f7146119be5780632a6375da146119835780633522f0101461191957806345925013146116eb57806347cc2f3d146116c75780634cc4f2b61461168c57806354fd4d50146116305780635872bbed146116115780635da1f255146115d657806360e27464146114c55780636338049b146114a657806365e1dfa41461146b5780636c541de11461132d578063715018a6146112d457806385f9ce72146112b55780638d7a1d5f1461128b5780638da5cb5b146112645780639eeeb21414610905578063a703800d146108dd578063b3debd42146108a2578063b6a82c4c14610884578063bb825afc14610849578063bc378a731461082b578063c7f758a8146107ff578063d1de856c146107e0578063d5d44d80146107a7578063d7a0df791461073c578063d83ef2671461070b578063db3aa5d0146106db578063dc26de6f146106bd578063dd843d5614610696578063e9ed9b6414610613578063eca77cd614610523578063ed6892ed146104e8578063eea128fd146104bf578063f2fde38b146103fc578063f584be7b146103c1578063f5f3bf2314610286578063f7c736d01461024b5763f8315bc21461020a575f80fd5b346102485760203660031901126102485760209060ff906040906001600160a01b036102346120c2565b168152600484522054166040519015158152f35b80fd5b503461024857806003193601126102485760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b5034610248576020806003193601126103bd57600435916001600160401b038084116103bd57366023850112156103bd5783600401359081116103bd5760246005943660248460051b830101116103b9576102e3839694966125e6565b936102f1604051958661213e565b8385526102fd846125e6565b601f1901875b81811061039d575050865b84811061035f57604080518881528751818a01819052888a01928201908a8c5b82811061033b5784840385f35b90919282610140826103506001948a516121aa565b0196019101949291909461032e565b8061037e61037886600194869c9a9c1b87010135612236565b5061246a565b610388828b6125fd565b52610393818a6125fd565b500196949661030e565b87906103aa999799612420565b82828c01015201979597610303565b8380fd5b5080fd5b503461024857806003193601126102485760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b5034610248576020366003190112610248576104166120c2565b61041e6127e5565b6001600160a01b0390811690811561046b575f54826001600160601b0360a01b8216175f55167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a380f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b50346102485760203660031901126102485760206104de600435612611565b6040519015158152f35b503461024857806003193601126102485760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b5034610248576020806003193601126103bd576002546004359181831161060a575b919092610551826125e6565b9361055f604051958661213e565b82855261056b836125e6565b8585019390601f19013685375f198201918211835b8281106105c9575050505060405193838594850191818652518092526040850193925b8281106105b257505050500390f35b8351855286955093810193928101926001016105a3565b8197959694976105f657806105e060019286612413565b6105ea82896125fd565b52019693959496610580565b634e487b7160e01b88526011600452602488fd5b91508091610545565b50346102485760403660031901126102485761062d6120c2565b602435908115158092036106925760207f205b4586f0aad63e3849b0c69893bd6139aca673e7f16088c504691c6502cee4916106676127e5565b6001600160a01b0316808552600482526040808620805460ff191660ff87161790555193845292a280f35b8280fd5b50346102485760203660031901126102485760206106b56004356125b1565b604051908152f35b50346102485780600319360112610248576020600554604051908152f35b503461024857806003193601126102485760206107016106fc6005546125b1565b612236565b5054604051908152f35b5034610248578060031936011261024857604060055461072d6106fc826125b1565b50549082519182526020820152f35b503461024857602036600319011261024857600435610759612420565b5061076f815f52600760205260405f2054151590565b15610795576107866103786106fc610140936125b1565b61079360405180926121aa565bf35b604051638988695560e01b8152600490fd5b5034610248576020366003190112610248576020906040906001600160a01b036107cf6120c2565b168152600383522054604051908152f35b50346102485760203660031901126102485760206106b5600435612508565b503461024857602036600319011261024857610819612420565b50610140610786610378600435612236565b50346102485780600319360112610248576020600254604051908152f35b503461024857806003193601126102485760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b503461024857806003193601126102485760206106b56005546125b1565b503461024857806003193601126102485760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b50346102485760203660031901126102485760206106b56108ff600435612508565b42612413565b5034610248576080366003190112610248576064356001600160401b0381116103bd57610936903690600401612095565b60055491610943836125b1565b60025493848210156111f65761095882612236565b509060043511156112525761096e600435612508565b4211156112405761098c6004355f52600760205260405f2054151590565b61122e576109c8600182015463ffffffff7f00000000000000000000000000000000000000000000000000000000000000009160a01c166122b4565b6004350361121c576002015460281c60ff166003811015611208576002146111f657600160401b8410156111e2576001840180600255610a0785612236565b505084116111ce575f90610a1a85612236565b5060243581556001610a2d6004356127c2565b910190815463ffffffff60c01b610a43856127c2565b60c01b169163ffffffff60a01b9060a01b16906001600160401b0360a01b191617178155610abc610a9c610a977f0000000000000000000000000000000000000000000000000000000000000000426122b4565b6127c2565b82546001600160e01b031660e09190911b6001600160e01b031916178255565b6001600160601b0360a01b8154169055847f5ae47664e2cdbd85222ff522486d507f7311952d08dc81781c25973caf6bae126040805160243581526004356020820152a4610b09836123b1565b6111bc57610b1683612236565b5091600183015491610b3063ffffffff8460c01c16612236565b50546044358752600660205260408720549081156111aa5763ffffffff8895875460405193610b5e856120d8565b8585526020850152604084015260a01c1660608201527f000000000000000000000000000000000000000000000000000000000000000060808201527f000000000000000000000000000000000000000000000000000000000000000060a08201523360c0820152604051916020830152602081015160408301526040810151606083015260608101516080830152608081015160a083015260a081015160c083015260c060018060a01b039101511660e082015260e08152610c2081612122565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163b156103b9576020610ca291859385604051968795869463020a49e360e51b86527f0000000000000000000000000000000000000000000000000000000000000000600487015260606024870152606486019061215f565b84810360031901604486015281815292858401378181018401869052601f01601f1916010301817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa801561119f5761118b575b50506003810180546001600160a01b03191633179055600281015460201c60ff16600581101561106c57610d4291906001036111825760026003915b016122c1565b33817f1461dccde4e3f58a9010868dc43563dda5be3676fe5fc59b041ab40bf02944278480a3610d71816123b1565b1561117057610d7f81612236565b5060ff6002610d9a63ffffffff600185015460c01c16612236565b50015460281c16600381101561106c57801561115e5760028201549060ff8260281c16600381101561114a5761113857600203611080575060028101805460ff60281b1916600160291b1790555b6002810154600360ff8260281c16101561106c57602060ff610f1360028695856001857f955589a6b8a11706e02f54c169e85891a5d966197da00abf4ee10c47a6a467809860281c16145f14610fd6575063ffffffff600182015460a01c16610e5c815f52600760205260405f2054151590565b15610fb5575b5063ffffffff600182015460a01c16610e9d7f00000000000000000000000000000000000000000000000000000000000000006005546122b4565b8114610f6e575b506001810154610ec6906001600160a01b0316610ec08361274f565b90612712565b610edb610ed282612698565b610ec083612789565b6404000000008282015463ffffffff610ef3426127c2565b169064ffffffffff19161717918291015560405192839160281c1661219d565ba2604051907f887777ccf43690541bed9e00b10d0fccfa7520b11875f09847a57b3085d8ab928380a2602435815233907f17ae64cc26e10fbe333bdedb0be1a40bcc58d2baf97ba819e4bf4730654a81ec602060043592a380f35b600555867fe0f20f96cb4482a1d3b3a190223cdf2e585de7ee0c659385a90822f6c87c6b056040835463ffffffff600186015460a01c16825191825289820152a25f610ea4565b87610fcf575f19905b8a526007865260408a20555f610e62565b8790610fbe565b82858260281c1614610fe9575b50610edb565b61101b9060301c6001600160a01b03168015611021575b610ec061100c8461274f565b61101585612789565b906122b4565b5f610fe3565b63ffffffff600184015460a01c16611044815f52600760205260405f2054151590565b61104f575b50611000565b61106691506106fc611060916125b1565b50612698565b5f611049565b634e487b7160e01b84526021600452602484fd5b61108982612651565b156110a9575060028101805460ff60281b1916600160291b179055610de8565b6001600160a01b036110ba83612698565b16156110db575060028101805460ff60281b1916600160281b179055610de8565b60ff8160201c1660058110156111245760010361110d575060028101805460ff60281b1916600160291b179055610de8565b60ff60281b1916600160281b176002820155610de8565b634e487b7160e01b85526021600452602485fd5b6040516336ab81e160e11b8152600490fd5b634e487b7160e01b86526021600452602486fd5b604051634962835760e11b8152600490fd5b6040516304643c3960e01b8152600490fd5b60028091610d3c565b611194906120f3565b61069257825f610d00565b6040513d84823e3d90fd5b604051630455475360e31b8152600490fd5b60405163df469ccb60e01b8152600490fd5b634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52604160045260245ffd5b60405163346119f760e01b8152600490fd5b634e487b7160e01b5f52602160045260245ffd5b604051631305dd8760e31b8152600490fd5b604051631a02af9160e21b8152600490fd5b60405163445f4d2560e11b8152600490fd5b60405163ae8b86c760e01b8152600490fd5b5034610248578060031936011261024857546040516001600160a01b039091168152602090f35b50346102485760203660031901126102485760406020916004358152600683522054604051908152f35b50346102485760203660031901126102485760206104de6004356123b1565b50346102485780600319360112610248576112ed6127e5565b5f80546001600160a01b0319811682556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b50602036600319011261024857600435611346816123b1565b6111bc577f000000000000000000000000000000000000000000000000000000000000000034036114595761137a81612236565b50600281019081549160ff8360201c16600581101561114a576114475765ff0100000000600160d01b03199092163360301b6601000000000000600160d01b0316176401000000001790915561141e9060016113f9610a977f0000000000000000000000000000000000000000000000000000000000000000426122b4565b910180546001600160e01b031660e09290921b6001600160e01b031916919091179055565b33907fa431b55c6515e4cbd1f194e8da0750a597fac900c054ac438ca56dc356406fcd8380a380f35b60405163f1082a9360e01b8152600490fd5b604051638620aa1960e01b8152600490fd5b503461024857806003193601126102485760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b50346102485760203660031901126102485760206104de600435612360565b5034610248576020806003193601126103bd576114e06120c2565b6002600154146115915760026001556001600160a01b0381168084526003835260408420549091811561157f578480939281939282938352600387528260408120555af1903d15611579573d906001600160401b0382116111e25783906040519261155482601f19601f840116018561213e565b83523d92013e5b15611567576001805580f35b6040516312171d8360e31b8152600490fd5b5061155b565b604051630c56c38560e21b8152600490fd5b60405162461bcd60e51b815260048101839052601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b503461024857806003193601126102485760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b50346102485760203660031901126102485760206104de600435612318565b503461024857806003193601126102485760405160408101908082106001600160401b038311176111e2576116889160405260058152640312e302e360dc1b602082015260405191829160208352602083019061215f565b0390f35b503461024857806003193601126102485760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b50346102485760203660031901126102485760206104de6116e66120c2565b6122e6565b506060366003190112610248576024356044356004357f0000000000000000000000000000000000000000000000000000000000000000340361145957611731336122e6565b15806118e4575b6118d25760025491828110156111f65761175181612236565b506005548511156112525761176585612508565b42111561124057611781855f52600760205260405f2054151590565b61122e576117bd600182015463ffffffff7f00000000000000000000000000000000000000000000000000000000000000009160a01c166122b4565b850361121c576002015460281c60ff166003811015611208576002146111f657600160401b8310156111e25760018301806002556117fa84612236565b505083116111ce5760209361180e84612236565b50838155600161181d836127c2565b910190815463ffffffff60c01b611833866127c2565b60c01b169163ffffffff60a01b9060a01b16906001600160401b0360a01b191617178155611887610a9c610a977f0000000000000000000000000000000000000000000000000000000000000000426122b4565b336001600160601b0360a01b82541617905560405192835284830152827f5ae47664e2cdbd85222ff522486d507f7311952d08dc81781c25973caf6bae1260403394a4604051908152f35b6040516369c3779f60e11b8152600490fd5b506118f16108ff84612508565b7f00000000000000000000000000000000000000000000000000000000000000001015611738565b503461024857602036600319011261024857600435804080156119715760207f0eed5a702da1b9c67c79a885bef1cc0f342484a8cde755df9a047e5c173c724d9183855260068252806040862055604051908152a280f35b6040516321301a1960e21b8152600490fd5b503461024857806003193601126102485760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b503461024857806003193601126102485760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b5034610248576020366003190112610248576020611a1b6108ff600435612508565b604051907f0000000000000000000000000000000000000000000000000000000000000000108152f35b50346102485780600319360112610248576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5034611d1157600319606036820112611d1157600435906044356001600160401b038111611d1157611ac0903690600401612095565b611acc849392936123b1565b6111bc57611ad984612236565b509160018301549363ffffffff94611af5868260c01c16612236565b5054956024355f526020966006885260405f20549283156111aa57889288549160405191611b22836120d8565b86835285830194855260408301938452606083019160a01c16815260808201907f0000000000000000000000000000000000000000000000000000000000000000825260c060a08401937f00000000000000000000000000000000000000000000000000000000000000008552019333855260018060a01b0395867f00000000000000000000000000000000000000000000000000000000000000001698604051988901525160408801525160608701525160808601525160a08501525160c0840152511660e082015260e08152611bf981612122565b813b15611d115786611c53915f95876040519889978896879563020a49e360e51b87527f0000000000000000000000000000000000000000000000000000000000000000600488015260606024880152606487019061215f565b93858503016044860152818452858401378181018401889052601f01601f1916010301915afa8015611d0657611cf2575b506003810180546001600160a01b03191633179055600201805490911c60ff16600581101561106c57611cc19190600103611cea576003906122c1565b33907f1461dccde4e3f58a9010868dc43563dda5be3676fe5fc59b041ab40bf02944278380a380f35b6002906122c1565b611cfd9194506120f3565b5f926002611c84565b6040513d5f823e3d90fd5b5f80fd5b34611d11576020366003190112611d1157600435611d32816123b1565b1561117057611d4081612236565b50600181019063ffffffff9060ff6002611d5f84865460c01c16612236565b50015460281c1692600384101561120857831561115e57600282019384549060ff8260281c1660038110156112085761113857600203611fc85750835460ff60281b1916600160291b1784555b835460ff8160281c16946003861015611208576404000000008560209560ff95611eb7957f955589a6b8a11706e02f54c169e85891a5d966197da00abf4ee10c47a6a46780998b60018e9d145f14611f3f5750611e7b915091611e8d9392815460a01c16611e25815f52600760205260405f2054151590565b15611f1e575b5084815460a01c16611e606005547f0000000000000000000000000000000000000000000000000000000000000000906122b4565b8114611ede575b50546001600160a01b0316610ec08361274f565b610ec0611e8782612698565b91612789565b825490611e99426127c2565b169064ffffffffff1916171780915560405192839160281c1661219d565ba27f887777ccf43690541bed9e00b10d0fccfa7520b11875f09847a57b3085d8ab925f80a2005b6005558b7fe0f20f96cb4482a1d3b3a190223cdf2e585de7ee0c659385a90822f6c87c6b056040855488855460a01c1682519182528e820152a28d611e67565b8c611f38575f19905b5f5260078b5260405f20558d611e2b565b8c90611f27565b919391600214611f53575b50505050611e8d565b611f7d9360301c6001600160a01b0316928315611f86575b505080611015611e87610ec09361274f565b89808083611f4a565b5460a01c16611fa0815f52600760205260405f2054151590565b611fac575b8490611f6b565b610ec09192506110606106fc611fc1926125b1565b9190611fa5565b611fd183612651565b15611fed5750835460ff60281b1916600160291b178455611dac565b6001600160a01b03611ffe84612698565b161561201b5750835460ff60281b1916600160281b178455611dac565b60ff8160201c166005811015611208576001036120495750835460ff60281b1916600160291b178455611dac565b60ff60281b1916600160281b178455611dac565b34611d11575f366003190112611d11576020907f00000000000000000000000000000000000000000000000000000000000000008152f35b9181601f84011215611d11578235916001600160401b038311611d115760208381860195010111611d1157565b600435906001600160a01b0382168203611d1157565b60e081019081106001600160401b038211176111e257604052565b6001600160401b0381116111e257604052565b61014081019081106001600160401b038211176111e257604052565b61010081019081106001600160401b038211176111e257604052565b90601f801991011681019081106001600160401b038211176111e257604052565b91908251928382525f5b848110612189575050825f602080949584010152601f8019910116010190565b602081830181015184830182015201612169565b9060038210156112085752565b80518252602081015160018060a01b038091166020840152604082015163ffffffff809116604085015280606084015116606085015280608084015116608085015260a08301511660a084015260c082015160058110156112085760c084015261221c60e083015160e085019061219d565b610100818184015116908401526101208092015116910152565b60025481101561226e5760025f5260021b7f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace01905f90565b634e487b7160e01b5f52603260045260245ffd5b6002541561226e5760025f527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace905f90565b919082018092116111ce57565b9060058110156112085764ff0000000082549160201b169064ff000000001916179055565b6001600160a01b03165f9081526004602052604090205460ff1680156123095790565b505f805260ff60405f20541690565b60025481101561235b5761232b816123b1565b159081612336575090565b60ff9150612345600291612236565b50015460201c1660058110156112085760011490565b505f90565b60025481101561235b5763ffffffff600161237a83612236565b50015460a01c1690612397825f52600760205260405f2054151590565b91826123a257505090565b6123ad9192506125b1565b1490565b6123ba90612236565b506001810154428160e01c109182156123fc575b5081156123d9575090565b6123f9915063ffffffff9060a01c165f52600760205260405f2054151590565b90565b600301546001600160a01b0316151591505f6123ce565b919082039182116111ce57565b6040519061242d82612106565b5f610120838281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152826101008201520152565b9060405161247781612106565b809280548252600181015460018060a01b0390818116602085015263ffffffff90818160a01c166040860152818160c01c16606086015260e01c6080850152600283015490811660a085015260ff8160201c1660058110156112085760c085015260ff8160281c1692600384101561120857826003926101209560e088015260301c16610100860152015416910152565b600190612513612282565b5063ffffffff928391015460a01c16811061259f57612543916001612536612282565b50015460a01c1690612413565b7f0000000000000000000000000000000000000000000000000000000000000000908181029181830414901517156111ce576123f9907f00000000000000000000000000000000000000000000000000000000000000006122b4565b6040516335ca043360e21b8152600490fd5b6125c6815f52600760205260405f2054151590565b15610795575f52600760205260405f20545f1981145f146123f957505f90565b6001600160401b0381116111e25760051b60200190565b805182101561226e5760209160051b010190565b60025481101561235b5761262e61262782612236565b50916123b1565b9081612638575090565b60ff91506002015460281c166003811015611208571590565b63ffffffff600182015460a01c1690612675825f52600760205260405f2054151590565b918261268057505090565b61268f9192506106fc906125b1565b50549054141590565b6126a181612651565b61235b5760038101546001600160a01b03919082168061270c57506001015460a01c63ffffffff165f818152600760205260409020546126e15750505f90565b6106fc6126ed916125b1565b50600381015482169190821561270257505090565b6001015416919050565b91505090565b6001600160a01b031680151580612746575b61272c575050565b5f52600360205261274260405f209182546122b4565b9055565b50811515612724565b600101546001600160a01b031615612785577f000000000000000000000000000000000000000000000000000000000000000090565b5f90565b6002015460301c6001600160a01b031615612785577f000000000000000000000000000000000000000000000000000000000000000090565b6401000000008110156127d85763ffffffff1690565b6335278d125f526004601cfd5b5f546001600160a01b031633036127f857565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fdfea2646970667358221220b490a6f2b6e9eb7d444f0609f403ae096d02561fcf015348735ca508bdc0382b64736f6c634300081800330000000000000000000000000000000000000000000000000000000000093a800000000000000000000000000000000000000000000000000000000000093a800000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000070888b54f3a73b2cbb7f29caae53a780a8b4974c5e0bd157ad3c7bb122b72939bcc00000000000000000000000000000000000000000000000000000000001a43ac0000000000000000000000000000000000000000000000000000000068938a4b000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000070c7fdb9e543bd15cd392df04e6d4bd05afd8a669554c3fe04d8bd05d2dff01471781e1d9fbbdcfa58bda686ad883fe5451fd97c0083a8b50160475a7a5911c03dfdee30f6c8a83112a71c5c1125cfb96148b8c243f01f7522e77ddc0bea30de6cb8075608a0d0c906660e4f5f430a1e5e170829

Deployed Bytecode

0x6080806040526004361015610012575f80fd5b5f905f3560e01c9081622134cc1461205d5750806262804e14611d1557806275552a14611a8a57806308c84e7014611a455780631c1d5335146119f95780631ef7a1f7146119be5780632a6375da146119835780633522f0101461191957806345925013146116eb57806347cc2f3d146116c75780634cc4f2b61461168c57806354fd4d50146116305780635872bbed146116115780635da1f255146115d657806360e27464146114c55780636338049b146114a657806365e1dfa41461146b5780636c541de11461132d578063715018a6146112d457806385f9ce72146112b55780638d7a1d5f1461128b5780638da5cb5b146112645780639eeeb21414610905578063a703800d146108dd578063b3debd42146108a2578063b6a82c4c14610884578063bb825afc14610849578063bc378a731461082b578063c7f758a8146107ff578063d1de856c146107e0578063d5d44d80146107a7578063d7a0df791461073c578063d83ef2671461070b578063db3aa5d0146106db578063dc26de6f146106bd578063dd843d5614610696578063e9ed9b6414610613578063eca77cd614610523578063ed6892ed146104e8578063eea128fd146104bf578063f2fde38b146103fc578063f584be7b146103c1578063f5f3bf2314610286578063f7c736d01461024b5763f8315bc21461020a575f80fd5b346102485760203660031901126102485760209060ff906040906001600160a01b036102346120c2565b168152600484522054166040519015158152f35b80fd5b503461024857806003193601126102485760206040517f00000000000000000000000000000000000000000000000000000000000007088152f35b5034610248576020806003193601126103bd57600435916001600160401b038084116103bd57366023850112156103bd5783600401359081116103bd5760246005943660248460051b830101116103b9576102e3839694966125e6565b936102f1604051958661213e565b8385526102fd846125e6565b601f1901875b81811061039d575050865b84811061035f57604080518881528751818a01819052888a01928201908a8c5b82811061033b5784840385f35b90919282610140826103506001948a516121aa565b0196019101949291909461032e565b8061037e61037886600194869c9a9c1b87010135612236565b5061246a565b610388828b6125fd565b52610393818a6125fd565b500196949661030e565b87906103aa999799612420565b82828c01015201979597610303565b8380fd5b5080fd5b503461024857806003193601126102485760206040517f00000000000000000000000000000000000000000000000000000000001275008152f35b5034610248576020366003190112610248576104166120c2565b61041e6127e5565b6001600160a01b0390811690811561046b575f54826001600160601b0360a01b8216175f55167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a380f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b50346102485760203660031901126102485760206104de600435612611565b6040519015158152f35b503461024857806003193601126102485760206040517f43f01f7522e77ddc0bea30de6cb8075608a0d0c906660e4f5f430a1e5e1708298152f35b5034610248576020806003193601126103bd576002546004359181831161060a575b919092610551826125e6565b9361055f604051958661213e565b82855261056b836125e6565b8585019390601f19013685375f198201918211835b8281106105c9575050505060405193838594850191818652518092526040850193925b8281106105b257505050500390f35b8351855286955093810193928101926001016105a3565b8197959694976105f657806105e060019286612413565b6105ea82896125fd565b52019693959496610580565b634e487b7160e01b88526011600452602488fd5b91508091610545565b50346102485760403660031901126102485761062d6120c2565b602435908115158092036106925760207f205b4586f0aad63e3849b0c69893bd6139aca673e7f16088c504691c6502cee4916106676127e5565b6001600160a01b0316808552600482526040808620805460ff191660ff87161790555193845292a280f35b8280fd5b50346102485760203660031901126102485760206106b56004356125b1565b604051908152f35b50346102485780600319360112610248576020600554604051908152f35b503461024857806003193601126102485760206107016106fc6005546125b1565b612236565b5054604051908152f35b5034610248578060031936011261024857604060055461072d6106fc826125b1565b50549082519182526020820152f35b503461024857602036600319011261024857600435610759612420565b5061076f815f52600760205260405f2054151590565b15610795576107866103786106fc610140936125b1565b61079360405180926121aa565bf35b604051638988695560e01b8152600490fd5b5034610248576020366003190112610248576020906040906001600160a01b036107cf6120c2565b168152600383522054604051908152f35b50346102485760203660031901126102485760206106b5600435612508565b503461024857602036600319011261024857610819612420565b50610140610786610378600435612236565b50346102485780600319360112610248576020600254604051908152f35b503461024857806003193601126102485760206040517f0000000000000000000000000000000000000000000000008ac7230489e800008152f35b503461024857806003193601126102485760206106b56005546125b1565b503461024857806003193601126102485760206040517f0000000000000000000000000000000000000000000000000000000068938a4b8152f35b50346102485760203660031901126102485760206106b56108ff600435612508565b42612413565b5034610248576080366003190112610248576064356001600160401b0381116103bd57610936903690600401612095565b60055491610943836125b1565b60025493848210156111f65761095882612236565b509060043511156112525761096e600435612508565b4211156112405761098c6004355f52600760205260405f2054151590565b61122e576109c8600182015463ffffffff7f00000000000000000000000000000000000000000000000000000000000007089160a01c166122b4565b6004350361121c576002015460281c60ff166003811015611208576002146111f657600160401b8410156111e2576001840180600255610a0785612236565b505084116111ce575f90610a1a85612236565b5060243581556001610a2d6004356127c2565b910190815463ffffffff60c01b610a43856127c2565b60c01b169163ffffffff60a01b9060a01b16906001600160401b0360a01b191617178155610abc610a9c610a977f0000000000000000000000000000000000000000000000000000000000093a80426122b4565b6127c2565b82546001600160e01b031660e09190911b6001600160e01b031916178255565b6001600160601b0360a01b8154169055847f5ae47664e2cdbd85222ff522486d507f7311952d08dc81781c25973caf6bae126040805160243581526004356020820152a4610b09836123b1565b6111bc57610b1683612236565b5091600183015491610b3063ffffffff8460c01c16612236565b50546044358752600660205260408720549081156111aa5763ffffffff8895875460405193610b5e856120d8565b8585526020850152604084015260a01c1660608201527f9554c3fe04d8bd05d2dff01471781e1d9fbbdcfa58bda686ad883fe5451fd97c60808201527f43f01f7522e77ddc0bea30de6cb8075608a0d0c906660e4f5f430a1e5e17082960a08201523360c0820152604051916020830152602081015160408301526040810151606083015260608101516080830152608081015160a083015260a081015160c083015260c060018060a01b039101511660e082015260e08152610c2081612122565b7f00000000000000000000000070c7fdb9e543bd15cd392df04e6d4bd05afd8a666001600160a01b03163b156103b9576020610ca291859385604051968795869463020a49e360e51b86527f0083a8b50160475a7a5911c03dfdee30f6c8a83112a71c5c1125cfb96148b8c2600487015260606024870152606486019061215f565b84810360031901604486015281815292858401378181018401869052601f01601f1916010301817f00000000000000000000000070c7fdb9e543bd15cd392df04e6d4bd05afd8a666001600160a01b03165afa801561119f5761118b575b50506003810180546001600160a01b03191633179055600281015460201c60ff16600581101561106c57610d4291906001036111825760026003915b016122c1565b33817f1461dccde4e3f58a9010868dc43563dda5be3676fe5fc59b041ab40bf02944278480a3610d71816123b1565b1561117057610d7f81612236565b5060ff6002610d9a63ffffffff600185015460c01c16612236565b50015460281c16600381101561106c57801561115e5760028201549060ff8260281c16600381101561114a5761113857600203611080575060028101805460ff60281b1916600160291b1790555b6002810154600360ff8260281c16101561106c57602060ff610f1360028695856001857f955589a6b8a11706e02f54c169e85891a5d966197da00abf4ee10c47a6a467809860281c16145f14610fd6575063ffffffff600182015460a01c16610e5c815f52600760205260405f2054151590565b15610fb5575b5063ffffffff600182015460a01c16610e9d7f00000000000000000000000000000000000000000000000000000000000007086005546122b4565b8114610f6e575b506001810154610ec6906001600160a01b0316610ec08361274f565b90612712565b610edb610ed282612698565b610ec083612789565b6404000000008282015463ffffffff610ef3426127c2565b169064ffffffffff19161717918291015560405192839160281c1661219d565ba2604051907f887777ccf43690541bed9e00b10d0fccfa7520b11875f09847a57b3085d8ab928380a2602435815233907f17ae64cc26e10fbe333bdedb0be1a40bcc58d2baf97ba819e4bf4730654a81ec602060043592a380f35b600555867fe0f20f96cb4482a1d3b3a190223cdf2e585de7ee0c659385a90822f6c87c6b056040835463ffffffff600186015460a01c16825191825289820152a25f610ea4565b87610fcf575f19905b8a526007865260408a20555f610e62565b8790610fbe565b82858260281c1614610fe9575b50610edb565b61101b9060301c6001600160a01b03168015611021575b610ec061100c8461274f565b61101585612789565b906122b4565b5f610fe3565b63ffffffff600184015460a01c16611044815f52600760205260405f2054151590565b61104f575b50611000565b61106691506106fc611060916125b1565b50612698565b5f611049565b634e487b7160e01b84526021600452602484fd5b61108982612651565b156110a9575060028101805460ff60281b1916600160291b179055610de8565b6001600160a01b036110ba83612698565b16156110db575060028101805460ff60281b1916600160281b179055610de8565b60ff8160201c1660058110156111245760010361110d575060028101805460ff60281b1916600160291b179055610de8565b60ff60281b1916600160281b176002820155610de8565b634e487b7160e01b85526021600452602485fd5b6040516336ab81e160e11b8152600490fd5b634e487b7160e01b86526021600452602486fd5b604051634962835760e11b8152600490fd5b6040516304643c3960e01b8152600490fd5b60028091610d3c565b611194906120f3565b61069257825f610d00565b6040513d84823e3d90fd5b604051630455475360e31b8152600490fd5b60405163df469ccb60e01b8152600490fd5b634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52604160045260245ffd5b60405163346119f760e01b8152600490fd5b634e487b7160e01b5f52602160045260245ffd5b604051631305dd8760e31b8152600490fd5b604051631a02af9160e21b8152600490fd5b60405163445f4d2560e11b8152600490fd5b60405163ae8b86c760e01b8152600490fd5b5034610248578060031936011261024857546040516001600160a01b039091168152602090f35b50346102485760203660031901126102485760406020916004358152600683522054604051908152f35b50346102485760203660031901126102485760206104de6004356123b1565b50346102485780600319360112610248576112ed6127e5565b5f80546001600160a01b0319811682556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b50602036600319011261024857600435611346816123b1565b6111bc577f0000000000000000000000000000000000000000000000008ac7230489e8000034036114595761137a81612236565b50600281019081549160ff8360201c16600581101561114a576114475765ff0100000000600160d01b03199092163360301b6601000000000000600160d01b0316176401000000001790915561141e9060016113f9610a977f0000000000000000000000000000000000000000000000000000000000093a80426122b4565b910180546001600160e01b031660e09290921b6001600160e01b031916919091179055565b33907fa431b55c6515e4cbd1f194e8da0750a597fac900c054ac438ca56dc356406fcd8380a380f35b60405163f1082a9360e01b8152600490fd5b604051638620aa1960e01b8152600490fd5b503461024857806003193601126102485760206040517f0083a8b50160475a7a5911c03dfdee30f6c8a83112a71c5c1125cfb96148b8c28152f35b50346102485760203660031901126102485760206104de600435612360565b5034610248576020806003193601126103bd576114e06120c2565b6002600154146115915760026001556001600160a01b0381168084526003835260408420549091811561157f578480939281939282938352600387528260408120555af1903d15611579573d906001600160401b0382116111e25783906040519261155482601f19601f840116018561213e565b83523d92013e5b15611567576001805580f35b6040516312171d8360e31b8152600490fd5b5061155b565b604051630c56c38560e21b8152600490fd5b60405162461bcd60e51b815260048101839052601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b503461024857806003193601126102485760206040517f0000000000000000000000000000000000000000000000000000000000093a808152f35b50346102485760203660031901126102485760206104de600435612318565b503461024857806003193601126102485760405160408101908082106001600160401b038311176111e2576116889160405260058152640312e302e360dc1b602082015260405191829160208352602083019061215f565b0390f35b503461024857806003193601126102485760206040517f0000000000000000000000000000000000000000000000000000000000093a808152f35b50346102485760203660031901126102485760206104de6116e66120c2565b6122e6565b506060366003190112610248576024356044356004357f0000000000000000000000000000000000000000000000000011c37937e08000340361145957611731336122e6565b15806118e4575b6118d25760025491828110156111f65761175181612236565b506005548511156112525761176585612508565b42111561124057611781855f52600760205260405f2054151590565b61122e576117bd600182015463ffffffff7f00000000000000000000000000000000000000000000000000000000000007089160a01c166122b4565b850361121c576002015460281c60ff166003811015611208576002146111f657600160401b8310156111e25760018301806002556117fa84612236565b505083116111ce5760209361180e84612236565b50838155600161181d836127c2565b910190815463ffffffff60c01b611833866127c2565b60c01b169163ffffffff60a01b9060a01b16906001600160401b0360a01b191617178155611887610a9c610a977f0000000000000000000000000000000000000000000000000000000000093a80426122b4565b336001600160601b0360a01b82541617905560405192835284830152827f5ae47664e2cdbd85222ff522486d507f7311952d08dc81781c25973caf6bae1260403394a4604051908152f35b6040516369c3779f60e11b8152600490fd5b506118f16108ff84612508565b7f00000000000000000000000000000000000000000000000000000000001275001015611738565b503461024857602036600319011261024857600435804080156119715760207f0eed5a702da1b9c67c79a885bef1cc0f342484a8cde755df9a047e5c173c724d9183855260068252806040862055604051908152a280f35b6040516321301a1960e21b8152600490fd5b503461024857806003193601126102485760206040517f9554c3fe04d8bd05d2dff01471781e1d9fbbdcfa58bda686ad883fe5451fd97c8152f35b503461024857806003193601126102485760206040517f0000000000000000000000000000000000000000000000000011c37937e080008152f35b5034610248576020366003190112610248576020611a1b6108ff600435612508565b604051907f0000000000000000000000000000000000000000000000000000000000127500108152f35b50346102485780600319360112610248576040517f00000000000000000000000070c7fdb9e543bd15cd392df04e6d4bd05afd8a666001600160a01b03168152602090f35b5034611d1157600319606036820112611d1157600435906044356001600160401b038111611d1157611ac0903690600401612095565b611acc849392936123b1565b6111bc57611ad984612236565b509160018301549363ffffffff94611af5868260c01c16612236565b5054956024355f526020966006885260405f20549283156111aa57889288549160405191611b22836120d8565b86835285830194855260408301938452606083019160a01c16815260808201907f9554c3fe04d8bd05d2dff01471781e1d9fbbdcfa58bda686ad883fe5451fd97c825260c060a08401937f43f01f7522e77ddc0bea30de6cb8075608a0d0c906660e4f5f430a1e5e1708298552019333855260018060a01b0395867f00000000000000000000000070c7fdb9e543bd15cd392df04e6d4bd05afd8a661698604051988901525160408801525160608701525160808601525160a08501525160c0840152511660e082015260e08152611bf981612122565b813b15611d115786611c53915f95876040519889978896879563020a49e360e51b87527f0083a8b50160475a7a5911c03dfdee30f6c8a83112a71c5c1125cfb96148b8c2600488015260606024880152606487019061215f565b93858503016044860152818452858401378181018401889052601f01601f1916010301915afa8015611d0657611cf2575b506003810180546001600160a01b03191633179055600201805490911c60ff16600581101561106c57611cc19190600103611cea576003906122c1565b33907f1461dccde4e3f58a9010868dc43563dda5be3676fe5fc59b041ab40bf02944278380a380f35b6002906122c1565b611cfd9194506120f3565b5f926002611c84565b6040513d5f823e3d90fd5b5f80fd5b34611d11576020366003190112611d1157600435611d32816123b1565b1561117057611d4081612236565b50600181019063ffffffff9060ff6002611d5f84865460c01c16612236565b50015460281c1692600384101561120857831561115e57600282019384549060ff8260281c1660038110156112085761113857600203611fc85750835460ff60281b1916600160291b1784555b835460ff8160281c16946003861015611208576404000000008560209560ff95611eb7957f955589a6b8a11706e02f54c169e85891a5d966197da00abf4ee10c47a6a46780998b60018e9d145f14611f3f5750611e7b915091611e8d9392815460a01c16611e25815f52600760205260405f2054151590565b15611f1e575b5084815460a01c16611e606005547f0000000000000000000000000000000000000000000000000000000000000708906122b4565b8114611ede575b50546001600160a01b0316610ec08361274f565b610ec0611e8782612698565b91612789565b825490611e99426127c2565b169064ffffffffff1916171780915560405192839160281c1661219d565ba27f887777ccf43690541bed9e00b10d0fccfa7520b11875f09847a57b3085d8ab925f80a2005b6005558b7fe0f20f96cb4482a1d3b3a190223cdf2e585de7ee0c659385a90822f6c87c6b056040855488855460a01c1682519182528e820152a28d611e67565b8c611f38575f19905b5f5260078b5260405f20558d611e2b565b8c90611f27565b919391600214611f53575b50505050611e8d565b611f7d9360301c6001600160a01b0316928315611f86575b505080611015611e87610ec09361274f565b89808083611f4a565b5460a01c16611fa0815f52600760205260405f2054151590565b611fac575b8490611f6b565b610ec09192506110606106fc611fc1926125b1565b9190611fa5565b611fd183612651565b15611fed5750835460ff60281b1916600160291b178455611dac565b6001600160a01b03611ffe84612698565b161561201b5750835460ff60281b1916600160281b178455611dac565b60ff8160201c166005811015611208576001036120495750835460ff60281b1916600160291b178455611dac565b60ff60281b1916600160281b178455611dac565b34611d11575f366003190112611d11576020907f000000000000000000000000000000000000000000000000000000000000000c8152f35b9181601f84011215611d11578235916001600160401b038311611d115760208381860195010111611d1157565b600435906001600160a01b0382168203611d1157565b60e081019081106001600160401b038211176111e257604052565b6001600160401b0381116111e257604052565b61014081019081106001600160401b038211176111e257604052565b61010081019081106001600160401b038211176111e257604052565b90601f801991011681019081106001600160401b038211176111e257604052565b91908251928382525f5b848110612189575050825f602080949584010152601f8019910116010190565b602081830181015184830182015201612169565b9060038210156112085752565b80518252602081015160018060a01b038091166020840152604082015163ffffffff809116604085015280606084015116606085015280608084015116608085015260a08301511660a084015260c082015160058110156112085760c084015261221c60e083015160e085019061219d565b610100818184015116908401526101208092015116910152565b60025481101561226e5760025f5260021b7f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace01905f90565b634e487b7160e01b5f52603260045260245ffd5b6002541561226e5760025f527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace905f90565b919082018092116111ce57565b9060058110156112085764ff0000000082549160201b169064ff000000001916179055565b6001600160a01b03165f9081526004602052604090205460ff1680156123095790565b505f805260ff60405f20541690565b60025481101561235b5761232b816123b1565b159081612336575090565b60ff9150612345600291612236565b50015460201c1660058110156112085760011490565b505f90565b60025481101561235b5763ffffffff600161237a83612236565b50015460a01c1690612397825f52600760205260405f2054151590565b91826123a257505090565b6123ad9192506125b1565b1490565b6123ba90612236565b506001810154428160e01c109182156123fc575b5081156123d9575090565b6123f9915063ffffffff9060a01c165f52600760205260405f2054151590565b90565b600301546001600160a01b0316151591505f6123ce565b919082039182116111ce57565b6040519061242d82612106565b5f610120838281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152826101008201520152565b9060405161247781612106565b809280548252600181015460018060a01b0390818116602085015263ffffffff90818160a01c166040860152818160c01c16606086015260e01c6080850152600283015490811660a085015260ff8160201c1660058110156112085760c085015260ff8160281c1692600384101561120857826003926101209560e088015260301c16610100860152015416910152565b600190612513612282565b5063ffffffff928391015460a01c16811061259f57612543916001612536612282565b50015460a01c1690612413565b7f000000000000000000000000000000000000000000000000000000000000000c908181029181830414901517156111ce576123f9907f0000000000000000000000000000000000000000000000000000000068938a4b6122b4565b6040516335ca043360e21b8152600490fd5b6125c6815f52600760205260405f2054151590565b15610795575f52600760205260405f20545f1981145f146123f957505f90565b6001600160401b0381116111e25760051b60200190565b805182101561226e5760209160051b010190565b60025481101561235b5761262e61262782612236565b50916123b1565b9081612638575090565b60ff91506002015460281c166003811015611208571590565b63ffffffff600182015460a01c1690612675825f52600760205260405f2054151590565b918261268057505090565b61268f9192506106fc906125b1565b50549054141590565b6126a181612651565b61235b5760038101546001600160a01b03919082168061270c57506001015460a01c63ffffffff165f818152600760205260409020546126e15750505f90565b6106fc6126ed916125b1565b50600381015482169190821561270257505090565b6001015416919050565b91505090565b6001600160a01b031680151580612746575b61272c575050565b5f52600360205261274260405f209182546122b4565b9055565b50811515612724565b600101546001600160a01b031615612785577f0000000000000000000000000000000000000000000000000011c37937e0800090565b5f90565b6002015460301c6001600160a01b031615612785577f0000000000000000000000000000000000000000000000008ac7230489e8000090565b6401000000008110156127d85763ffffffff1690565b6335278d125f526004601cfd5b5f546001600160a01b031633036127f857565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fdfea2646970667358221220b490a6f2b6e9eb7d444f0609f403ae096d02561fcf015348735ca508bdc0382b64736f6c63430008180033

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.