Sepolia Testnet

Contract

0x236FD1A6D9871b1D3f21646781129d4fbC321728

Overview

ETH Balance

0 ETH

Multichain Info

N/A
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Advanced mode:
Parent Transaction Hash Block From To
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FaultDisputeGame

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 999999 runs

Other Settings:
london EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 15 : FaultDisputeGame.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol";
import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol";
import { IInitializable } from "src/dispute/interfaces/IInitializable.sol";
import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol";

import { Clone } from "src/libraries/Clone.sol";
import { Types } from "src/libraries/Types.sol";
import { ISemver } from "src/universal/ISemver.sol";
import { LibClock } from "src/dispute/lib/LibUDT.sol";

import "src/libraries/DisputeTypes.sol";
import "src/libraries/DisputeErrors.sol";

/// @title FaultDisputeGame
/// @notice An implementation of the `IFaultDisputeGame` interface.
contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
    ////////////////////////////////////////////////////////////////
    //                         State Vars                         //
    ////////////////////////////////////////////////////////////////

    /// @notice The absolute prestate of the instruction trace. This is a constant that is defined
    ///         by the program that is being used to execute the trace.
    Claim internal immutable ABSOLUTE_PRESTATE;

    /// @notice The max depth of the game.
    uint256 internal immutable MAX_GAME_DEPTH;

    /// @notice The max depth of the output bisection portion of the position tree. Immediately beneath
    ///         this depth, execution trace bisection begins.
    uint256 internal immutable SPLIT_DEPTH;

    /// @notice The duration of the game.
    Duration internal immutable GAME_DURATION;

    /// @notice An onchain VM that performs single instruction steps on a fault proof program trace.
    IBigStepper internal immutable VM;

    /// @notice The genesis block number
    uint256 internal immutable GENESIS_BLOCK_NUMBER;

    /// @notice The genesis output root
    Hash internal immutable GENESIS_OUTPUT_ROOT;

    /// @notice The game type ID
    GameType internal immutable GAME_TYPE;

    /// @notice The global root claim's position is always at gindex 1.
    Position internal constant ROOT_POSITION = Position.wrap(1);

    /// @notice The starting timestamp of the game
    Timestamp public createdAt;

    /// @notice The timestamp of the game's global resolution.
    Timestamp public resolvedAt;

    /// @inheritdoc IDisputeGame
    GameStatus public status;

    /// @inheritdoc IFaultDisputeGame
    Hash public l1Head;

    /// @notice An append-only array of all claims made during the dispute game.
    ClaimData[] public claimData;

    /// @notice Credited balances for winning participants.
    mapping(address => uint256) public credit;

    /// @notice An internal mapping to allow for constant-time lookups of existing claims.
    mapping(ClaimHash => bool) internal claims;

    /// @notice An internal mapping of subgames rooted at a claim index to other claim indices in the subgame.
    mapping(uint256 => uint256[]) internal subgames;

    /// @notice Indicates whether the subgame rooted at the root claim has been resolved.
    bool internal subgameAtRootResolved;

    /// @notice Flag for the `initialize` function to prevent re-initialization.
    bool internal initialized;

    /// @notice Semantic version.
    /// @custom:semver 0.0.24
    string public constant version = "0.0.24";

    /// @param _gameType The type ID of the game.
    /// @param _absolutePrestate The absolute prestate of the instruction trace.
    /// @param _genesisBlockNumber The block number of the genesis block.
    /// @param _genesisOutputRoot The output root of the genesis block.
    /// @param _maxGameDepth The maximum depth of bisection.
    /// @param _splitDepth The final depth of the output bisection portion of the game.
    /// @param _gameDuration The duration of the game.
    /// @param _vm An onchain VM that performs single instruction steps on a fault proof program
    ///            trace.
    constructor(
        GameType _gameType,
        Claim _absolutePrestate,
        uint256 _genesisBlockNumber,
        Hash _genesisOutputRoot,
        uint256 _maxGameDepth,
        uint256 _splitDepth,
        Duration _gameDuration,
        IBigStepper _vm
    ) {
        // The split depth cannot be greater than or equal to the max game depth.
        if (_splitDepth >= _maxGameDepth) revert InvalidSplitDepth();

        GAME_TYPE = _gameType;
        ABSOLUTE_PRESTATE = _absolutePrestate;
        GENESIS_BLOCK_NUMBER = _genesisBlockNumber;
        GENESIS_OUTPUT_ROOT = _genesisOutputRoot;
        MAX_GAME_DEPTH = _maxGameDepth;
        SPLIT_DEPTH = _splitDepth;
        GAME_DURATION = _gameDuration;
        VM = _vm;
    }

    ////////////////////////////////////////////////////////////////
    //                  `IFaultDisputeGame` impl                  //
    ////////////////////////////////////////////////////////////////

    /// @inheritdoc IFaultDisputeGame
    function step(uint256 _claimIndex, bool _isAttack, bytes calldata _stateData, bytes calldata _proof) external {
        // INVARIANT: Steps cannot be made unless the game is currently in progress.
        if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();

        // Get the parent. If it does not exist, the call will revert with OOB.
        ClaimData storage parent = claimData[_claimIndex];

        // Pull the parent position out of storage.
        Position parentPos = parent.position;
        // Determine the position of the step.
        Position stepPos = parentPos.move(_isAttack);

        // INVARIANT: A step cannot be made unless the move position is 1 below the `MAX_GAME_DEPTH`
        if (stepPos.depth() != MAX_GAME_DEPTH + 1) revert InvalidParent();

        // Determine the expected pre & post states of the step.
        Claim preStateClaim;
        ClaimData storage postState;
        if (_isAttack) {
            // If the step position's index at depth is 0, the prestate is the absolute
            // prestate.
            // If the step is an attack at a trace index > 0, the prestate exists elsewhere in
            // the game state.
            // NOTE: We localize the `indexAtDepth` for the current execution trace subgame by finding
            //       the remainder of the index at depth divided by 2 ** (MAX_GAME_DEPTH - SPLIT_DEPTH),
            //       which is the number of leaves in each execution trace subgame. This is so that we can
            //       determine whether or not the step position is represents the `ABSOLUTE_PRESTATE`.
            preStateClaim = (stepPos.indexAtDepth() % (1 << (MAX_GAME_DEPTH - SPLIT_DEPTH))) == 0
                ? ABSOLUTE_PRESTATE
                : _findTraceAncestor(Position.wrap(parentPos.raw() - 1), parent.parentIndex, false).claim;
            // For all attacks, the poststate is the parent claim.
            postState = parent;
        } else {
            // If the step is a defense, the poststate exists elsewhere in the game state,
            // and the parent claim is the expected pre-state.
            preStateClaim = parent.claim;
            postState = _findTraceAncestor(Position.wrap(parentPos.raw() + 1), parent.parentIndex, false);
        }

        // INVARIANT: The prestate is always invalid if the passed `_stateData` is not the
        //            preimage of the prestate claim hash.
        //            We ignore the highest order byte of the digest because it is used to
        //            indicate the VM Status and is added after the digest is computed.
        if (keccak256(_stateData) << 8 != preStateClaim.raw() << 8) revert InvalidPrestate();

        // Compute the local preimage context for the step.
        Hash uuid = _findLocalContext(_claimIndex);

        // INVARIANT: If a step is an attack, the poststate is valid if the step produces
        //            the same poststate hash as the parent claim's value.
        //            If a step is a defense:
        //              1. If the parent claim and the found post state agree with each other
        //                 (depth diff % 2 == 0), the step is valid if it produces the same
        //                 state hash as the post state's claim.
        //              2. If the parent claim and the found post state disagree with each other
        //                 (depth diff % 2 != 0), the parent cannot be countered unless the step
        //                 produces the same state hash as `postState.claim`.
        // SAFETY:    While the `attack` path does not need an extra check for the post
        //            state's depth in relation to the parent, we don't need another
        //            branch because (n - n) % 2 == 0.
        bool validStep = VM.step(_stateData, _proof, uuid.raw()) == postState.claim.raw();
        bool parentPostAgree = (parentPos.depth() - postState.position.depth()) % 2 == 0;
        if (parentPostAgree == validStep) revert ValidStep();

        // Set the parent claim as countered. We do not need to append a new claim to the game;
        // instead, we can just set the existing parent as countered.
        parent.counteredBy = msg.sender;
    }

    /// @notice Generic move function, used for both `attack` and `defend` moves.
    /// @param _challengeIndex The index of the claim being moved against.
    /// @param _claim The claim at the next logical position in the game.
    /// @param _isAttack Whether or not the move is an attack or defense.
    function move(uint256 _challengeIndex, Claim _claim, bool _isAttack) public payable {
        // INVARIANT: Moves cannot be made unless the game is currently in progress.
        if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();

        // Get the parent. If it does not exist, the call will revert with OOB.
        ClaimData memory parent = claimData[_challengeIndex];

        // Compute the position that the claim commits to. Because the parent's position is already
        // known, we can compute the next position by moving left or right depending on whether
        // or not the move is an attack or defense.
        Position parentPos = parent.position;
        Position nextPosition = parentPos.move(_isAttack);
        uint256 nextPositionDepth = nextPosition.depth();

        // INVARIANT: A defense can never be made against the root claim of either the output root game or any
        //            of the execution trace bisection subgames. This is because the root claim commits to the
        //            entire state. Therefore, the only valid defense is to do nothing if it is agreed with.
        if ((_challengeIndex == 0 || nextPositionDepth == SPLIT_DEPTH + 2) && !_isAttack) {
            revert CannotDefendRootClaim();
        }

        // INVARIANT: A move can never surpass the `MAX_GAME_DEPTH`. The only option to counter a
        //            claim at this depth is to perform a single instruction step on-chain via
        //            the `step` function to prove that the state transition produces an unexpected
        //            post-state.
        if (nextPositionDepth > MAX_GAME_DEPTH) revert GameDepthExceeded();

        // When the next position surpasses the split depth (i.e., it is the root claim of an execution
        // trace bisection sub-game), we need to perform some extra verification steps.
        if (nextPositionDepth == SPLIT_DEPTH + 1) {
            _verifyExecBisectionRoot(_claim, _challengeIndex, parentPos, _isAttack);
        }

        // INVARIANT: The `msg.value` must be sufficient to cover the required bond.
        if (getRequiredBond(nextPosition) > msg.value) revert InsufficientBond();

        // Fetch the grandparent clock, if it exists.
        // The grandparent clock should always exist unless the parent is the root claim.
        Clock grandparentClock;
        if (parent.parentIndex != type(uint32).max) {
            grandparentClock = claimData[parent.parentIndex].clock;
        }

        // Compute the duration of the next clock. This is done by adding the duration of the
        // grandparent claim to the difference between the current block timestamp and the
        // parent's clock timestamp.
        Duration nextDuration = Duration.wrap(
            uint64(
                // First, fetch the duration of the grandparent claim.
                grandparentClock.duration().raw()
                // Second, add the difference between the current block timestamp and the
                // parent's clock timestamp.
                + block.timestamp - parent.clock.timestamp().raw()
            )
        );

        // INVARIANT: A move can never be made once its clock has exceeded `GAME_DURATION / 2`
        //            seconds of time.
        if (nextDuration.raw() > GAME_DURATION.raw() >> 1) revert ClockTimeExceeded();

        // Construct the next clock with the new duration and the current block timestamp.
        Clock nextClock = LibClock.wrap(nextDuration, Timestamp.wrap(uint64(block.timestamp)));

        // INVARIANT: There cannot be multiple identical claims with identical moves on the same challengeIndex. Multiple
        //            claims at the same position may dispute the same challengeIndex. However, they must have different
        //            values.
        ClaimHash claimHash = _claim.hashClaimPos(nextPosition, _challengeIndex);
        if (claims[claimHash]) revert ClaimAlreadyExists();
        claims[claimHash] = true;

        // Create the new claim.
        claimData.push(
            ClaimData({
                parentIndex: uint32(_challengeIndex),
                counteredBy: address(0),
                claimant: msg.sender,
                bond: uint128(msg.value),
                claim: _claim,
                position: nextPosition,
                clock: nextClock
            })
        );

        // Set the parent claim as countered.
        claimData[_challengeIndex].counteredBy = msg.sender;

        // Update the subgame rooted at the parent claim.
        subgames[_challengeIndex].push(claimData.length - 1);

        // Emit the appropriate event for the attack or defense.
        emit Move(_challengeIndex, _claim, msg.sender);
    }

    /// @inheritdoc IFaultDisputeGame
    function attack(uint256 _parentIndex, Claim _claim) external payable {
        move(_parentIndex, _claim, true);
    }

    /// @inheritdoc IFaultDisputeGame
    function defend(uint256 _parentIndex, Claim _claim) external payable {
        move(_parentIndex, _claim, false);
    }

    /// @inheritdoc IFaultDisputeGame
    function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) external {
        // INVARIANT: Local data can only be added if the game is currently in progress.
        if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();

        (Claim starting, Position startingPos, Claim disputed, Position disputedPos) =
            _findStartingAndDisputedOutputs(_execLeafIdx);
        Hash uuid = _computeLocalContext(starting, startingPos, disputed, disputedPos);

        IPreimageOracle oracle = VM.oracle();
        if (_ident == LocalPreimageKey.L1_HEAD_HASH) {
            // Load the L1 head hash
            oracle.loadLocalData(_ident, uuid.raw(), l1Head.raw(), 32, _partOffset);
        } else if (_ident == LocalPreimageKey.STARTING_OUTPUT_ROOT) {
            // Load the starting proposal's output root.
            oracle.loadLocalData(_ident, uuid.raw(), starting.raw(), 32, _partOffset);
        } else if (_ident == LocalPreimageKey.DISPUTED_OUTPUT_ROOT) {
            // Load the disputed proposal's output root
            oracle.loadLocalData(_ident, uuid.raw(), disputed.raw(), 32, _partOffset);
        } else if (_ident == LocalPreimageKey.STARTING_L2_BLOCK_NUMBER) {
            // Load the starting proposal's L2 block number as a big-endian uint64 in the
            // high order 8 bytes of the word.

            // If the starting position is 0 (invalid), the starting output root is genesis. Otherwise,
            // we add the index at depth + 1 to the genesis block number to get the L2 block number.
            uint256 l2Number = startingPos.raw() == 0
                ? GENESIS_BLOCK_NUMBER
                : GENESIS_BLOCK_NUMBER + startingPos.traceIndex(SPLIT_DEPTH) + 1;

            oracle.loadLocalData(_ident, uuid.raw(), bytes32(l2Number << 0xC0), 8, _partOffset);
        } else if (_ident == LocalPreimageKey.CHAIN_ID) {
            // Load the chain ID as a big-endian uint64 in the high order 8 bytes of the word.
            oracle.loadLocalData(_ident, uuid.raw(), bytes32(block.chainid << 0xC0), 8, _partOffset);
        } else {
            revert InvalidLocalIdent();
        }
    }

    /// @inheritdoc IFaultDisputeGame
    function l2BlockNumber() public pure returns (uint256 l2BlockNumber_) {
        l2BlockNumber_ = _getArgUint256(0x20);
    }

    ////////////////////////////////////////////////////////////////
    //                    `IDisputeGame` impl                     //
    ////////////////////////////////////////////////////////////////

    /// @inheritdoc IDisputeGame
    function gameType() public view override returns (GameType gameType_) {
        gameType_ = GAME_TYPE;
    }

    /// @inheritdoc IDisputeGame
    function resolve() external returns (GameStatus status_) {
        // INVARIANT: Resolution cannot occur unless the game is currently in progress.
        if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();

        // INVARIANT: Resolution cannot occur unless the absolute root subgame has been resolved.
        if (!subgameAtRootResolved) revert OutOfOrderResolution();

        // Update the global game status; The dispute has concluded.
        status_ = claimData[0].counteredBy == address(0) ? GameStatus.DEFENDER_WINS : GameStatus.CHALLENGER_WINS;
        resolvedAt = Timestamp.wrap(uint64(block.timestamp));

        emit Resolved(status = status_);
    }

    /// @inheritdoc IFaultDisputeGame
    function resolveClaim(uint256 _claimIndex) external payable {
        // INVARIANT: Resolution cannot occur unless the game is currently in progress.
        if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();

        ClaimData storage parent = claimData[_claimIndex];

        // INVARIANT: Cannot resolve a subgame unless the clock of its root has expired
        uint64 parentClockDuration = parent.clock.duration().raw();
        uint64 timeSinceParentMove = uint64(block.timestamp) - parent.clock.timestamp().raw();
        if (parentClockDuration + timeSinceParentMove <= GAME_DURATION.raw() >> 1) {
            revert ClockNotExpired();
        }

        uint256[] storage challengeIndices = subgames[_claimIndex];
        uint256 challengeIndicesLen = challengeIndices.length;

        // INVARIANT: Cannot resolve subgames twice
        if (_claimIndex == 0 && subgameAtRootResolved) {
            revert ClaimAlreadyResolved();
        }

        // Uncontested claims are resolved implicitly unless they are the root claim. Pay out the bond to the claimant
        // and return early.
        if (challengeIndicesLen == 0 && _claimIndex != 0) {
            _distributeBond(parent.claimant, parent);
            return;
        }

        // Assume parent is honest until proven otherwise
        address countered = address(0);
        for (uint256 i = 0; i < challengeIndicesLen; ++i) {
            uint256 challengeIndex = challengeIndices[i];

            // INVARIANT: Cannot resolve a subgame containing an unresolved claim
            if (subgames[challengeIndex].length != 0) revert OutOfOrderResolution();

            ClaimData storage claim = claimData[challengeIndex];

            // Ignore false claims
            if (claim.counteredBy == address(0)) {
                countered = msg.sender;
                break;
            }
        }

        // If the parent was not successfully countered, pay out the parent's bond to the claimant.
        // If the parent was successfully countered, pay out the parent's bond to the challenger.
        _distributeBond(countered == address(0) ? parent.claimant : countered, parent);

        // Once a subgame is resolved, we percolate the result up the DAG so subsequent calls to
        // resolveClaim will not need to traverse this subgame.
        parent.counteredBy = countered;

        // Resolved subgames have no entries
        delete subgames[_claimIndex];

        // Indicate the game is ready to be resolved globally.
        if (_claimIndex == 0) {
            subgameAtRootResolved = true;
        }
    }

    /// @inheritdoc IDisputeGame
    function rootClaim() public pure returns (Claim rootClaim_) {
        rootClaim_ = Claim.wrap(_getArgFixedBytes(0x00));
    }

    /// @inheritdoc IDisputeGame
    function extraData() public pure returns (bytes memory extraData_) {
        // The extra data starts at the second word within the cwia calldata and
        // is 32 bytes long.
        extraData_ = _getArgDynBytes(0x20, 0x20);
    }

    /// @inheritdoc IDisputeGame
    function gameData() external view returns (GameType gameType_, Claim rootClaim_, bytes memory extraData_) {
        gameType_ = gameType();
        rootClaim_ = rootClaim();
        extraData_ = extraData();
    }

    ////////////////////////////////////////////////////////////////
    //                       MISC EXTERNAL                        //
    ////////////////////////////////////////////////////////////////

    /// @inheritdoc IInitializable
    function initialize() external payable {
        // SAFETY: Any revert in this function will bubble up to the DisputeGameFactory and
        // prevent the game from being created.
        //
        // Implicit assumptions:
        // - The `gameStatus` state variable defaults to 0, which is `GameStatus.IN_PROGRESS`
        // - The dispute game factory will enforce the required bond to initialize the game.
        //
        // Explicit checks:
        // - The game must not have already been initialized.
        // - An output root cannot be proposed at or before the genesis block.

        // INVARIANT: The game must not have already been initialized.
        if (initialized) revert AlreadyInitialized();

        // Do not allow the game to be initialized if the root claim corresponds to a block at or before the
        // configured genesis block number.
        if (l2BlockNumber() <= GENESIS_BLOCK_NUMBER) revert UnexpectedRootClaim(rootClaim());

        // Revert if the calldata size is too large, which signals that the `extraData` contains more than expected.
        // This is to prevent adding extra bytes to the `extraData` that result in a different game UUID in the factory,
        // but are not used by the game, which would allow for multiple dispute games for the same output proposal to
        // be created.
        // Expected length: 0x46 (0x04 selector + 0x20 root claim + 0x20 extraData + 0x02 CWIA bytes)
        assembly {
            if gt(calldatasize(), 0x46) {
                // Store the selector for `ExtraDataTooLong()` & revert
                mstore(0x00, 0xc407e025)
                revert(0x1C, 0x04)
            }
        }

        // Set the root claim
        claimData.push(
            ClaimData({
                parentIndex: type(uint32).max,
                counteredBy: address(0),
                claimant: tx.origin,
                bond: uint128(msg.value),
                claim: rootClaim(),
                position: ROOT_POSITION,
                clock: LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp)))
            })
        );

        // Set the game's starting timestamp
        createdAt = Timestamp.wrap(uint64(block.timestamp));

        // Persist the blockhash of the parent block.
        l1Head = Hash.wrap(blockhash(block.number - 1));

        // Set the game as initialized.
        initialized = true;
    }

    /// @notice Returns the length of the `claimData` array.
    function claimDataLen() external view returns (uint256 len_) {
        len_ = claimData.length;
    }

    /// @notice Returns the required bond for a given move kind.
    /// @param _position The position of the bonded interaction.
    /// @return requiredBond_ The required ETH bond for the given move, in wei.
    function getRequiredBond(Position _position) public pure returns (uint256 requiredBond_) {
        // TODO
        _position;
        requiredBond_ = 0;
    }

    /// @notice Claim the credit belonging to the recipient address.
    /// @param _recipient The owner and recipient of the credit.
    function claimCredit(address _recipient) external {
        // Remove the credit from the recipient prior to performing the external call.
        uint256 recipientCredit = credit[_recipient];
        credit[_recipient] = 0;

        // Transfer the credit to the recipient.
        (bool success,) = _recipient.call{ value: recipientCredit }(hex"");
        if (!success) revert BondTransferFailed();
    }

    ////////////////////////////////////////////////////////////////
    //                     IMMUTABLE GETTERS                      //
    ////////////////////////////////////////////////////////////////

    /// @notice Returns the absolute prestate of the instruction trace.
    function absolutePrestate() external view returns (Claim absolutePrestate_) {
        absolutePrestate_ = ABSOLUTE_PRESTATE;
    }

    /// @notice Returns the max game depth.
    function maxGameDepth() external view returns (uint256 maxGameDepth_) {
        maxGameDepth_ = MAX_GAME_DEPTH;
    }

    /// @notice Returns the split depth.
    function splitDepth() external view returns (uint256 splitDepth_) {
        splitDepth_ = SPLIT_DEPTH;
    }

    /// @notice Returns the game duration.
    function gameDuration() external view returns (Duration gameDuration_) {
        gameDuration_ = GAME_DURATION;
    }

    /// @notice Returns the address of the VM.
    function vm() external view returns (IBigStepper vm_) {
        vm_ = VM;
    }

    /// @notice Returns the genesis block number.
    function genesisBlockNumber() external view returns (uint256 genesisBlockNumber_) {
        genesisBlockNumber_ = GENESIS_BLOCK_NUMBER;
    }

    /// @notice Returns the genesis output root.
    function genesisOutputRoot() external view returns (Hash genesisOutputRoot_) {
        genesisOutputRoot_ = GENESIS_OUTPUT_ROOT;
    }

    ////////////////////////////////////////////////////////////////
    //                          HELPERS                           //
    ////////////////////////////////////////////////////////////////

    /// @notice Pays out the bond of a claim to a given recipient.
    /// @param _recipient The recipient of the bond.
    /// @param _bonded The claim to pay out the bond of.
    function _distributeBond(address _recipient, ClaimData storage _bonded) internal {
        // Set all bits in the bond value to indicate that the bond has been paid out.
        uint256 bond = _bonded.bond;
        if (bond == type(uint128).max) revert ClaimAlreadyResolved();
        _bonded.bond = type(uint128).max;

        // Increase the recipient's credit.
        credit[_recipient] += bond;
    }

    /// @notice Verifies the integrity of an execution bisection subgame's root claim. Reverts if the claim
    ///         is invalid.
    /// @param _rootClaim The root claim of the execution bisection subgame.
    function _verifyExecBisectionRoot(
        Claim _rootClaim,
        uint256 _parentIdx,
        Position _parentPos,
        bool _isAttack
    )
        internal
        view
    {
        // The root claim of an execution trace bisection sub-game must:
        // 1. Signal that the VM panicked or resulted in an invalid transition if the disputed output root
        //    was made by the opposing party.
        // 2. Signal that the VM resulted in a valid transition if the disputed output root was made by the same party.

        // If the move is a defense, the disputed output could have been made by either party. In this case, we
        // need to search for the parent output to determine what the expected status byte should be.
        Position disputedLeafPos = Position.wrap(_parentPos.raw() + 1);
        ClaimData storage disputed = _findTraceAncestor({ _pos: disputedLeafPos, _start: _parentIdx, _global: true });
        uint8 vmStatus = uint8(_rootClaim.raw()[0]);

        if (_isAttack || disputed.position.depth() % 2 == SPLIT_DEPTH % 2) {
            // If the move is an attack, the parent output is always deemed to be disputed. In this case, we only need
            // to check that the root claim signals that the VM panicked or resulted in an invalid transition.
            // If the move is a defense, and the disputed output and creator of the execution trace subgame disagree,
            // the root claim should also signal that the VM panicked or resulted in an invalid transition.
            if (!(vmStatus == VMStatuses.INVALID.raw() || vmStatus == VMStatuses.PANIC.raw())) {
                revert UnexpectedRootClaim(_rootClaim);
            }
        } else if (vmStatus != VMStatuses.VALID.raw()) {
            // The disputed output and the creator of the execution trace subgame agree. The status byte should
            // have signaled that the VM succeeded.
            revert UnexpectedRootClaim(_rootClaim);
        }
    }

    /// @notice Finds the trace ancestor of a given position within the DAG.
    /// @param _pos The position to find the trace ancestor claim of.
    /// @param _start The index to start searching from.
    /// @param _global Whether or not to search the entire dag or just within an execution trace subgame. If set to
    ///                `true`, and `_pos` is at or above the split depth, this function will revert.
    /// @return ancestor_ The ancestor claim that commits to the same trace index as `_pos`.
    function _findTraceAncestor(
        Position _pos,
        uint256 _start,
        bool _global
    )
        internal
        view
        returns (ClaimData storage ancestor_)
    {
        // Grab the trace ancestor's expected position.
        Position traceAncestorPos = _global ? _pos.traceAncestor() : _pos.traceAncestorBounded(SPLIT_DEPTH);

        // Walk up the DAG to find a claim that commits to the same trace index as `_pos`. It is
        // guaranteed that such a claim exists.
        ancestor_ = claimData[_start];
        while (ancestor_.position.raw() != traceAncestorPos.raw()) {
            ancestor_ = claimData[ancestor_.parentIndex];
        }
    }

    /// @notice Finds the starting and disputed output root for a given `ClaimData` within the DAG. This
    ///         `ClaimData` must be below the `SPLIT_DEPTH`.
    /// @param _start The index within `claimData` of the claim to start searching from.
    /// @return startingClaim_ The starting output root claim.
    /// @return startingPos_ The starting output root position.
    /// @return disputedClaim_ The disputed output root claim.
    /// @return disputedPos_ The disputed output root position.
    function _findStartingAndDisputedOutputs(uint256 _start)
        internal
        view
        returns (Claim startingClaim_, Position startingPos_, Claim disputedClaim_, Position disputedPos_)
    {
        // Fatch the starting claim.
        uint256 claimIdx = _start;
        ClaimData storage claim = claimData[claimIdx];

        // If the starting claim's depth is less than or equal to the split depth, we revert as this is UB.
        if (claim.position.depth() <= SPLIT_DEPTH) revert ClaimAboveSplit();

        // We want to:
        // 1. Find the first claim at the split depth.
        // 2. Determine whether it was the starting or disputed output for the exec game.
        // 3. Find the complimentary claim depending on the info from #2 (pre or post).

        // Walk up the DAG until the ancestor's depth is equal to the split depth.
        uint256 currentDepth;
        ClaimData storage execRootClaim = claim;
        while ((currentDepth = claim.position.depth()) > SPLIT_DEPTH) {
            uint256 parentIndex = claim.parentIndex;

            // If we're currently at the split depth + 1, we're at the root of the execution sub-game.
            // We need to keep track of the root claim here to determine whether the execution sub-game was
            // started with an attack or defense against the output leaf claim.
            if (currentDepth == SPLIT_DEPTH + 1) execRootClaim = claim;

            claim = claimData[parentIndex];
            claimIdx = parentIndex;
        }

        // Determine whether the start of the execution sub-game was an attack or defense to the output root
        // above. This is important because it determines which claim is the starting output root and which
        // is the disputed output root.
        (Position execRootPos, Position outputPos) = (execRootClaim.position, claim.position);
        bool wasAttack = execRootPos.parent().raw() == outputPos.raw();

        // Determine the starting and disputed output root indices.
        // 1. If it was an attack, the disputed output root is `claim`, and the starting output root is
        //    elsewhere in the DAG (it must commit to the block # index at depth of `outputPos - 1`).
        // 2. If it was a defense, the starting output root is `claim`, and the disputed output root is
        //    elsewhere in the DAG (it must commit to the block # index at depth of `outputPos + 1`).
        if (wasAttack) {
            // If this is an attack on the first output root (the block directly after genesis), the
            // starting claim nor position exists in the tree. We leave these as 0, which can be easily
            // identified due to 0 being an invalid Gindex.
            if (outputPos.indexAtDepth() > 0) {
                ClaimData storage starting = _findTraceAncestor(Position.wrap(outputPos.raw() - 1), claimIdx, true);
                (startingClaim_, startingPos_) = (starting.claim, starting.position);
            } else {
                startingClaim_ = Claim.wrap(GENESIS_OUTPUT_ROOT.raw());
            }
            (disputedClaim_, disputedPos_) = (claim.claim, claim.position);
        } else {
            ClaimData storage disputed = _findTraceAncestor(Position.wrap(outputPos.raw() + 1), claimIdx, true);
            (startingClaim_, startingPos_) = (claim.claim, claim.position);
            (disputedClaim_, disputedPos_) = (disputed.claim, disputed.position);
        }
    }

    /// @notice Finds the local context hash for a given claim index that is present in an execution trace subgame.
    /// @param _claimIndex The index of the claim to find the local context hash for.
    /// @return uuid_ The local context hash.
    function _findLocalContext(uint256 _claimIndex) internal view returns (Hash uuid_) {
        (Claim starting, Position startingPos, Claim disputed, Position disputedPos) =
            _findStartingAndDisputedOutputs(_claimIndex);
        uuid_ = _computeLocalContext(starting, startingPos, disputed, disputedPos);
    }

    /// @notice Computes the local context hash for a set of starting/disputed claim values and positions.
    /// @param _starting The starting claim.
    /// @param _startingPos The starting claim's position.
    /// @param _disputed The disputed claim.
    /// @param _disputedPos The disputed claim's position.
    /// @return uuid_ The local context hash.
    function _computeLocalContext(
        Claim _starting,
        Position _startingPos,
        Claim _disputed,
        Position _disputedPos
    )
        internal
        pure
        returns (Hash uuid_)
    {
        // A position of 0 indicates that the starting claim is the absolute prestate. In this special case,
        // we do not include the starting claim within the local context hash.
        if (_startingPos.raw() == 0) {
            uuid_ = Hash.wrap(keccak256(abi.encode(_disputed, _disputedPos)));
        } else {
            uuid_ = Hash.wrap(keccak256(abi.encode(_starting, _startingPos, _disputed, _disputedPos)));
        }
    }
}

File 2 of 15 : IDisputeGame.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

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

import "src/libraries/DisputeTypes.sol";

/// @title IDisputeGame
/// @notice The generic interface for a DisputeGame contract.
interface IDisputeGame is IInitializable {
    /// @notice Emitted when the game is resolved.
    /// @param status The status of the game after resolution.
    event Resolved(GameStatus indexed status);

    /// @notice Returns the timestamp that the DisputeGame contract was created at.
    /// @return createdAt_ The timestamp that the DisputeGame contract was created at.
    function createdAt() external view returns (Timestamp createdAt_);

    /// @notice Returns the current status of the game.
    /// @return status_ The current status of the game.
    function status() external view returns (GameStatus status_);

    /// @notice Getter for the game type.
    /// @dev The reference impl should be entirely different depending on the type (fault, validity)
    ///      i.e. The game type should indicate the security model.
    /// @return gameType_ The type of proof system being used.
    function gameType() external view returns (GameType gameType_);

    /// @notice Getter for the root claim.
    /// @dev `clones-with-immutable-args` argument #1
    /// @return rootClaim_ The root claim of the DisputeGame.
    function rootClaim() external pure returns (Claim rootClaim_);

    /// @notice Getter for the extra data.
    /// @dev `clones-with-immutable-args` argument #2
    /// @return extraData_ Any extra data supplied to the dispute game contract by the creator.
    function extraData() external pure returns (bytes memory extraData_);

    /// @notice If all necessary information has been gathered, this function should mark the game
    ///         status as either `CHALLENGER_WINS` or `DEFENDER_WINS` and return the status of
    ///         the resolved game. It is at this stage that the bonds should be awarded to the
    ///         necessary parties.
    /// @dev May only be called if the `status` is `IN_PROGRESS`.
    /// @return status_ The status of the game after resolution.
    function resolve() external returns (GameStatus status_);

    /// @notice A compliant implementation of this interface should return the components of the
    ///         game UUID's preimage provided in the cwia payload. The preimage of the UUID is
    ///         constructed as `keccak256(gameType . rootClaim . extraData)` where `.` denotes
    ///         concatenation.
    /// @return gameType_ The type of proof system being used.
    /// @return rootClaim_ The root claim of the DisputeGame.
    /// @return extraData_ Any extra data supplied to the dispute game contract by the creator.
    function gameData() external view returns (GameType gameType_, Claim rootClaim_, bytes memory extraData_);
}

File 3 of 15 : IFaultDisputeGame.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import { IDisputeGame } from "./IDisputeGame.sol";

import "src/libraries/DisputeTypes.sol";

/// @title IFaultDisputeGame
/// @notice The interface for a fault proof backed dispute game.
interface IFaultDisputeGame is IDisputeGame {
    /// @notice The `ClaimData` struct represents the data associated with a Claim.
    struct ClaimData {
        uint32 parentIndex;
        address counteredBy;
        address claimant;
        uint128 bond;
        Claim claim;
        Position position;
        Clock clock;
    }

    /// @notice Emitted when a new claim is added to the DAG by `claimant`
    /// @param parentIndex The index within the `claimData` array of the parent claim
    /// @param claim The claim being added
    /// @param claimant The address of the claimant
    event Move(uint256 indexed parentIndex, Claim indexed claim, address indexed claimant);

    /// @notice Attack a disagreed upon `Claim`.
    /// @param _parentIndex Index of the `Claim` to attack in the `claimData` array.
    /// @param _claim The `Claim` at the relative attack position.
    function attack(uint256 _parentIndex, Claim _claim) external payable;

    /// @notice Defend an agreed upon `Claim`.
    /// @param _parentIndex Index of the claim to defend in the `claimData` array.
    /// @param _claim The `Claim` at the relative defense position.
    function defend(uint256 _parentIndex, Claim _claim) external payable;

    /// @notice Perform an instruction step via an on-chain fault proof processor.
    /// @dev This function should point to a fault proof processor in order to execute
    ///      a step in the fault proof program on-chain. The interface of the fault proof
    ///      processor contract should adhere to the `IBigStepper` interface.
    /// @param _claimIndex The index of the challenged claim within `claimData`.
    /// @param _isAttack Whether or not the step is an attack or a defense.
    /// @param _stateData The stateData of the step is the preimage of the claim at the given
    ///        prestate, which is at `_stateIndex` if the move is an attack and `_claimIndex` if
    ///        the move is a defense. If the step is an attack on the first instruction, it is
    ///        the absolute prestate of the fault proof VM.
    /// @param _proof Proof to access memory nodes in the VM's merkle state tree.
    function step(uint256 _claimIndex, bool _isAttack, bytes calldata _stateData, bytes calldata _proof) external;

    /// @notice Posts the requested local data to the VM's `PreimageOralce`.
    /// @param _ident The local identifier of the data to post.
    /// @param _execLeafIdx The index of the leaf claim in an execution subgame that requires the local data for a step.
    /// @param _partOffset The offset of the data to post.
    function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) external;

    /// @notice Resolves the subgame rooted at the given claim index.
    /// @dev This function must be called bottom-up in the DAG
    ///      A subgame is a tree of claims that has a maximum depth of 1.
    ///      A subgame root claims is valid if, and only if, all of its child claims are invalid.
    ///      At the deepest level in the DAG, a claim is invalid if there's a successful step against it.
    /// @param _claimIndex The index of the subgame root claim to resolve.
    function resolveClaim(uint256 _claimIndex) external payable;

    /// @notice A block hash on the L1 that contains the disputed output root.
    function l1Head() external view returns (Hash l1Head_);

    /// @notice The l2BlockNumber of the disputed output root in the `L2OutputOracle`.
    function l2BlockNumber() external view returns (uint256 l2BlockNumber_);
}

File 4 of 15 : IInitializable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

/// @title IInitializable
/// @notice An interface for initializable contracts.
interface IInitializable {
    /// @notice Initializes the contract.
    /// @dev This function may only be called once.
    function initialize() external payable;
}

File 5 of 15 : IBigStepper.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol";

/// @title IBigStepper
/// @notice Describes a state machine that can perform a single instruction step, provided a prestate and an optional
///         proof.
/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⠶⢅⠒⢄⢔⣶⡦⣤⡤⠄⣀⠀⠀⠀⠀⠀⠀⠀
/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠨⡏⠀⠀⠈⠢⣙⢯⣄⠀⢨⠯⡺⡘⢄⠀⠀⠀⠀⠀
/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣶⡆⠀⠀⠀⠀⠈⠓⠬⡒⠡⣀⢙⡜⡀⠓⠄⠀⠀⠀
/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡷⠿⣧⣀⡀⠀⠀⠀⠀⠀⠀⠉⠣⣞⠩⠥⠀⠼⢄⠀⠀
/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡇⠀⠀⠀⠉⢹⣶⠒⠒⠂⠈⠉⠁⠘⡆⠀⣿⣿⠫⡄⠀
/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⢶⣤⣀⡀⠀⠀⢸⡿⠀⠀⠀⠀⠀⢀⠞⠀⠀⢡⢨⢀⡄⠀
/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⡒⣿⢿⡤⠝⡣⠉⠁⠚⠛⠀⠤⠤⣄⡰⠁⠀⠀⠀⠉⠙⢸⠀⠀
/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡤⢯⡌⡿⡇⠘⡷⠀⠁⠀⠀⢀⣰⠢⠲⠛⣈⣸⠦⠤⠶⠴⢬⣐⣊⡂⠀
/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⡪⡗⢫⠞⠀⠆⣀⠻⠤⠴⠐⠚⣉⢀⠦⠂⠋⠁⠀⠁⠀⠀⠀⠀⢋⠉⠇⠀
/// ⠀⠀⠀⠀⣀⡤⠐⠒⠘⡹⠉⢸⠇⠸⠀⠀⠀⠀⣀⣤⠴⠚⠉⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠼⠀⣾⠀
/// ⠀⠀⠀⡰⠀⠉⠉⠀⠁⠀⠀⠈⢇⠈⠒⠒⠘⠈⢀⢡⡂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠀⢸⡄
/// ⠀⠀⠸⣿⣆⠤⢀⡀⠀⠀⠀⠀⢘⡌⠀⠀⣀⣀⣀⡈⣤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⢸⡇
/// ⠀⠀⢸⣀⠀⠉⠒⠐⠛⠋⠭⠭⠍⠉⠛⠒⠒⠒⠀⠒⠚⠛⠛⠛⠩⠭⠭⠭⠭⠤⠤⠤⠤⠤⠭⠭⠉⠓⡆
/// ⠀⠀⠘⠿⣷⣶⣤⣤⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇
/// ⠀⠀⠀⠀⠀⠉⠙⠛⠛⠻⠿⢿⣿⣿⣷⣶⣶⣶⣤⣤⣀⣁⣛⣃⣒⠿⠿⠿⠤⠠⠄⠤⠤⢤⣛⣓⣂⣻⡇
/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠉⠙⠛⠻⠿⠿⠿⢿⣿⣿⣿⣷⣶⣶⣾⣿⣿⣿⣿⠿⠟⠁
/// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠈⠉⠉⠉⠉⠁⠀⠀⠀⠀⠀
interface IBigStepper {
    /// @notice Performs the state transition from a given prestate and returns the hash of the post state witness.
    /// @param _stateData The raw opaque prestate data.
    /// @param _proof Opaque proof data, can be used to prove things about the prestate in relation to the state of the
    ///               interface's implementation.
    /// @param _localContext The local key context for the preimage oracle. Optional, can be set as a constant if the
    ///                      implementation only requires one set of local keys.
    /// @return postState_ The hash of the post state witness after the state transition.
    function step(
        bytes calldata _stateData,
        bytes calldata _proof,
        bytes32 _localContext
    )
        external
        returns (bytes32 postState_);

    /// @notice Returns the preimage oracle used by the state machine.
    function oracle() external view returns (IPreimageOracle oracle_);
}

File 6 of 15 : Clone.sol
// SPDX-License-Identifier: BSD
pragma solidity ^0.8.15;

/// @title Clone
/// @author zefram.eth, Saw-mon & Natalie, clabby
/// @notice Provides helper functions for reading immutable args from calldata
/// @dev Original:
///      https://github.com/Saw-mon-and-Natalie/clones-with-immutable-args/
///      blob/105efee1b9127ed7f6fedf139e1fc796ce8791f2/src/Clone.sol
/// @dev MODIFICATIONS:
///      - Added `_getArgDynBytes` function.
contract Clone {
    uint256 private constant ONE_WORD = 0x20;

    /// @notice Reads an immutable arg with type address
    /// @param argOffset The offset of the arg in the packed data
    /// @return arg The arg value
    function _getArgAddress(uint256 argOffset) internal pure returns (address arg) {
        uint256 offset = _getImmutableArgsOffset();
        assembly {
            arg := shr(0x60, calldataload(add(offset, argOffset)))
        }
    }

    /// @notice Reads an immutable arg with type uint256
    /// @param argOffset The offset of the arg in the packed data
    /// @return arg The arg value
    function _getArgUint256(uint256 argOffset) internal pure returns (uint256 arg) {
        uint256 offset = _getImmutableArgsOffset();
        assembly {
            arg := calldataload(add(offset, argOffset))
        }
    }

    /// @notice Reads an immutable arg with type bytes32
    /// @param argOffset The offset of the arg in the packed data
    /// @return arg The arg value
    function _getArgFixedBytes(uint256 argOffset) internal pure returns (bytes32 arg) {
        uint256 offset = _getImmutableArgsOffset();
        assembly {
            arg := calldataload(add(offset, argOffset))
        }
    }

    /// @notice Reads a uint256 array stored in the immutable args.
    /// @param argOffset The offset of the arg in the packed data
    /// @param arrLen Number of elements in the array
    /// @return arr The array
    function _getArgUint256Array(uint256 argOffset, uint64 arrLen) internal pure returns (uint256[] memory arr) {
        uint256 offset = _getImmutableArgsOffset() + argOffset;
        arr = new uint256[](arrLen);

        assembly {
            calldatacopy(add(arr, ONE_WORD), offset, shl(5, arrLen))
        }
    }

    /// @notice Reads a dynamic bytes array stored in the immutable args.
    /// @param argOffset The offset of the arg in the packed data
    /// @param arrLen Number of elements in the array
    /// @return arr The array
    function _getArgDynBytes(uint256 argOffset, uint64 arrLen) internal pure returns (bytes memory arr) {
        uint256 offset = _getImmutableArgsOffset() + argOffset;
        arr = new bytes(arrLen);

        assembly {
            calldatacopy(add(arr, ONE_WORD), offset, arrLen)
        }
    }

    /// @notice Reads an immutable arg with type uint64
    /// @param argOffset The offset of the arg in the packed data
    /// @return arg The arg value
    function _getArgUint64(uint256 argOffset) internal pure returns (uint64 arg) {
        uint256 offset = _getImmutableArgsOffset();
        assembly {
            arg := shr(0xc0, calldataload(add(offset, argOffset)))
        }
    }

    /// @notice Reads an immutable arg with type uint8
    /// @param argOffset The offset of the arg in the packed data
    /// @return arg The arg value
    function _getArgUint8(uint256 argOffset) internal pure returns (uint8 arg) {
        uint256 offset = _getImmutableArgsOffset();
        assembly {
            arg := shr(0xf8, calldataload(add(offset, argOffset)))
        }
    }

    /// @return offset The offset of the packed immutable args in calldata
    function _getImmutableArgsOffset() internal pure returns (uint256 offset) {
        assembly {
            offset := sub(calldatasize(), shr(0xf0, calldataload(sub(calldatasize(), 2))))
        }
    }
}

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

/// @title Types
/// @notice Contains various types used throughout the Optimism contract system.
library Types {
    /// @notice OutputProposal represents a commitment to the L2 state. The timestamp is the L1
    ///         timestamp that the output root is posted. This timestamp is used to verify that the
    ///         finalization period has passed since the output root was submitted.
    /// @custom:field outputRoot    Hash of the L2 output.
    /// @custom:field timestamp     Timestamp of the L1 block that the output root was submitted in.
    /// @custom:field l2BlockNumber L2 block number that the output corresponds to.
    struct OutputProposal {
        bytes32 outputRoot;
        uint128 timestamp;
        uint128 l2BlockNumber;
    }

    /// @notice Struct representing the elements that are hashed together to generate an output root
    ///         which itself represents a snapshot of the L2 state.
    /// @custom:field version                  Version of the output root.
    /// @custom:field stateRoot                Root of the state trie at the block of this output.
    /// @custom:field messagePasserStorageRoot Root of the message passer storage trie.
    /// @custom:field latestBlockhash          Hash of the block this output was generated from.
    struct OutputRootProof {
        bytes32 version;
        bytes32 stateRoot;
        bytes32 messagePasserStorageRoot;
        bytes32 latestBlockhash;
    }

    /// @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end
    ///         user (as opposed to a system deposit transaction generated by the system).
    /// @custom:field from        Address of the sender of the transaction.
    /// @custom:field to          Address of the recipient of the transaction.
    /// @custom:field isCreation  True if the transaction is a contract creation.
    /// @custom:field value       Value to send to the recipient.
    /// @custom:field mint        Amount of ETH to mint.
    /// @custom:field gasLimit    Gas limit of the transaction.
    /// @custom:field data        Data of the transaction.
    /// @custom:field l1BlockHash Hash of the block the transaction was submitted in.
    /// @custom:field logIndex    Index of the log in the block the transaction was submitted in.
    struct UserDepositTransaction {
        address from;
        address to;
        bool isCreation;
        uint256 value;
        uint256 mint;
        uint64 gasLimit;
        bytes data;
        bytes32 l1BlockHash;
        uint256 logIndex;
    }

    /// @notice Struct representing a withdrawal transaction.
    /// @custom:field nonce    Nonce of the withdrawal transaction
    /// @custom:field sender   Address of the sender of the transaction.
    /// @custom:field target   Address of the recipient of the transaction.
    /// @custom:field value    Value to send to the recipient.
    /// @custom:field gasLimit Gas limit of the transaction.
    /// @custom:field data     Data of the transaction.
    struct WithdrawalTransaction {
        uint256 nonce;
        address sender;
        address target;
        uint256 value;
        uint256 gasLimit;
        bytes data;
    }
}

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

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

File 9 of 15 : LibUDT.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import "src/libraries/DisputeTypes.sol";

/// @title LibClock
/// @notice This library contains helper functions for working with the `Clock` type.
library LibClock {
    /// @notice Packs a `Duration` and `Timestamp` into a `Clock` type.
    /// @param _duration The `Duration` to pack into the `Clock` type.
    /// @param _timestamp The `Timestamp` to pack into the `Clock` type.
    /// @return clock_ The `Clock` containing the `_duration` and `_timestamp`.
    function wrap(Duration _duration, Timestamp _timestamp) internal pure returns (Clock clock_) {
        assembly {
            clock_ := or(shl(0x40, _duration), _timestamp)
        }
    }

    /// @notice Pull the `Duration` out of a `Clock` type.
    /// @param _clock The `Clock` type to pull the `Duration` out of.
    /// @return duration_ The `Duration` pulled out of `_clock`.
    function duration(Clock _clock) internal pure returns (Duration duration_) {
        // Shift the high-order 64 bits into the low-order 64 bits, leaving only the `duration`.
        assembly {
            duration_ := shr(0x40, _clock)
        }
    }

    /// @notice Pull the `Timestamp` out of a `Clock` type.
    /// @param _clock The `Clock` type to pull the `Timestamp` out of.
    /// @return timestamp_ The `Timestamp` pulled out of `_clock`.
    function timestamp(Clock _clock) internal pure returns (Timestamp timestamp_) {
        // Clean the high-order 192 bits by shifting the clock left and then right again, leaving
        // only the `timestamp`.
        assembly {
            timestamp_ := shr(0xC0, shl(0xC0, _clock))
        }
    }

    /// @notice Get the value of a `Clock` type in the form of the underlying uint128.
    /// @param _clock The `Clock` type to get the value of.
    /// @return clock_ The value of the `Clock` type as a uint128 type.
    function raw(Clock _clock) internal pure returns (uint128 clock_) {
        assembly {
            clock_ := _clock
        }
    }
}

/// @title LibClaim
/// @notice This library contains helper functions for working with the `Claim` type.
library LibClaim {
    /// @notice Get the value of a `Claim` type in the form of the underlying bytes32.
    /// @param _claim The `Claim` type to get the value of.
    /// @return claim_ The value of the `Claim` type as a bytes32 type.
    function raw(Claim _claim) internal pure returns (bytes32 claim_) {
        assembly {
            claim_ := _claim
        }
    }
}

/// @title LibDuration
/// @notice This library contains helper functions for working with the `Duration` type.
library LibDuration {
    /// @notice Get the value of a `Duration` type in the form of the underlying uint64.
    /// @param _duration The `Duration` type to get the value of.
    /// @return duration_ The value of the `Duration` type as a uint64 type.
    function raw(Duration _duration) internal pure returns (uint64 duration_) {
        assembly {
            duration_ := _duration
        }
    }
}

/// @title LibHash
/// @notice This library contains helper functions for working with the `Hash` type.
library LibHash {
    /// @notice Get the value of a `Hash` type in the form of the underlying bytes32.
    /// @param _hash The `Hash` type to get the value of.
    /// @return hash_ The value of the `Hash` type as a bytes32 type.
    function raw(Hash _hash) internal pure returns (bytes32 hash_) {
        assembly {
            hash_ := _hash
        }
    }
}

/// @title LibTimestamp
/// @notice This library contains helper functions for working with the `Timestamp` type.
library LibTimestamp {
    /// @notice Get the value of a `Timestamp` type in the form of the underlying uint64.
    /// @param _timestamp The `Timestamp` type to get the value of.
    /// @return timestamp_ The value of the `Timestamp` type as a uint64 type.
    function raw(Timestamp _timestamp) internal pure returns (uint64 timestamp_) {
        assembly {
            timestamp_ := _timestamp
        }
    }
}

/// @title LibVMStatus
/// @notice This library contains helper functions for working with the `VMStatus` type.
library LibVMStatus {
    /// @notice Get the value of a `VMStatus` type in the form of the underlying uint8.
    /// @param _vmstatus The `VMStatus` type to get the value of.
    /// @return vmstatus_ The value of the `VMStatus` type as a uint8 type.
    function raw(VMStatus _vmstatus) internal pure returns (uint8 vmstatus_) {
        assembly {
            vmstatus_ := _vmstatus
        }
    }
}

/// @title LibGameType
/// @notice This library contains helper functions for working with the `GameType` type.
library LibGameType {
    /// @notice Get the value of a `GameType` type in the form of the underlying uint8.
    /// @param _gametype The `GameType` type to get the value of.
    /// @return gametype_ The value of the `GameType` type as a uint8 type.
    function raw(GameType _gametype) internal pure returns (uint8 gametype_) {
        assembly {
            gametype_ := _gametype
        }
    }
}

File 10 of 15 : DisputeTypes.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import { LibHashing } from "src/dispute/lib/LibHashing.sol";
import {
    LibClaim,
    LibHash,
    LibDuration,
    LibClock,
    LibTimestamp,
    LibVMStatus,
    LibGameType
} from "src/dispute/lib/LibUDT.sol";
import { LibPosition } from "src/dispute/lib/LibPosition.sol";
import { LibGameId } from "src/dispute/lib/LibGameId.sol";

using LibClaim for Claim global;
using LibHashing for Claim global;
using LibHash for Hash global;
using LibPosition for Position global;
using LibDuration for Duration global;
using LibClock for Clock global;
using LibGameId for GameId global;
using LibTimestamp for Timestamp global;
using LibVMStatus for VMStatus global;
using LibGameType for GameType global;

/// @notice A custom type for a generic hash.
type Hash is bytes32;

/// @notice A claim represents an MPT root representing the state of the fault proof program.
type Claim is bytes32;

/// @notice A claim hash represents a hash of a claim and a position within the game tree.
/// @dev Keccak hash of abi.encodePacked(Claim, Position);
type ClaimHash is bytes32;

/// @notice A bondamount represents the amount of collateral that a user has locked up in a claim.
type BondAmount is uint256;

/// @notice A dedicated timestamp type.
type Timestamp is uint64;

/// @notice A dedicated duration type.
/// @dev Unit: seconds
type Duration is uint64;

/// @notice A `GameId` represents a packed 1 byte game ID, an 11 byte timestamp, and a 20 byte address.
/// @dev The packed layout of this type is as follows:
/// ┌───────────┬───────────┐
/// │   Bits    │   Value   │
/// ├───────────┼───────────┤
/// │ [0, 8)    │ Game Type │
/// │ [8, 96)   │ Timestamp │
/// │ [96, 256) │ Address   │
/// └───────────┴───────────┘
type GameId is bytes32;

/// @notice A `Clock` represents a packed `Duration` and `Timestamp`
/// @dev The packed layout of this type is as follows:
/// ┌────────────┬────────────────┐
/// │    Bits    │     Value      │
/// ├────────────┼────────────────┤
/// │ [0, 64)    │ Duration       │
/// │ [64, 128)  │ Timestamp      │
/// └────────────┴────────────────┘
type Clock is uint128;

/// @notice A `Position` represents a position of a claim within the game tree.
/// @dev This is represented as a "generalized index" where the high-order bit
/// is the level in the tree and the remaining bits is a unique bit pattern, allowing
/// a unique identifier for each node in the tree. Mathematically, it is calculated
/// as 2^{depth} + indexAtDepth.
type Position is uint128;

/// @notice A `GameType` represents the type of game being played.
type GameType is uint8;

/// @notice A `VMStatus` represents the status of a VM execution.
type VMStatus is uint8;

/// @notice The current status of the dispute game.
enum GameStatus {
    // The game is currently in progress, and has not been resolved.
    IN_PROGRESS,
    // The game has concluded, and the `rootClaim` was challenged successfully.
    CHALLENGER_WINS,
    // The game has concluded, and the `rootClaim` could not be contested.
    DEFENDER_WINS
}

/// @title GameTypes
/// @notice A library that defines the IDs of games that can be played.
library GameTypes {
    /// @dev A dispute game type the uses the cannon vm.
    GameType internal constant CANNON = GameType.wrap(0);

    /// @notice A dispute game type that uses an alphabet vm.
    ///         Not intended for production use.
    GameType internal constant ALPHABET = GameType.wrap(255);
}

/// @title VMStatuses
/// @notice Named type aliases for the various valid VM status bytes.
library VMStatuses {
    /// @notice The VM has executed successfully and the outcome is valid.
    VMStatus internal constant VALID = VMStatus.wrap(0);

    /// @notice The VM has executed successfully and the outcome is invalid.
    VMStatus internal constant INVALID = VMStatus.wrap(1);

    /// @notice The VM has paniced.
    VMStatus internal constant PANIC = VMStatus.wrap(2);

    /// @notice The VM execution is still in progress.
    VMStatus internal constant UNFINISHED = VMStatus.wrap(3);
}

/// @title LocalPreimageKey
/// @notice Named type aliases for local `PreimageOracle` key identifiers.
library LocalPreimageKey {
    /// @notice The identifier for the L1 head hash.
    uint256 internal constant L1_HEAD_HASH = 0x01;

    /// @notice The identifier for the starting output root.
    uint256 internal constant STARTING_OUTPUT_ROOT = 0x02;

    /// @notice The identifier for the disputed output root.
    uint256 internal constant DISPUTED_OUTPUT_ROOT = 0x03;

    /// @notice The identifier for the starting L2 block number.
    uint256 internal constant STARTING_L2_BLOCK_NUMBER = 0x04;

    /// @notice The identifier for the chain ID.
    uint256 internal constant CHAIN_ID = 0x05;
}

File 11 of 15 : DisputeErrors.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import "src/libraries/DisputeTypes.sol";

////////////////////////////////////////////////////////////////
//                `DisputeGameFactory` Errors                 //
////////////////////////////////////////////////////////////////

/// @notice Thrown when a dispute game is attempted to be created with an unsupported game type.
/// @param gameType The unsupported game type.
error NoImplementation(GameType gameType);

/// @notice Thrown when a dispute game that already exists is attempted to be created.
/// @param uuid The UUID of the dispute game that already exists.
error GameAlreadyExists(Hash uuid);

/// @notice Thrown when the root claim has an unexpected VM status.
///         Some games can only start with a root-claim with a specific status.
/// @param rootClaim is the claim that was unexpected.
error UnexpectedRootClaim(Claim rootClaim);

////////////////////////////////////////////////////////////////
//                 `FaultDisputeGame` Errors                  //
////////////////////////////////////////////////////////////////

/// @notice Thrown when a dispute game has already been initialized.
error AlreadyInitialized();

/// @notice Thrown when a supplied bond is too low to cover the cost of the interaction.
error InsufficientBond();

/// @notice Thrown when the transfer of credit to a recipient account reverts.
error BondTransferFailed();

/// @notice Thrown when the `extraData` passed to the CWIA proxy is too long for the `FaultDisputeGame`.
error ExtraDataTooLong();

/// @notice Thrown when a defense against the root claim is attempted.
error CannotDefendRootClaim();

/// @notice Thrown when a claim is attempting to be made that already exists.
error ClaimAlreadyExists();

/// @notice Thrown when a given claim is invalid (0).
error InvalidClaim();

/// @notice Thrown when an action that requires the game to be `IN_PROGRESS` is invoked when
///         the game is not in progress.
error GameNotInProgress();

/// @notice Thrown when a move is attempted to be made after the clock has timed out.
error ClockTimeExceeded();

/// @notice Thrown when the game is attempted to be resolved too early.
error ClockNotExpired();

/// @notice Thrown when a move is attempted to be made at or greater than the max depth of the game.
error GameDepthExceeded();

/// @notice Thrown when a step is attempted above the maximum game depth.
error InvalidParent();

/// @notice Thrown when an invalid prestate is supplied to `step`.
error InvalidPrestate();

/// @notice Thrown when a step is made that computes the expected post state correctly.
error ValidStep();

/// @notice Thrown when a game is attempted to be initialized with an L1 head that does
///         not contain the disputed output root.
error L1HeadTooOld();

/// @notice Thrown when an invalid local identifier is passed to the `addLocalData` function.
error InvalidLocalIdent();

/// @notice Thrown when resolving claims out of order.
error OutOfOrderResolution();

/// @notice Thrown when resolving a claim that has already been resolved.
error ClaimAlreadyResolved();

/// @notice Thrown when a parent output root is attempted to be found on a claim that is in
///         the output root portion of the tree.
error ClaimAboveSplit();

/// @notice Thrown on deployment if the split depth is greater than or equal to the max
///         depth of the game.
error InvalidSplitDepth();

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

/// @title IPreimageOracle
/// @notice Interface for a preimage oracle.
interface IPreimageOracle {
    /// @notice Reads a preimage from the oracle.
    /// @param _key The key of the preimage to read.
    /// @param _offset The offset of the preimage to read.
    /// @return dat_ The preimage data.
    /// @return datLen_ The length of the preimage data.
    function readPreimage(bytes32 _key, uint256 _offset) external view returns (bytes32 dat_, uint256 datLen_);

    /// @notice Loads of local data part into the preimage oracle.
    /// @param _ident The identifier of the local data.
    /// @param _localContext The local key context for the preimage oracle. Optionally, can be set as a constant
    ///                      if the caller only requires one set of local keys.
    /// @param _word The local data word.
    /// @param _size The number of bytes in `_word` to load.
    /// @param _partOffset The offset of the local data part to write to the oracle.
    /// @dev The local data parts are loaded into the preimage oracle under the context
    ///      of the caller - no other account can write to the caller's context
    ///      specific data.
    ///
    ///      There are 5 local data identifiers:
    ///      ┌────────────┬────────────────────────┐
    ///      │ Identifier │      Data              │
    ///      ├────────────┼────────────────────────┤
    ///      │          1 │ L1 Head Hash (bytes32) │
    ///      │          2 │ Output Root (bytes32)  │
    ///      │          3 │ Root Claim (bytes32)   │
    ///      │          4 │ L2 Block Number (u64)  │
    ///      │          5 │ Chain ID (u64)         │
    ///      └────────────┴────────────────────────┘
    function loadLocalData(
        uint256 _ident,
        bytes32 _localContext,
        bytes32 _word,
        uint256 _size,
        uint256 _partOffset
    )
        external
        returns (bytes32 key_);

    /// @notice Prepares a preimage to be read by keccak256 key, starting at the given offset and up to 32 bytes
    ///         (clipped at preimage length, if out of data).
    /// @param _partOffset The offset of the preimage to read.
    /// @param _preimage The preimage data.
    function loadKeccak256PreimagePart(uint256 _partOffset, bytes calldata _preimage) external;

    /// @notice Prepares a preimage to be read by sha256 key, starting at the given offset and up to 32 bytes
    ///         (clipped at preimage length, if out of data).
    /// @param _partOffset The offset of the preimage to read.
    /// @param _preimage The preimage data.
    function loadSha256PreimagePart(uint256 _partOffset, bytes calldata _preimage) external;
}

File 13 of 15 : LibHashing.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import "src/libraries/DisputeTypes.sol";

/// @title Hashing
/// @notice This library contains all of the hashing utilities used in the Cannon contracts.
library LibHashing {
    /// @notice Hashes a claim and a position together.
    /// @param _claim A Claim type.
    /// @param _position The position of `claim`.
    /// @param _challengeIndex The index of the claim being moved against.
    /// @return claimHash_ A hash of abi.encodePacked(claim, position|challengeIndex);
    function hashClaimPos(
        Claim _claim,
        Position _position,
        uint256 _challengeIndex
    )
        internal
        pure
        returns (ClaimHash claimHash_)
    {
        assembly {
            mstore(0x00, _claim)
            mstore(0x20, or(shl(128, _position), and(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, _challengeIndex)))
            claimHash_ := keccak256(0x00, 0x40)
        }
    }
}

File 14 of 15 : LibPosition.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import "src/libraries/DisputeTypes.sol";
import "src/libraries/DisputeErrors.sol";

/// @title LibPosition
/// @notice This library contains helper functions for working with the `Position` type.
library LibPosition {
    /// @notice Computes a generalized index (2^{depth} + indexAtDepth).
    /// @param _depth The depth of the position.
    /// @param _indexAtDepth The index at the depth of the position.
    /// @return position_ The computed generalized index.
    function wrap(uint64 _depth, uint64 _indexAtDepth) internal pure returns (Position position_) {
        assembly {
            // gindex = 2^{_depth} + _indexAtDepth
            position_ := add(shl(_depth, 1), _indexAtDepth)
        }
    }

    /// @notice Pulls the `depth` out of a `Position` type.
    /// @param _position The generalized index to get the `depth` of.
    /// @return depth_ The `depth` of the `position` gindex.
    /// @custom:attribution Solady <https://github.com/Vectorized/Solady>
    function depth(Position _position) internal pure returns (uint64 depth_) {
        // Return the most significant bit offset, which signifies the depth of the gindex.
        assembly {
            depth_ := or(depth_, shl(6, lt(0xffffffffffffffff, shr(depth_, _position))))
            depth_ := or(depth_, shl(5, lt(0xffffffff, shr(depth_, _position))))

            // For the remaining 32 bits, use a De Bruijn lookup.
            _position := shr(depth_, _position)
            _position := or(_position, shr(1, _position))
            _position := or(_position, shr(2, _position))
            _position := or(_position, shr(4, _position))
            _position := or(_position, shr(8, _position))
            _position := or(_position, shr(16, _position))

            depth_ :=
                or(
                    depth_,
                    byte(
                        shr(251, mul(_position, shl(224, 0x07c4acdd))),
                        0x0009010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f
                    )
                )
        }
    }

    /// @notice Pulls the `indexAtDepth` out of a `Position` type.
    ///         The `indexAtDepth` is the left/right index of a position at a specific depth within
    ///         the binary tree, starting from index 0. For example, at gindex 2, the `depth` = 1
    ///         and the `indexAtDepth` = 0.
    /// @param _position The generalized index to get the `indexAtDepth` of.
    /// @return indexAtDepth_ The `indexAtDepth` of the `position` gindex.
    function indexAtDepth(Position _position) internal pure returns (uint64 indexAtDepth_) {
        // Return bits p_{msb-1}...p_{0}. This effectively pulls the 2^{depth} out of the gindex,
        // leaving only the `indexAtDepth`.
        uint256 msb = depth(_position);
        assembly {
            indexAtDepth_ := sub(_position, shl(msb, 1))
        }
    }

    /// @notice Get the left child of `_position`.
    /// @param _position The position to get the left position of.
    /// @return left_ The position to the left of `position`.
    function left(Position _position) internal pure returns (Position left_) {
        assembly {
            left_ := shl(1, _position)
        }
    }

    /// @notice Get the right child of `_position`
    /// @param _position The position to get the right position of.
    /// @return right_ The position to the right of `position`.
    function right(Position _position) internal pure returns (Position right_) {
        assembly {
            right_ := or(1, shl(1, _position))
        }
    }

    /// @notice Get the parent position of `_position`.
    /// @param _position The position to get the parent position of.
    /// @return parent_ The parent position of `position`.
    function parent(Position _position) internal pure returns (Position parent_) {
        assembly {
            parent_ := shr(1, _position)
        }
    }

    /// @notice Get the deepest, right most gindex relative to the `position`. This is equivalent to
    ///         calling `right` on a position until the maximum depth is reached.
    /// @param _position The position to get the relative deepest, right most gindex of.
    /// @param _maxDepth The maximum depth of the game.
    /// @return rightIndex_ The deepest, right most gindex relative to the `position`.
    function rightIndex(Position _position, uint256 _maxDepth) internal pure returns (Position rightIndex_) {
        uint256 msb = depth(_position);
        assembly {
            let remaining := sub(_maxDepth, msb)
            rightIndex_ := or(shl(remaining, _position), sub(shl(remaining, 1), 1))
        }
    }

    /// @notice Get the deepest, right most trace index relative to the `position`. This is
    ///         equivalent to calling `right` on a position until the maximum depth is reached and
    ///         then finding its index at depth.
    /// @param _position The position to get the relative trace index of.
    /// @param _maxDepth The maximum depth of the game.
    /// @return traceIndex_ The trace index relative to the `position`.
    function traceIndex(Position _position, uint256 _maxDepth) internal pure returns (uint256 traceIndex_) {
        uint256 msb = depth(_position);
        assembly {
            let remaining := sub(_maxDepth, msb)
            traceIndex_ := sub(or(shl(remaining, _position), sub(shl(remaining, 1), 1)), shl(_maxDepth, 1))
        }
    }

    /// @notice Gets the position of the highest ancestor of `_position` that commits to the same
    ///         trace index.
    /// @param _position The position to get the highest ancestor of.
    /// @return ancestor_ The highest ancestor of `position` that commits to the same trace index.
    function traceAncestor(Position _position) internal pure returns (Position ancestor_) {
        // Create a field with only the lowest unset bit of `_position` set.
        Position lsb;
        assembly {
            lsb := and(not(_position), add(_position, 1))
        }
        // Find the index of the lowest unset bit within the field.
        uint256 msb = depth(lsb);
        // The highest ancestor that commits to the same trace index is the original position
        // shifted right by the index of the lowest unset bit.
        assembly {
            let a := shr(msb, _position)
            // Bound the ancestor to the minimum gindex, 1.
            ancestor_ := or(a, iszero(a))
        }
    }

    /// @notice Gets the position of the highest ancestor of `_position` that commits to the same
    ///         trace index, while still being below `_upperBoundExclusive`.
    /// @param _position The position to get the highest ancestor of.
    /// @param _upperBoundExclusive The exclusive upper depth bound, used to inform where to stop in order
    ///                             to not escape a sub-tree.
    /// @return ancestor_ The highest ancestor of `position` that commits to the same trace index.
    function traceAncestorBounded(
        Position _position,
        uint256 _upperBoundExclusive
    )
        internal
        pure
        returns (Position ancestor_)
    {
        // This function only works for positions that are below the upper bound.
        if (_position.depth() <= _upperBoundExclusive) revert ClaimAboveSplit();

        // Grab the global trace ancestor.
        ancestor_ = traceAncestor(_position);

        // If the ancestor is above or at the upper bound, shift it to be below the upper bound.
        // This should be a special case that only covers positions that commit to the final leaf
        // in a sub-tree.
        if (ancestor_.depth() <= _upperBoundExclusive) {
            ancestor_ = ancestor_.rightIndex(_upperBoundExclusive + 1);
        }
    }

    /// @notice Get the move position of `_position`, which is the left child of:
    ///         1. `_position + 1` if `_isAttack` is true.
    ///         1. `_position` if `_isAttack` is false.
    /// @param _position The position to get the relative attack/defense position of.
    /// @param _isAttack Whether or not the move is an attack move.
    /// @return move_ The move position relative to `position`.
    function move(Position _position, bool _isAttack) internal pure returns (Position move_) {
        assembly {
            move_ := shl(1, or(iszero(_isAttack), _position))
        }
    }

    /// @notice Get the value of a `Position` type in the form of the underlying uint128.
    /// @param _position The position to get the value of.
    /// @return raw_ The value of the `position` as a uint128 type.
    function raw(Position _position) internal pure returns (uint128 raw_) {
        assembly {
            raw_ := _position
        }
    }
}

File 15 of 15 : LibGameId.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import "src/libraries/DisputeTypes.sol";
import "src/dispute/interfaces/IDisputeGame.sol";

/// @title LibGameId
/// @notice Utility functions for packing and unpacking GameIds.
library LibGameId {
    /// @notice Packs values into a 32 byte GameId type.
    /// @param _gameType The game type.
    /// @param _timestamp The timestamp of the game's creation.
    /// @param _gameProxy The game proxy address.
    /// @return gameId_ The packed GameId.
    function pack(
        GameType _gameType,
        Timestamp _timestamp,
        IDisputeGame _gameProxy
    )
        internal
        pure
        returns (GameId gameId_)
    {
        assembly {
            gameId_ := or(or(shl(248, _gameType), shl(184, _timestamp)), _gameProxy)
        }
    }

    /// @notice Unpacks values from a 32 byte GameId type.
    /// @param _gameId The packed GameId.
    /// @return gameType_ The game type.
    /// @return timestamp_ The timestamp of the game's creation.
    /// @return gameProxy_ The game proxy address.
    function unpack(GameId _gameId)
        internal
        pure
        returns (GameType gameType_, Timestamp timestamp_, IDisputeGame gameProxy_)
    {
        assembly {
            gameType_ := shr(248, _gameId)
            timestamp_ := shr(184, and(_gameId, not(shl(248, 0xff))))
            gameProxy_ := and(_gameId, 0xffffffffffffffffffffffffffffffffffffffff)
        }
    }
}

Settings
{
  "remappings": [
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "@rari-capital/solmate/=lib/solmate/",
    "@cwia/=lib/clones-with-immutable-args/src/",
    "@lib-keccak/=lib/lib-keccak/contracts/lib/",
    "forge-std/=lib/forge-std/src/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "safe-contracts/=lib/safe-contracts/contracts/",
    "kontrol-cheatcodes/=lib/kontrol-cheatcodes/src/",
    "solady/=lib/solady/src/",
    "@eth-optimism/=node_modules/@eth-optimism/",
    "clones-with-immutable-args/=lib/clones-with-immutable-args/src/",
    "lib-keccak/=lib/lib-keccak/contracts/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "solmate/=lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 999999
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "none"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"GameType","name":"_gameType","type":"uint8"},{"internalType":"Claim","name":"_absolutePrestate","type":"bytes32"},{"internalType":"uint256","name":"_genesisBlockNumber","type":"uint256"},{"internalType":"Hash","name":"_genesisOutputRoot","type":"bytes32"},{"internalType":"uint256","name":"_maxGameDepth","type":"uint256"},{"internalType":"uint256","name":"_splitDepth","type":"uint256"},{"internalType":"Duration","name":"_gameDuration","type":"uint64"},{"internalType":"contract IBigStepper","name":"_vm","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"BondTransferFailed","type":"error"},{"inputs":[],"name":"CannotDefendRootClaim","type":"error"},{"inputs":[],"name":"ClaimAboveSplit","type":"error"},{"inputs":[],"name":"ClaimAlreadyExists","type":"error"},{"inputs":[],"name":"ClaimAlreadyResolved","type":"error"},{"inputs":[],"name":"ClockNotExpired","type":"error"},{"inputs":[],"name":"ClockTimeExceeded","type":"error"},{"inputs":[],"name":"GameDepthExceeded","type":"error"},{"inputs":[],"name":"GameNotInProgress","type":"error"},{"inputs":[],"name":"InsufficientBond","type":"error"},{"inputs":[],"name":"InvalidLocalIdent","type":"error"},{"inputs":[],"name":"InvalidParent","type":"error"},{"inputs":[],"name":"InvalidPrestate","type":"error"},{"inputs":[],"name":"InvalidSplitDepth","type":"error"},{"inputs":[],"name":"OutOfOrderResolution","type":"error"},{"inputs":[{"internalType":"Claim","name":"rootClaim","type":"bytes32"}],"name":"UnexpectedRootClaim","type":"error"},{"inputs":[],"name":"ValidStep","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"parentIndex","type":"uint256"},{"indexed":true,"internalType":"Claim","name":"claim","type":"bytes32"},{"indexed":true,"internalType":"address","name":"claimant","type":"address"}],"name":"Move","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"enum GameStatus","name":"status","type":"uint8"}],"name":"Resolved","type":"event"},{"inputs":[],"name":"absolutePrestate","outputs":[{"internalType":"Claim","name":"absolutePrestate_","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_ident","type":"uint256"},{"internalType":"uint256","name":"_execLeafIdx","type":"uint256"},{"internalType":"uint256","name":"_partOffset","type":"uint256"}],"name":"addLocalData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_parentIndex","type":"uint256"},{"internalType":"Claim","name":"_claim","type":"bytes32"}],"name":"attack","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"}],"name":"claimCredit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"claimData","outputs":[{"internalType":"uint32","name":"parentIndex","type":"uint32"},{"internalType":"address","name":"counteredBy","type":"address"},{"internalType":"address","name":"claimant","type":"address"},{"internalType":"uint128","name":"bond","type":"uint128"},{"internalType":"Claim","name":"claim","type":"bytes32"},{"internalType":"Position","name":"position","type":"uint128"},{"internalType":"Clock","name":"clock","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimDataLen","outputs":[{"internalType":"uint256","name":"len_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"createdAt","outputs":[{"internalType":"Timestamp","name":"","type":"uint64"}],"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":"_parentIndex","type":"uint256"},{"internalType":"Claim","name":"_claim","type":"bytes32"}],"name":"defend","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"extraData","outputs":[{"internalType":"bytes","name":"extraData_","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"gameData","outputs":[{"internalType":"GameType","name":"gameType_","type":"uint8"},{"internalType":"Claim","name":"rootClaim_","type":"bytes32"},{"internalType":"bytes","name":"extraData_","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gameDuration","outputs":[{"internalType":"Duration","name":"gameDuration_","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gameType","outputs":[{"internalType":"GameType","name":"gameType_","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genesisBlockNumber","outputs":[{"internalType":"uint256","name":"genesisBlockNumber_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genesisOutputRoot","outputs":[{"internalType":"Hash","name":"genesisOutputRoot_","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"Position","name":"_position","type":"uint128"}],"name":"getRequiredBond","outputs":[{"internalType":"uint256","name":"requiredBond_","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"l1Head","outputs":[{"internalType":"Hash","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2BlockNumber","outputs":[{"internalType":"uint256","name":"l2BlockNumber_","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"maxGameDepth","outputs":[{"internalType":"uint256","name":"maxGameDepth_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_challengeIndex","type":"uint256"},{"internalType":"Claim","name":"_claim","type":"bytes32"},{"internalType":"bool","name":"_isAttack","type":"bool"}],"name":"move","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"resolve","outputs":[{"internalType":"enum GameStatus","name":"status_","type":"uint8"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_claimIndex","type":"uint256"}],"name":"resolveClaim","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"resolvedAt","outputs":[{"internalType":"Timestamp","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rootClaim","outputs":[{"internalType":"Claim","name":"rootClaim_","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"splitDepth","outputs":[{"internalType":"uint256","name":"splitDepth_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"status","outputs":[{"internalType":"enum GameStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_claimIndex","type":"uint256"},{"internalType":"bool","name":"_isAttack","type":"bool"},{"internalType":"bytes","name":"_stateData","type":"bytes"},{"internalType":"bytes","name":"_proof","type":"bytes"}],"name":"step","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vm","outputs":[{"internalType":"contract IBigStepper","name":"vm_","type":"address"}],"stateMutability":"view","type":"function"}]

6101806040523480156200001257600080fd5b5060405162003a4138038062003a41833981016040819052620000359162000098565b838310620000565760405163e62ccf3960e01b815260040160405180910390fd5b60ff90971661016052608095909552610120939093526101409190915260a05260c0526001600160401b031660e0526001600160a01b0316610100526200013a565b600080600080600080600080610100898b031215620000b657600080fd5b885160ff81168114620000c857600080fd5b60208a015160408b015160608c015160808d015160a08e015160c08f0151959d50939b509199509750955093506001600160401b03811681146200010b57600080fd5b60e08a01519092506001600160a01b03811681146200012957600080fd5b809150509295985092959890939650565b60805160a05160c05160e051610100516101205161014051610160516138076200023a6000396000818161049b0152611ffa0152600081816103d30152612bad0152600081816101e10152818161122c01528181611e2e0152611e640152600081816102e6015281816119180152611c1d01526000818161063d01528181610db4015261215801526000818161067001528181610be301528181610cac0152818161177301528181611e04015281816124ff01528181612739015281816128670152818161296f0152612a4b0152600081816106e701528181610c4f015281816116620152611794015260008181610463015261182a01526138076000f3fe6080604052600436106101cd5760003560e01c80638d450a95116100f7578063d5d44d8011610095578063f8f43ff611610064578063f8f43ff614610694578063fa24f743146106b4578063fa315aa9146106d8578063fdffbb281461070b57600080fd5b8063d5d44d80146105e1578063d8cc1a3c1461060e578063e1f0c3761461062e578063ec5e63081461066157600080fd5b8063c395e1ca116100d1578063c395e1ca14610502578063c55cd0c714610523578063c6f0308c14610536578063cf09e0d0146105c057600080fd5b80638d450a9514610454578063bbdc02db14610487578063bcef3b55146104c557600080fd5b8063609d33341161016f57806368800abf1161013e57806368800abf146103c45780638129fc1c146103f75780638980e0cc146103ff5780638b85902b1461041457600080fd5b8063609d33341461036657806360e274641461037b578063632247ea1461039b5780636361506d146103ae57600080fd5b80632810e1d6116101ab5780632810e1d61461029557806335fef567146102aa5780633a768463146102bf57806354fd4d501461031057600080fd5b80630356fe3a146101d257806319effeb414610214578063200d2ed21461025a575b600080fd5b3480156101de57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040519081526020015b60405180910390f35b34801561022057600080fd5b506000546102419068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161020b565b34801561026657600080fd5b5060005461028890700100000000000000000000000000000000900460ff1681565b60405161020b9190613244565b3480156102a157600080fd5b5061028861071e565b6102bd6102b8366004613285565b61091b565b005b3480156102cb57600080fd5b5060405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016815260200161020b565b34801561031c57600080fd5b506103596040518060400160405280600681526020017f302e302e3234000000000000000000000000000000000000000000000000000081525081565b60405161020b9190613312565b34801561037257600080fd5b5061035961092b565b34801561038757600080fd5b506102bd610396366004613347565b61093d565b6102bd6103a9366004613380565b6109ed565b3480156103ba57600080fd5b5061020160015481565b3480156103d057600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610201565b6102bd6111e8565b34801561040b57600080fd5b50600254610201565b34801561042057600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360200135610201565b34801561046057600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610201565b34801561049357600080fd5b5060405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161020b565b3480156104d157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335610201565b34801561050e57600080fd5b5061020161051d3660046133b5565b50600090565b6102bd610531366004613285565b61150e565b34801561054257600080fd5b506105566105513660046133e7565b61151a565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e00161020b565b3480156105cc57600080fd5b506000546102419067ffffffffffffffff1681565b3480156105ed57600080fd5b506102016105fc366004613347565b60036020526000908152604090205481565b34801561061a57600080fd5b506102bd610629366004613449565b6115b1565b34801561063a57600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610241565b34801561066d57600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610201565b3480156106a057600080fd5b506102bd6106af3660046134d3565b611b8f565b3480156106c057600080fd5b506106c9611ff8565b60405161020b939291906134ff565b3480156106e457600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610201565b6102bd6107193660046133e7565b612055565b600080600054700100000000000000000000000000000000900460ff16600281111561074c5761074c613215565b14610783576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60065460ff166107bf576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660026000815481106107eb576107eb61352a565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614610826576001610829565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff909116177001000000000000000000000000000000008360028111156108da576108da613215565b0217905560028111156108ef576108ef613215565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a290565b610927828260006109ed565b5050565b606061093860208061241c565b905090565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260036020526040808220805490839055905190929083908381818185875af1925050503d80600081146109a8576040519150601f19603f3d011682016040523d82523d6000602084013e6109ad565b606091505b50509050806109e8576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b60008054700100000000000000000000000000000000900460ff166002811115610a1957610a19613215565b14610a50576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110610a6557610a6561352a565b600091825260208083206040805160e0810182526005909402909101805463ffffffff808216865273ffffffffffffffffffffffffffffffffffffffff6401000000009092048216948601949094526001820154169184019190915260028101546fffffffffffffffffffffffffffffffff90811660608501526003820154608085015260049091015480821660a0850181905270010000000000000000000000000000000090910490911660c0840152919350909190610b2a90839086906124b316565b90506000610bca826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050861580610c0c5750610c097f00000000000000000000000000000000000000000000000000000000000000006002613588565b81145b8015610c16575084155b15610c4d576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000811115610ca7576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cd27f00000000000000000000000000000000000000000000000000000000000000006001613588565b8103610ce457610ce4868885886124bb565b835160009063ffffffff90811614610d44576002856000015163ffffffff1681548110610d1357610d1361352a565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b60c0850151600090610d689067ffffffffffffffff165b67ffffffffffffffff1690565b67ffffffffffffffff1642610d92610d5b856fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610da69190613588565b610db091906135a0565b90507f000000000000000000000000000000000000000000000000000000000000000060011c677fffffffffffffff1667ffffffffffffffff82161115610e23576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615610ea1576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050503360028c815481106111265761112661352a565b60009182526020808320600592830201805473ffffffffffffffffffffffffffffffffffffffff95909516640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff909516949094179093558d82529091526040902060025461119c906001906135a0565b8154600181018355600092835260208320015560405133918c918e917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a45050505050505050505050565b600654610100900460ff161561122a576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360200135116112e1576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560048201526024015b60405180910390fd5b60463611156112f85763c407e0256000526004601cfd5b6040805160e08101825263ffffffff8152600060208201523291810191909152346fffffffffffffffffffffffffffffffff16606082015260029060808101367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335815260016020820152604001426fffffffffffffffffffffffffffffffff90811690915282546001808201855560009485526020808620855160059094020180549186015163ffffffff9094167fffffffffffffffff0000000000000000000000000000000000000000000000009092169190911764010000000073ffffffffffffffffffffffffffffffffffffffff94851602178155604085015181830180547fffffffffffffffffffffffff000000000000000000000000000000000000000016919094161790925560608401516002830180547fffffffffffffffffffffffffffffffff00000000000000000000000000000000169185169190911790556080840151600383015560a084015160c09094015193831670010000000000000000000000000000000094909316939093029190911760049091015581547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff16179091556114dc90436135a0565b40600155600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b610927828260016109ed565b6002818154811061152a57600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff1660028111156115dd576115dd613215565b14611614576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600287815481106116295761162961352a565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506116887f00000000000000000000000000000000000000000000000000000000000000006001613588565b611724826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1614611765576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808915611854576117b87f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006135a0565b6001901b6117d7846fffffffffffffffffffffffffffffffff16612673565b67ffffffffffffffff166117eb91906135e6565b156118285761181f61181060016fffffffffffffffffffffffffffffffff87166135fa565b865463ffffffff166000612719565b6003015461184a565b7f00000000000000000000000000000000000000000000000000000000000000005b915084905061187e565b6003850154915061187b6118106fffffffffffffffffffffffffffffffff8616600161362b565b90505b600882901b60088a8a60405161189592919061365f565b6040518091039020901b146118d6576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006118e18c6127fd565b905060006118f0836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e14ced329061196a908f908f908f908f908a906004016136b8565b6020604051808303816000875af1158015611989573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ad91906136f2565b600485015491149150600090600290611a58906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b611af4896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b611afe919061370b565b611b08919061372c565b67ffffffffffffffff161590508115158103611b50576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff166002811115611bbb57611bbb613215565b14611bf2576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600080611c018661282c565b93509350935093506000611c1785858585612c59565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611caa9190613753565b905060018903611d725773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a846001545b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af1158015611d48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6c91906136f2565b50611fed565b60028903611d9e5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8489611cd6565b60038903611dca5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8487611cd6565b60048903611f425760006fffffffffffffffffffffffffffffffff861615611e6257611e286fffffffffffffffffffffffffffffffff87167f0000000000000000000000000000000000000000000000000000000000000000612d18565b611e52907f0000000000000000000000000000000000000000000000000000000000000000613588565b611e5d906001613588565b611e84565b7f00000000000000000000000000000000000000000000000000000000000000005b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af1158015611f17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f3b91906136f2565b5050611fed565b60058903611fbb576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390524660c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a401611d29565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335606061204e61092b565b9050909192565b60008054700100000000000000000000000000000000900460ff16600281111561208157612081613215565b146120b8576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600282815481106120cd576120cd61352a565b60009182526020822060059190910201600481015490925061210f90700100000000000000000000000000000000900460401c67ffffffffffffffff16610d5b565b600483015490915060009061214190700100000000000000000000000000000000900467ffffffffffffffff16610d5b565b61214b904261370b565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c166121858284613770565b67ffffffffffffffff16116121c6576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526005602052604090208054851580156121e6575060065460ff165b1561221d576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8015801561222a57508515155b1561225c5760018501546122549073ffffffffffffffffffffffffffffffffffffffff1686612dcd565b505050505050565b6000805b8281101561233b57600084828154811061227c5761227c61352a565b60009182526020808320909101548083526005909152604090912054909150156122d2576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600282815481106122e7576122e761352a565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff1661232857339350505061233b565b50508061233490613793565b9050612260565b5061238373ffffffffffffffffffffffffffffffffffffffff821615612361578161237d565b600187015473ffffffffffffffffffffffffffffffffffffffff165b87612dcd565b85547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff83160217865560008781526005602052604081206123df916131db565b8660000361241357600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b50505050505050565b6060600061245384367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003613588565b90508267ffffffffffffffff1667ffffffffffffffff811115612478576124786137cb565b6040519080825280601f01601f1916602001820160405280156124a2576020820181803683370190505b509150828160208401375092915050565b151760011b90565b60006124da6fffffffffffffffffffffffffffffffff8416600161362b565b905060006124ea82866001612719565b9050600086901a83806125dd575061252360027f00000000000000000000000000000000000000000000000000000000000000006135e6565b60048301546002906125c7906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6125d1919061372c565b67ffffffffffffffff16145b156126355760ff8116600114806125f7575060ff81166002145b612630576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016112d8565b612413565b60ff811615612413576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016112d8565b600080612700837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b600080826127625761275d6fffffffffffffffffffffffffffffffff86167f0000000000000000000000000000000000000000000000000000000000000000612eb8565b61277d565b61277d856fffffffffffffffffffffffffffffffff1661307f565b9050600284815481106127925761279261352a565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff8281169116146127f557815460028054909163ffffffff169081106127e0576127e061352a565b906000526020600020906005020191506127a3565b509392505050565b600080600080600061280e8661282c565b935093509350935061282284848484612c59565b9695505050505050565b600080600080600085905060006002828154811061284c5761284c61352a565b600091825260209091206004600590920201908101549091507f000000000000000000000000000000000000000000000000000000000000000090612923906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611612964576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f000000000000000000000000000000000000000000000000000000000000000090612a2b906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169250821115612aa757825463ffffffff16612a717f00000000000000000000000000000000000000000000000000000000000000006001613588565b8303612a7b578391505b60028181548110612a8e57612a8e61352a565b9060005260206000209060050201935080945050612968565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff16612b10612afb856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff161490508015612bf5576000612b48836fffffffffffffffffffffffffffffffff16612673565b67ffffffffffffffff161115612bab576000612b82612b7a60016fffffffffffffffffffffffffffffffff86166135fa565b896001612719565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a50612bcf9050565b7f00000000000000000000000000000000000000000000000000000000000000009a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750612c4b565b6000612c17612b7a6fffffffffffffffffffffffffffffffff8516600161362b565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff84168103612cbf578282604051602001612ca29291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b604051602081830303815290604052805190602001209050612d10565b60408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a0016040516020818303038152906040528051906020012090505b949350505050565b600080612da5847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b60028101546fffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffff000000000000000000000000000000018101612e3d576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002820180547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff17905573ffffffffffffffffffffffffffffffffffffffff831660009081526003602052604081208054839290612eae908490613588565b9091555050505050565b600081612f57846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611612f98576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fa18361307f565b905081613040826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16116130795761307661305d836001613588565b6fffffffffffffffffffffffffffffffff83169061312b565b90505b92915050565b60008119600183011681613113827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b6000806131b8847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050808303600180821b0385821b179250505092915050565b50805460008255906000526020600020908101906131f991906131fc565b50565b5b8082111561321157600081556001016131fd565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b602081016003831061327f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806040838503121561329857600080fd5b50508035926020909101359150565b6000815180845260005b818110156132cd576020818501810151868301820152016132b1565b818111156132df576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061307660208301846132a7565b73ffffffffffffffffffffffffffffffffffffffff811681146131f957600080fd5b60006020828403121561335957600080fd5b813561336481613325565b9392505050565b8035801515811461337b57600080fd5b919050565b60008060006060848603121561339557600080fd5b83359250602084013591506133ac6040850161336b565b90509250925092565b6000602082840312156133c757600080fd5b81356fffffffffffffffffffffffffffffffff8116811461336457600080fd5b6000602082840312156133f957600080fd5b5035919050565b60008083601f84011261341257600080fd5b50813567ffffffffffffffff81111561342a57600080fd5b60208301915083602082850101111561344257600080fd5b9250929050565b6000806000806000806080878903121561346257600080fd5b863595506134726020880161336b565b9450604087013567ffffffffffffffff8082111561348f57600080fd5b61349b8a838b01613400565b909650945060608901359150808211156134b457600080fd5b506134c189828a01613400565b979a9699509497509295939492505050565b6000806000606084860312156134e857600080fd5b505081359360208301359350604090920135919050565b60ff8416815282602082015260606040820152600061352160608301846132a7565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561359b5761359b613559565b500190565b6000828210156135b2576135b2613559565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826135f5576135f56135b7565b500690565b60006fffffffffffffffffffffffffffffffff8381169083168181101561362357613623613559565b039392505050565b60006fffffffffffffffffffffffffffffffff80831681851680830382111561365657613656613559565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6060815260006136cc60608301878961366f565b82810360208401526136df81868861366f565b9150508260408301529695505050505050565b60006020828403121561370457600080fd5b5051919050565b600067ffffffffffffffff8381169083168181101561362357613623613559565b600067ffffffffffffffff80841680613747576137476135b7565b92169190910692915050565b60006020828403121561376557600080fd5b815161336481613325565b600067ffffffffffffffff80831681851680830382111561365657613656613559565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036137c4576137c4613559565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c634300080f000a000000000000000000000000000000000000000000000000000000000000000003c7ae758795765c6664a5d39bf63841c71ff191e9189522bad8ebff5d4eca9800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000004b00000000000000000000000008e3d2585592ec53538bb9d07e72f4ee9fb5c26ef

Deployed Bytecode

0x6080604052600436106101cd5760003560e01c80638d450a95116100f7578063d5d44d8011610095578063f8f43ff611610064578063f8f43ff614610694578063fa24f743146106b4578063fa315aa9146106d8578063fdffbb281461070b57600080fd5b8063d5d44d80146105e1578063d8cc1a3c1461060e578063e1f0c3761461062e578063ec5e63081461066157600080fd5b8063c395e1ca116100d1578063c395e1ca14610502578063c55cd0c714610523578063c6f0308c14610536578063cf09e0d0146105c057600080fd5b80638d450a9514610454578063bbdc02db14610487578063bcef3b55146104c557600080fd5b8063609d33341161016f57806368800abf1161013e57806368800abf146103c45780638129fc1c146103f75780638980e0cc146103ff5780638b85902b1461041457600080fd5b8063609d33341461036657806360e274641461037b578063632247ea1461039b5780636361506d146103ae57600080fd5b80632810e1d6116101ab5780632810e1d61461029557806335fef567146102aa5780633a768463146102bf57806354fd4d501461031057600080fd5b80630356fe3a146101d257806319effeb414610214578063200d2ed21461025a575b600080fd5b3480156101de57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040519081526020015b60405180910390f35b34801561022057600080fd5b506000546102419068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161020b565b34801561026657600080fd5b5060005461028890700100000000000000000000000000000000900460ff1681565b60405161020b9190613244565b3480156102a157600080fd5b5061028861071e565b6102bd6102b8366004613285565b61091b565b005b3480156102cb57600080fd5b5060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000008e3d2585592ec53538bb9d07e72f4ee9fb5c26ef16815260200161020b565b34801561031c57600080fd5b506103596040518060400160405280600681526020017f302e302e3234000000000000000000000000000000000000000000000000000081525081565b60405161020b9190613312565b34801561037257600080fd5b5061035961092b565b34801561038757600080fd5b506102bd610396366004613347565b61093d565b6102bd6103a9366004613380565b6109ed565b3480156103ba57600080fd5b5061020160015481565b3480156103d057600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610201565b6102bd6111e8565b34801561040b57600080fd5b50600254610201565b34801561042057600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360200135610201565b34801561046057600080fd5b507f03c7ae758795765c6664a5d39bf63841c71ff191e9189522bad8ebff5d4eca98610201565b34801561049357600080fd5b5060405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161020b565b3480156104d157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335610201565b34801561050e57600080fd5b5061020161051d3660046133b5565b50600090565b6102bd610531366004613285565b61150e565b34801561054257600080fd5b506105566105513660046133e7565b61151a565b6040805163ffffffff909816885273ffffffffffffffffffffffffffffffffffffffff968716602089015295909416948601949094526fffffffffffffffffffffffffffffffff9182166060860152608085015291821660a08401521660c082015260e00161020b565b3480156105cc57600080fd5b506000546102419067ffffffffffffffff1681565b3480156105ed57600080fd5b506102016105fc366004613347565b60036020526000908152604090205481565b34801561061a57600080fd5b506102bd610629366004613449565b6115b1565b34801561063a57600080fd5b507f00000000000000000000000000000000000000000000000000000000000004b0610241565b34801561066d57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000e610201565b3480156106a057600080fd5b506102bd6106af3660046134d3565b611b8f565b3480156106c057600080fd5b506106c9611ff8565b60405161020b939291906134ff565b3480156106e457600080fd5b507f000000000000000000000000000000000000000000000000000000000000002c610201565b6102bd6107193660046133e7565b612055565b600080600054700100000000000000000000000000000000900460ff16600281111561074c5761074c613215565b14610783576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60065460ff166107bf576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660026000815481106107eb576107eb61352a565b6000918252602090912060059091020154640100000000900473ffffffffffffffffffffffffffffffffffffffff1614610826576001610829565b60025b6000805467ffffffffffffffff421668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff82168117835592935083927fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffff000000000000000000ffffffffffffffff909116177001000000000000000000000000000000008360028111156108da576108da613215565b0217905560028111156108ef576108ef613215565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a290565b610927828260006109ed565b5050565b606061093860208061241c565b905090565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260036020526040808220805490839055905190929083908381818185875af1925050503d80600081146109a8576040519150601f19603f3d011682016040523d82523d6000602084013e6109ad565b606091505b50509050806109e8576040517f83e6cc6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b60008054700100000000000000000000000000000000900460ff166002811115610a1957610a19613215565b14610a50576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110610a6557610a6561352a565b600091825260208083206040805160e0810182526005909402909101805463ffffffff808216865273ffffffffffffffffffffffffffffffffffffffff6401000000009092048216948601949094526001820154169184019190915260028101546fffffffffffffffffffffffffffffffff90811660608501526003820154608085015260049091015480821660a0850181905270010000000000000000000000000000000090910490911660c0840152919350909190610b2a90839086906124b316565b90506000610bca826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050861580610c0c5750610c097f000000000000000000000000000000000000000000000000000000000000000e6002613588565b81145b8015610c16575084155b15610c4d576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000002c811115610ca7576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cd27f000000000000000000000000000000000000000000000000000000000000000e6001613588565b8103610ce457610ce4868885886124bb565b835160009063ffffffff90811614610d44576002856000015163ffffffff1681548110610d1357610d1361352a565b906000526020600020906005020160040160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b60c0850151600090610d689067ffffffffffffffff165b67ffffffffffffffff1690565b67ffffffffffffffff1642610d92610d5b856fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610da69190613588565b610db091906135a0565b90507f00000000000000000000000000000000000000000000000000000000000004b060011c677fffffffffffffff1667ffffffffffffffff82161115610e23576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b421760008a8152608087901b6fffffffffffffffffffffffffffffffff8d1617602052604081209192509060008181526004602052604090205490915060ff1615610ea1576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016004600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060026040518060e001604052808d63ffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001346fffffffffffffffffffffffffffffffff1681526020018c8152602001886fffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906005020160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160020160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506080820151816003015560a08201518160040160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160040160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050503360028c815481106111265761112661352a565b60009182526020808320600592830201805473ffffffffffffffffffffffffffffffffffffffff95909516640100000000027fffffffffffffffff0000000000000000000000000000000000000000ffffffff909516949094179093558d82529091526040902060025461119c906001906135a0565b8154600181018355600092835260208320015560405133918c918e917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a45050505050505050505050565b600654610100900460ff161561122a576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360200135116112e1576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560048201526024015b60405180910390fd5b60463611156112f85763c407e0256000526004601cfd5b6040805160e08101825263ffffffff8152600060208201523291810191909152346fffffffffffffffffffffffffffffffff16606082015260029060808101367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335815260016020820152604001426fffffffffffffffffffffffffffffffff90811690915282546001808201855560009485526020808620855160059094020180549186015163ffffffff9094167fffffffffffffffff0000000000000000000000000000000000000000000000009092169190911764010000000073ffffffffffffffffffffffffffffffffffffffff94851602178155604085015181830180547fffffffffffffffffffffffff000000000000000000000000000000000000000016919094161790925560608401516002830180547fffffffffffffffffffffffffffffffff00000000000000000000000000000000169185169190911790556080840151600383015560a084015160c09094015193831670010000000000000000000000000000000094909316939093029190911760049091015581547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff16179091556114dc90436135a0565b40600155600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b610927828260016109ed565b6002818154811061152a57600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015463ffffffff8416955064010000000090930473ffffffffffffffffffffffffffffffffffffffff908116949216926fffffffffffffffffffffffffffffffff91821692918082169170010000000000000000000000000000000090041687565b60008054700100000000000000000000000000000000900460ff1660028111156115dd576115dd613215565b14611614576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600287815481106116295761162961352a565b6000918252602082206005919091020160048101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506116887f000000000000000000000000000000000000000000000000000000000000002c6001613588565b611724826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1614611765576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808915611854576117b87f000000000000000000000000000000000000000000000000000000000000000e7f000000000000000000000000000000000000000000000000000000000000002c6135a0565b6001901b6117d7846fffffffffffffffffffffffffffffffff16612673565b67ffffffffffffffff166117eb91906135e6565b156118285761181f61181060016fffffffffffffffffffffffffffffffff87166135fa565b865463ffffffff166000612719565b6003015461184a565b7f03c7ae758795765c6664a5d39bf63841c71ff191e9189522bad8ebff5d4eca985b915084905061187e565b6003850154915061187b6118106fffffffffffffffffffffffffffffffff8616600161362b565b90505b600882901b60088a8a60405161189592919061365f565b6040518091039020901b146118d6576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006118e18c6127fd565b905060006118f0836003015490565b6040517fe14ced320000000000000000000000000000000000000000000000000000000081527f0000000000000000000000008e3d2585592ec53538bb9d07e72f4ee9fb5c26ef73ffffffffffffffffffffffffffffffffffffffff169063e14ced329061196a908f908f908f908f908a906004016136b8565b6020604051808303816000875af1158015611989573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ad91906136f2565b600485015491149150600090600290611a58906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b611af4896fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b611afe919061370b565b611b08919061372c565b67ffffffffffffffff161590508115158103611b50576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505085547fffffffffffffffff0000000000000000000000000000000000000000ffffffff163364010000000002179095555050505050505050505050565b60008054700100000000000000000000000000000000900460ff166002811115611bbb57611bbb613215565b14611bf2576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600080611c018661282c565b93509350935093506000611c1785858585612c59565b905060007f0000000000000000000000008e3d2585592ec53538bb9d07e72f4ee9fb5c26ef73ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611caa9190613753565b905060018903611d725773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a846001545b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260048101939093526024830191909152604482015260206064820152608481018a905260a4015b6020604051808303816000875af1158015611d48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6c91906136f2565b50611fed565b60028903611d9e5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8489611cd6565b60038903611dca5773ffffffffffffffffffffffffffffffffffffffff81166352f0f3ad8a8487611cd6565b60048903611f425760006fffffffffffffffffffffffffffffffff861615611e6257611e286fffffffffffffffffffffffffffffffff87167f000000000000000000000000000000000000000000000000000000000000000e612d18565b611e52907f0000000000000000000000000000000000000000000000000000000000000000613588565b611e5d906001613588565b611e84565b7f00000000000000000000000000000000000000000000000000000000000000005b905073ffffffffffffffffffffffffffffffffffffffff82166352f0f3ad8b8560405160e084901b7fffffffff000000000000000000000000000000000000000000000000000000001681526004810192909252602482015260c084901b604482015260086064820152608481018b905260a4016020604051808303816000875af1158015611f17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f3b91906136f2565b5050611fed565b60058903611fbb576040517f52f0f3ad000000000000000000000000000000000000000000000000000000008152600481018a9052602481018390524660c01b6044820152600860648201526084810188905273ffffffffffffffffffffffffffffffffffffffff8216906352f0f3ad9060a401611d29565b6040517fff137e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335606061204e61092b565b9050909192565b60008054700100000000000000000000000000000000900460ff16600281111561208157612081613215565b146120b8576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600282815481106120cd576120cd61352a565b60009182526020822060059190910201600481015490925061210f90700100000000000000000000000000000000900460401c67ffffffffffffffff16610d5b565b600483015490915060009061214190700100000000000000000000000000000000900467ffffffffffffffff16610d5b565b61214b904261370b565b9050677fffffffffffffff7f00000000000000000000000000000000000000000000000000000000000004b060011c166121858284613770565b67ffffffffffffffff16116121c6576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526005602052604090208054851580156121e6575060065460ff165b1561221d576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8015801561222a57508515155b1561225c5760018501546122549073ffffffffffffffffffffffffffffffffffffffff1686612dcd565b505050505050565b6000805b8281101561233b57600084828154811061227c5761227c61352a565b60009182526020808320909101548083526005909152604090912054909150156122d2576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600282815481106122e7576122e761352a565b600091825260209091206005909102018054909150640100000000900473ffffffffffffffffffffffffffffffffffffffff1661232857339350505061233b565b50508061233490613793565b9050612260565b5061238373ffffffffffffffffffffffffffffffffffffffff821615612361578161237d565b600187015473ffffffffffffffffffffffffffffffffffffffff165b87612dcd565b85547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff83160217865560008781526005602052604081206123df916131db565b8660000361241357600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b50505050505050565b6060600061245384367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003613588565b90508267ffffffffffffffff1667ffffffffffffffff811115612478576124786137cb565b6040519080825280601f01601f1916602001820160405280156124a2576020820181803683370190505b509150828160208401375092915050565b151760011b90565b60006124da6fffffffffffffffffffffffffffffffff8416600161362b565b905060006124ea82866001612719565b9050600086901a83806125dd575061252360027f000000000000000000000000000000000000000000000000000000000000000e6135e6565b60048301546002906125c7906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6125d1919061372c565b67ffffffffffffffff16145b156126355760ff8116600114806125f7575060ff81166002145b612630576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016112d8565b612413565b60ff811615612413576040517ff40239db000000000000000000000000000000000000000000000000000000008152600481018890526024016112d8565b600080612700837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b600080826127625761275d6fffffffffffffffffffffffffffffffff86167f000000000000000000000000000000000000000000000000000000000000000e612eb8565b61277d565b61277d856fffffffffffffffffffffffffffffffff1661307f565b9050600284815481106127925761279261352a565b906000526020600020906005020191505b60048201546fffffffffffffffffffffffffffffffff8281169116146127f557815460028054909163ffffffff169081106127e0576127e061352a565b906000526020600020906005020191506127a3565b509392505050565b600080600080600061280e8661282c565b935093509350935061282284848484612c59565b9695505050505050565b600080600080600085905060006002828154811061284c5761284c61352a565b600091825260209091206004600590920201908101549091507f000000000000000000000000000000000000000000000000000000000000000e90612923906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611612964576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815b60048301547f000000000000000000000000000000000000000000000000000000000000000e90612a2b906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169250821115612aa757825463ffffffff16612a717f000000000000000000000000000000000000000000000000000000000000000e6001613588565b8303612a7b578391505b60028181548110612a8e57612a8e61352a565b9060005260206000209060050201935080945050612968565b600481810154908401546fffffffffffffffffffffffffffffffff91821691166000816fffffffffffffffffffffffffffffffff16612b10612afb856fffffffffffffffffffffffffffffffff1660011c90565b6fffffffffffffffffffffffffffffffff1690565b6fffffffffffffffffffffffffffffffff161490508015612bf5576000612b48836fffffffffffffffffffffffffffffffff16612673565b67ffffffffffffffff161115612bab576000612b82612b7a60016fffffffffffffffffffffffffffffffff86166135fa565b896001612719565b6003810154600490910154909c506fffffffffffffffffffffffffffffffff169a50612bcf9050565b7f00000000000000000000000000000000000000000000000000000000000000009a505b600386015460048701549099506fffffffffffffffffffffffffffffffff169750612c4b565b6000612c17612b7a6fffffffffffffffffffffffffffffffff8516600161362b565b6003808901546004808b015492840154930154909e506fffffffffffffffffffffffffffffffff9182169d50919b50169850505b505050505050509193509193565b60006fffffffffffffffffffffffffffffffff84168103612cbf578282604051602001612ca29291909182526fffffffffffffffffffffffffffffffff16602082015260400190565b604051602081830303815290604052805190602001209050612d10565b60408051602081018790526fffffffffffffffffffffffffffffffff8087169282019290925260608101859052908316608082015260a0016040516020818303038152906040528051906020012090505b949350505050565b600080612da5847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b60028101546fffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffff000000000000000000000000000000018101612e3d576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002820180547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff17905573ffffffffffffffffffffffffffffffffffffffff831660009081526003602052604081208054839290612eae908490613588565b9091555050505050565b600081612f57846fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1611612f98576040517fb34b5c2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fa18361307f565b905081613040826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16116130795761307661305d836001613588565b6fffffffffffffffffffffffffffffffff83169061312b565b90505b92915050565b60008119600183011681613113827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b6000806131b8847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050808303600180821b0385821b179250505092915050565b50805460008255906000526020600020908101906131f991906131fc565b50565b5b8082111561321157600081556001016131fd565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b602081016003831061327f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000806040838503121561329857600080fd5b50508035926020909101359150565b6000815180845260005b818110156132cd576020818501810151868301820152016132b1565b818111156132df576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061307660208301846132a7565b73ffffffffffffffffffffffffffffffffffffffff811681146131f957600080fd5b60006020828403121561335957600080fd5b813561336481613325565b9392505050565b8035801515811461337b57600080fd5b919050565b60008060006060848603121561339557600080fd5b83359250602084013591506133ac6040850161336b565b90509250925092565b6000602082840312156133c757600080fd5b81356fffffffffffffffffffffffffffffffff8116811461336457600080fd5b6000602082840312156133f957600080fd5b5035919050565b60008083601f84011261341257600080fd5b50813567ffffffffffffffff81111561342a57600080fd5b60208301915083602082850101111561344257600080fd5b9250929050565b6000806000806000806080878903121561346257600080fd5b863595506134726020880161336b565b9450604087013567ffffffffffffffff8082111561348f57600080fd5b61349b8a838b01613400565b909650945060608901359150808211156134b457600080fd5b506134c189828a01613400565b979a9699509497509295939492505050565b6000806000606084860312156134e857600080fd5b505081359360208301359350604090920135919050565b60ff8416815282602082015260606040820152600061352160608301846132a7565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561359b5761359b613559565b500190565b6000828210156135b2576135b2613559565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826135f5576135f56135b7565b500690565b60006fffffffffffffffffffffffffffffffff8381169083168181101561362357613623613559565b039392505050565b60006fffffffffffffffffffffffffffffffff80831681851680830382111561365657613656613559565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6060815260006136cc60608301878961366f565b82810360208401526136df81868861366f565b9150508260408301529695505050505050565b60006020828403121561370457600080fd5b5051919050565b600067ffffffffffffffff8381169083168181101561362357613623613559565b600067ffffffffffffffff80841680613747576137476135b7565b92169190910692915050565b60006020828403121561376557600080fd5b815161336481613325565b600067ffffffffffffffff80831681851680830382111561365657613656613559565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036137c4576137c4613559565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c634300080f000a

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

000000000000000000000000000000000000000000000000000000000000000003c7ae758795765c6664a5d39bf63841c71ff191e9189522bad8ebff5d4eca9800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000004b00000000000000000000000008e3d2585592ec53538bb9d07e72f4ee9fb5c26ef

-----Decoded View---------------
Arg [0] : _gameType (uint8): 0
Arg [1] : _absolutePrestate (bytes32): 0x03c7ae758795765c6664a5d39bf63841c71ff191e9189522bad8ebff5d4eca98
Arg [2] : _genesisBlockNumber (uint256): 0
Arg [3] : _genesisOutputRoot (bytes32): 0x0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : _maxGameDepth (uint256): 44
Arg [5] : _splitDepth (uint256): 14
Arg [6] : _gameDuration (uint64): 1200
Arg [7] : _vm (address): 0x8E3d2585592EC53538bB9d07e72F4eE9Fb5c26ef

-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [1] : 03c7ae758795765c6664a5d39bf63841c71ff191e9189522bad8ebff5d4eca98
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 000000000000000000000000000000000000000000000000000000000000002c
Arg [5] : 000000000000000000000000000000000000000000000000000000000000000e
Arg [6] : 00000000000000000000000000000000000000000000000000000000000004b0
Arg [7] : 0000000000000000000000008e3d2585592ec53538bb9d07e72f4ee9fb5c26ef


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits

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.