Contract Address Details
contract

0x6DC852a4949E0deeD6b892d266169B4f16EE093b

Sponsored: 

Overview

OWCT Balance

0 OWCT

OWCT Value

$

Token Holdings

Fetching tokens...

More Info

Private Name Tags

Last Balance Update

Blocks Validated

Sponsored

Contract name:
PolygonZkEVMGlobalExitRootV2




Optimization enabled
true
Compiler version
v0.8.20+commit.a1b79de6




Optimization runs
999999
Verified at
2025-01-22T04:21:54.224276Z

Constructor Arguments

0000000000000000000000009d2dcf86e9ca815ba0010bf9644b488ad0dc39580000000000000000000000007376998677f02ed611ff976b9d7f19b193951bde

Arg [0] (address) : 0x9d2dcf86e9ca815ba0010bf9644b488ad0dc3958
Arg [1] (address) : 0x7376998677f02ed611ff976b9d7f19b193951bde

              

contracts/v2/PolygonZkEVMGlobalExitRootV2.sol

// SPDX-License-Identifier: AGPL-3.0

pragma solidity 0.8.20;

import "./interfaces/IPolygonZkEVMGlobalExitRootV2.sol";
import "./lib/PolygonZkEVMGlobalExitRootBaseStorage.sol";
import "../lib/GlobalExitRootLib.sol";
import "./lib/DepositContractBase.sol";

/**
 * Contract responsible for managing the exit roots across multiple networks
 */
contract PolygonZkEVMGlobalExitRootV2 is
    PolygonZkEVMGlobalExitRootBaseStorage,
    DepositContractBase
{
    // PolygonZkEVMBridge address
    address public immutable bridgeAddress;

    // Rollup manager contract address
    address public immutable rollupManager;

    /**
     * @dev Emitted when the global exit root is updated
     */
    event UpdateL1InfoTree(
        bytes32 indexed mainnetExitRoot,
        bytes32 indexed rollupExitRoot
    );

    /**
     * @param _rollupManager Rollup manager contract address
     * @param _bridgeAddress PolygonZkEVMBridge contract address
     */
    constructor(address _rollupManager, address _bridgeAddress) {
        rollupManager = _rollupManager;
        bridgeAddress = _bridgeAddress;
    }

    /**
     * @notice Update the exit root of one of the networks and the global exit root
     * @param newRoot new exit tree root
     */
    function updateExitRoot(bytes32 newRoot) external {
        // Store storage variables into temporal variables since will be used multiple times
        bytes32 cacheLastRollupExitRoot;
        bytes32 cacheLastMainnetExitRoot;

        if (msg.sender == bridgeAddress) {
            lastMainnetExitRoot = newRoot;
            cacheLastMainnetExitRoot = newRoot;
            cacheLastRollupExitRoot = lastRollupExitRoot;
        } else if (msg.sender == rollupManager) {
            lastRollupExitRoot = newRoot;
            cacheLastRollupExitRoot = newRoot;
            cacheLastMainnetExitRoot = lastMainnetExitRoot;
        } else {
            revert OnlyAllowedContracts();
        }

        bytes32 newGlobalExitRoot = GlobalExitRootLib.calculateGlobalExitRoot(
            cacheLastMainnetExitRoot,
            cacheLastRollupExitRoot
        );

        // If it already exists, do not modify the blockhash
        if (globalExitRootMap[newGlobalExitRoot] == 0) {
            uint256 lastBlockHash = uint256(blockhash(block.number - 1));
            globalExitRootMap[newGlobalExitRoot] = lastBlockHash;

            // save new leaf in L1InfoTree
            _addLeaf(
                getLeafValue(
                    newGlobalExitRoot,
                    lastBlockHash,
                    uint64(block.timestamp)
                )
            );

            emit UpdateL1InfoTree(
                cacheLastMainnetExitRoot,
                cacheLastRollupExitRoot
            );
        }
    }

    /**
     * @notice Return last global exit root
     */
    function getLastGlobalExitRoot() public view returns (bytes32) {
        return
            GlobalExitRootLib.calculateGlobalExitRoot(
                lastMainnetExitRoot,
                lastRollupExitRoot
            );
    }

    /**
     * @notice Computes and returns the merkle root of the L1InfoTree
     */
    function getRoot()
        public
        view
        override(DepositContractBase, IPolygonZkEVMGlobalExitRootV2)
        returns (bytes32)
    {
        return super.getRoot();
    }

    /**
     * @notice Given the leaf data returns the leaf hash
     * @param newGlobalExitRoot Last global exit root
     * @param lastBlockHash Last accesible block hash
     * @param timestamp Ethereum timestamp in seconds
     */
    function getLeafValue(
        bytes32 newGlobalExitRoot,
        uint256 lastBlockHash,
        uint64 timestamp
    ) public pure returns (bytes32) {
        return
            keccak256(
                abi.encodePacked(newGlobalExitRoot, lastBlockHash, timestamp)
            );
    }
}
        

contracts/interfaces/IBasePolygonZkEVMGlobalExitRoot.sol

// SPDX-License-Identifier: AGPL-3.0

pragma solidity ^0.8.20;

interface IBasePolygonZkEVMGlobalExitRoot {
    /**
     * @dev Thrown when the caller is not the allowed contracts
     */
    error OnlyAllowedContracts();

    function updateExitRoot(bytes32 newRollupExitRoot) external;

    function globalExitRootMap(
        bytes32 globalExitRootNum
    ) external returns (uint256);
}
          

contracts/lib/GlobalExitRootLib.sol

// SPDX-License-Identifier: AGPL-3.0

pragma solidity 0.8.20;

/**
 * @dev A library that provides the necessary calculations to calculate the global exit root
 */
library GlobalExitRootLib {
    function calculateGlobalExitRoot(
        bytes32 mainnetExitRoot,
        bytes32 rollupExitRoot
    ) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked(mainnetExitRoot, rollupExitRoot));
    }
}
          

contracts/v2/interfaces/IPolygonZkEVMGlobalExitRootV2.sol

// SPDX-License-Identifier: AGPL-3.0

pragma solidity ^0.8.20;
import "../../interfaces/IBasePolygonZkEVMGlobalExitRoot.sol";

interface IPolygonZkEVMGlobalExitRootV2 is IBasePolygonZkEVMGlobalExitRoot {
    function getLastGlobalExitRoot() external view returns (bytes32);

    function getRoot() external view returns (bytes32);
}
          

contracts/v2/lib/DepositContractBase.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.20;

/**
 * This contract will be used as a helper for all the sparse merkle tree related functions
 * Based on the implementation of the deposit eth2.0 contract https://github.com/ethereum/consensus-specs/blob/dev/solidity_deposit_contract/deposit_contract.sol
 */
contract DepositContractBase {
    /**
     * @dev Thrown when the merkle tree is full
     */
    error MerkleTreeFull();

    // Merkle tree levels
    uint256 internal constant _DEPOSIT_CONTRACT_TREE_DEPTH = 32;

    // This ensures `depositCount` will fit into 32-bits
    uint256 internal constant _MAX_DEPOSIT_COUNT =
        2 ** _DEPOSIT_CONTRACT_TREE_DEPTH - 1;

    // Branch array which contains the necessary sibilings to compute the next root when a new
    // leaf is inserted
    bytes32[_DEPOSIT_CONTRACT_TREE_DEPTH] internal _branch;

    // Counter of current deposits
    uint256 public depositCount;

    /**
     * @dev This empty reserved space is put in place to allow future versions to add new
     * variables without shifting down storage in the inheritance chain.
     */
    uint256[10] private _gap;

    /**
     * @notice Computes and returns the merkle root
     */
    function getRoot() public view virtual returns (bytes32) {
        bytes32 node;
        uint256 size = depositCount;
        bytes32 currentZeroHashHeight = 0;

        for (
            uint256 height = 0;
            height < _DEPOSIT_CONTRACT_TREE_DEPTH;
            height++
        ) {
            if (((size >> height) & 1) == 1)
                node = keccak256(abi.encodePacked(_branch[height], node));
            else
                node = keccak256(abi.encodePacked(node, currentZeroHashHeight));

            currentZeroHashHeight = keccak256(
                abi.encodePacked(currentZeroHashHeight, currentZeroHashHeight)
            );
        }
        return node;
    }

    /**
     * @notice Add a new leaf to the merkle tree
     * @param leaf Leaf
     */
    function _addLeaf(bytes32 leaf) internal {
        bytes32 node = leaf;

        // Avoid overflowing the Merkle tree (and prevent edge case in computing `_branch`)
        if (depositCount >= _MAX_DEPOSIT_COUNT) {
            revert MerkleTreeFull();
        }

        // Add deposit data root to Merkle tree (update a single `_branch` node)
        uint256 size = ++depositCount;
        for (
            uint256 height = 0;
            height < _DEPOSIT_CONTRACT_TREE_DEPTH;
            height++
        ) {
            if (((size >> height) & 1) == 1) {
                _branch[height] = node;
                return;
            }
            node = keccak256(abi.encodePacked(_branch[height], node));
        }
        // As the loop should always end prematurely with the `return` statement,
        // this code should be unreachable. We assert `false` just to be safe.
        assert(false);
    }

    /**
     * @notice Verify merkle proof
     * @param leafHash Leaf hash
     * @param smtProof Smt proof
     * @param index Index of the leaf
     * @param root Merkle root
     */
    function verifyMerkleProof(
        bytes32 leafHash,
        bytes32[_DEPOSIT_CONTRACT_TREE_DEPTH] calldata smtProof,
        uint32 index,
        bytes32 root
    ) public pure returns (bool) {
        return calculateRoot(leafHash, smtProof, index) == root;
    }

    /**
     * @notice Calculate root from merkle proof
     * @param leafHash Leaf hash
     * @param smtProof Smt proof
     * @param index Index of the leaf
     */
    function calculateRoot(
        bytes32 leafHash,
        bytes32[_DEPOSIT_CONTRACT_TREE_DEPTH] calldata smtProof,
        uint32 index
    ) public pure returns (bytes32) {
        bytes32 node = leafHash;

        // Compute root
        for (
            uint256 height = 0;
            height < _DEPOSIT_CONTRACT_TREE_DEPTH;
            height++
        ) {
            if (((index >> height) & 1) == 1)
                node = keccak256(abi.encodePacked(smtProof[height], node));
            else node = keccak256(abi.encodePacked(node, smtProof[height]));
        }

        return node;
    }
}
          

contracts/v2/lib/PolygonZkEVMGlobalExitRootBaseStorage.sol

// SPDX-License-Identifier: AGPL-3.0

pragma solidity ^0.8.20;
import "../interfaces/IPolygonZkEVMGlobalExitRootV2.sol";

/**
 * Since the current contract of PolygonZkEVMGlobalExitRoot will be upgraded to a PolygonZkEVMGlobalExitRootV2, and it will implement
 * the DepositContractBase, this base is needed to preserve the previous storage slots
 */
abstract contract PolygonZkEVMGlobalExitRootBaseStorage is
    IPolygonZkEVMGlobalExitRootV2
{
    // Rollup root, contains all exit roots of all rollups
    bytes32 public lastRollupExitRoot;

    // Mainnet exit root, this will be updated every time a deposit is made in mainnet
    bytes32 public lastMainnetExitRoot;

    // Store every global exit root: Root --> blockhash
    // Note that previously recoded global exit roots in previous versions, timestamp was recorded instead of blockhash
    mapping(bytes32 => uint256) public globalExitRootMap;
}
          

Compiler Settings

{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata","storageLayout"],"":["ast"]}},"optimizer":{"runs":999999,"enabled":true},"libraries":{},"evmVersion":"paris"}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_rollupManager","internalType":"address"},{"type":"address","name":"_bridgeAddress","internalType":"address"}]},{"type":"error","name":"MerkleTreeFull","inputs":[]},{"type":"error","name":"OnlyAllowedContracts","inputs":[]},{"type":"event","name":"UpdateL1InfoTree","inputs":[{"type":"bytes32","name":"mainnetExitRoot","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"rollupExitRoot","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"bridgeAddress","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"calculateRoot","inputs":[{"type":"bytes32","name":"leafHash","internalType":"bytes32"},{"type":"bytes32[32]","name":"smtProof","internalType":"bytes32[32]"},{"type":"uint32","name":"index","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"depositCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getLastGlobalExitRoot","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getLeafValue","inputs":[{"type":"bytes32","name":"newGlobalExitRoot","internalType":"bytes32"},{"type":"uint256","name":"lastBlockHash","internalType":"uint256"},{"type":"uint64","name":"timestamp","internalType":"uint64"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getRoot","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"globalExitRootMap","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"lastMainnetExitRoot","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"lastRollupExitRoot","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"rollupManager","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateExitRoot","inputs":[{"type":"bytes32","name":"newRoot","internalType":"bytes32"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"verifyMerkleProof","inputs":[{"type":"bytes32","name":"leafHash","internalType":"bytes32"},{"type":"bytes32[32]","name":"smtProof","internalType":"bytes32[32]"},{"type":"uint32","name":"index","internalType":"uint32"},{"type":"bytes32","name":"root","internalType":"bytes32"}]}]
              

Contract Creation Code

0x60c060405234801561001057600080fd5b50604051610b3c380380610b3c83398101604081905261002f91610062565b6001600160a01b0391821660a05216608052610095565b80516001600160a01b038116811461005d57600080fd5b919050565b6000806040838503121561007557600080fd5b61007e83610046565b915061008c60208401610046565b90509250929050565b60805160a051610a746100c86000396000818161014901526102c401526000818161021801526102770152610a746000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806349b7b8021161008157806383f244031161005b57806383f2440314610200578063a3c573eb14610213578063fb5708341461023a57600080fd5b806349b7b802146101445780635ca1e165146101905780635d8105011461019857600080fd5b8063319cf735116100b2578063319cf7351461011e57806333d6247d146101275780633ed691ef1461013c57600080fd5b806301fd9044146100d9578063257b3632146100f55780632dfdf0b514610115575b600080fd5b6100e260005481565b6040519081526020015b60405180910390f35b6100e2610103366004610722565b60026020526000908152604090205481565b6100e260235481565b6100e260015481565b61013a610135366004610722565b61025d565b005b6100e2610406565b61016b7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ec565b6100e261041b565b6100e26101a636600461073b565b604080516020808201959095528082019390935260c09190911b7fffffffffffffffff0000000000000000000000000000000000000000000000001660608301528051604881840301815260689092019052805191012090565b6100e261020e3660046107ac565b610425565b61016b7f000000000000000000000000000000000000000000000000000000000000000081565b61024d6102483660046107eb565b6104fb565b60405190151581526020016100ec565b60008073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633036102ad57505060018190556000548161032d565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633036102fb5750506000819055600154819061032d565b6040517fb49365dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103398284610513565b6000818152600260205260408120549192500361040057600061035d600143610862565b60008381526002602090815260409182902092409283905581518082018690528083018490527fffffffffffffffff0000000000000000000000000000000000000000000000004260c01b16606082015282518082036048018152606890910190925281519101209091506103d190610542565b604051849084907fda61aa7823fcd807e37b95aabcbe17f03a6f3efd514176444dae191d27fd66b390600090a3505b50505050565b6000610416600154600054610513565b905090565b6000610416610645565b600083815b60208110156104f257600163ffffffff8516821c811690036104955784816020811061045857610458610875565b602002013582604051602001610478929190918252602082015260400190565b6040516020818303038152906040528051906020012091506104e0565b818582602081106104a8576104a8610875565b60200201356040516020016104c7929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b806104ea816108a4565b91505061042a565b50949350505050565b600081610509868686610425565b1495945050505050565b604080516020808201859052818301849052825180830384018152606090920190925280519101205b92915050565b806001610551602060026109fc565b61055b9190610862565b60235410610595576040517fef5ccf6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006023600081546105a6906108a4565b9182905550905060005b6020811015610637578082901c6001166001036105e35782600382602081106105db576105db610875565b015550505050565b600381602081106105f6576105f6610875565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250808061062f906108a4565b9150506105b0565b50610640610a0f565b505050565b602354600090819081805b6020811015610719578083901c6001166001036106ad576003816020811061067a5761067a610875565b015460408051602081019290925281018590526060016040516020818303038152906040528051906020012093506106da565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b60408051602081018490529081018390526060016040516020818303038152906040528051906020012091508080610711906108a4565b915050610650565b50919392505050565b60006020828403121561073457600080fd5b5035919050565b60008060006060848603121561075057600080fd5b8335925060208401359150604084013567ffffffffffffffff8116811461077657600080fd5b809150509250925092565b80610400810183101561053c57600080fd5b803563ffffffff811681146107a757600080fd5b919050565b600080600061044084860312156107c257600080fd5b833592506107d38560208601610781565b91506107e26104208501610793565b90509250925092565b600080600080610460858703121561080257600080fd5b843593506108138660208701610781565b92506108226104208601610793565b939692955092936104400135925050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561053c5761053c610833565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036108d5576108d5610833565b5060010190565b600181815b8085111561093557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561091b5761091b610833565b8085161561092857918102915b93841c93908002906108e1565b509250929050565b60008261094c5750600161053c565b816109595750600061053c565b816001811461096f576002811461097957610995565b600191505061053c565b60ff84111561098a5761098a610833565b50506001821b61053c565b5060208310610133831016604e8410600b84101617156109b8575081810a61053c565b6109c283836108dc565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156109f4576109f4610833565b029392505050565b6000610a08838361093d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea2646970667358221220dbd1e7b3ff384ef35ee296421e7bc2bb2c5279b9abce68d63bcc855e92d1bdc264736f6c634300081400330000000000000000000000009d2dcf86e9ca815ba0010bf9644b488ad0dc39580000000000000000000000007376998677f02ed611ff976b9d7f19b193951bde

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106100d45760003560e01c806349b7b8021161008157806383f244031161005b57806383f2440314610200578063a3c573eb14610213578063fb5708341461023a57600080fd5b806349b7b802146101445780635ca1e165146101905780635d8105011461019857600080fd5b8063319cf735116100b2578063319cf7351461011e57806333d6247d146101275780633ed691ef1461013c57600080fd5b806301fd9044146100d9578063257b3632146100f55780632dfdf0b514610115575b600080fd5b6100e260005481565b6040519081526020015b60405180910390f35b6100e2610103366004610722565b60026020526000908152604090205481565b6100e260235481565b6100e260015481565b61013a610135366004610722565b61025d565b005b6100e2610406565b61016b7f0000000000000000000000009d2dcf86e9ca815ba0010bf9644b488ad0dc395881565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ec565b6100e261041b565b6100e26101a636600461073b565b604080516020808201959095528082019390935260c09190911b7fffffffffffffffff0000000000000000000000000000000000000000000000001660608301528051604881840301815260689092019052805191012090565b6100e261020e3660046107ac565b610425565b61016b7f0000000000000000000000007376998677f02ed611ff976b9d7f19b193951bde81565b61024d6102483660046107eb565b6104fb565b60405190151581526020016100ec565b60008073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007376998677f02ed611ff976b9d7f19b193951bde1633036102ad57505060018190556000548161032d565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000009d2dcf86e9ca815ba0010bf9644b488ad0dc39581633036102fb5750506000819055600154819061032d565b6040517fb49365dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103398284610513565b6000818152600260205260408120549192500361040057600061035d600143610862565b60008381526002602090815260409182902092409283905581518082018690528083018490527fffffffffffffffff0000000000000000000000000000000000000000000000004260c01b16606082015282518082036048018152606890910190925281519101209091506103d190610542565b604051849084907fda61aa7823fcd807e37b95aabcbe17f03a6f3efd514176444dae191d27fd66b390600090a3505b50505050565b6000610416600154600054610513565b905090565b6000610416610645565b600083815b60208110156104f257600163ffffffff8516821c811690036104955784816020811061045857610458610875565b602002013582604051602001610478929190918252602082015260400190565b6040516020818303038152906040528051906020012091506104e0565b818582602081106104a8576104a8610875565b60200201356040516020016104c7929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b806104ea816108a4565b91505061042a565b50949350505050565b600081610509868686610425565b1495945050505050565b604080516020808201859052818301849052825180830384018152606090920190925280519101205b92915050565b806001610551602060026109fc565b61055b9190610862565b60235410610595576040517fef5ccf6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006023600081546105a6906108a4565b9182905550905060005b6020811015610637578082901c6001166001036105e35782600382602081106105db576105db610875565b015550505050565b600381602081106105f6576105f6610875565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250808061062f906108a4565b9150506105b0565b50610640610a0f565b505050565b602354600090819081805b6020811015610719578083901c6001166001036106ad576003816020811061067a5761067a610875565b015460408051602081019290925281018590526060016040516020818303038152906040528051906020012093506106da565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b60408051602081018490529081018390526060016040516020818303038152906040528051906020012091508080610711906108a4565b915050610650565b50919392505050565b60006020828403121561073457600080fd5b5035919050565b60008060006060848603121561075057600080fd5b8335925060208401359150604084013567ffffffffffffffff8116811461077657600080fd5b809150509250925092565b80610400810183101561053c57600080fd5b803563ffffffff811681146107a757600080fd5b919050565b600080600061044084860312156107c257600080fd5b833592506107d38560208601610781565b91506107e26104208501610793565b90509250925092565b600080600080610460858703121561080257600080fd5b843593506108138660208701610781565b92506108226104208601610793565b939692955092936104400135925050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561053c5761053c610833565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036108d5576108d5610833565b5060010190565b600181815b8085111561093557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561091b5761091b610833565b8085161561092857918102915b93841c93908002906108e1565b509250929050565b60008261094c5750600161053c565b816109595750600061053c565b816001811461096f576002811461097957610995565b600191505061053c565b60ff84111561098a5761098a610833565b50506001821b61053c565b5060208310610133831016604e8410600b84101617156109b8575081810a61053c565b6109c283836108dc565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156109f4576109f4610833565b029392505050565b6000610a08838361093d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea2646970667358221220dbd1e7b3ff384ef35ee296421e7bc2bb2c5279b9abce68d63bcc855e92d1bdc264736f6c63430008140033