ETH Price: $3,327.16 (+1.96%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

> 10 Internal Transactions found.

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer*242387662026-01-15 7:57:592 days ago1768463879
0xc4444C5D...589DcAF22
0 ETH
Transfer*242387662026-01-15 7:57:592 days ago1768463879
0xc4444C5D...589DcAF22
0 ETH
Transfer*242387662026-01-15 7:57:592 days ago1768463879
0xc4444C5D...589DcAF22
0 ETH
Transfer*242387662026-01-15 7:57:592 days ago1768463879
0xc4444C5D...589DcAF22
0 ETH
Transfer*242387662026-01-15 7:57:592 days ago1768463879
0xc4444C5D...589DcAF22
0 ETH
Transfer*242387662026-01-15 7:57:592 days ago1768463879
0xc4444C5D...589DcAF22
0 ETH
Transfer*242387662026-01-15 7:57:592 days ago1768463879
0xc4444C5D...589DcAF22
0 ETH
Transfer*242387662026-01-15 7:57:592 days ago1768463879
0xc4444C5D...589DcAF22
0 ETH
Transfer*242387662026-01-15 7:57:592 days ago1768463879
0xc4444C5D...589DcAF22
0 ETH
Transfer*242387662026-01-15 7:57:592 days ago1768463879
0xc4444C5D...589DcAF22
0 ETH
Merkleize Pendin...242387662026-01-15 7:57:592 days ago1768463879
0xc4444C5D...589DcAF22
0 ETH
Transfer*241749252026-01-06 10:05:3511 days ago1767693935
0xc4444C5D...589DcAF22
0 ETH
Transfer*241749252026-01-06 10:05:3511 days ago1767693935
0xc4444C5D...589DcAF22
0 ETH
Transfer*241749252026-01-06 10:05:3511 days ago1767693935
0xc4444C5D...589DcAF22
0 ETH
Transfer*241749252026-01-06 10:05:3511 days ago1767693935
0xc4444C5D...589DcAF22
0 ETH
Transfer*241749252026-01-06 10:05:3511 days ago1767693935
0xc4444C5D...589DcAF22
0 ETH
Transfer*241749252026-01-06 10:05:3511 days ago1767693935
0xc4444C5D...589DcAF22
0 ETH
Transfer*241749252026-01-06 10:05:3511 days ago1767693935
0xc4444C5D...589DcAF22
0 ETH
Transfer*241749252026-01-06 10:05:3511 days ago1767693935
0xc4444C5D...589DcAF22
0 ETH
Transfer*241749252026-01-06 10:05:3511 days ago1767693935
0xc4444C5D...589DcAF22
0 ETH
Transfer*241749252026-01-06 10:05:3511 days ago1767693935
0xc4444C5D...589DcAF22
0 ETH
Transfer*241749252026-01-06 10:05:3511 days ago1767693935
0xc4444C5D...589DcAF22
0 ETH
Transfer*241749252026-01-06 10:05:3511 days ago1767693935
0xc4444C5D...589DcAF22
0 ETH
Transfer*241749252026-01-06 10:05:3511 days ago1767693935
0xc4444C5D...589DcAF22
0 ETH
Transfer*241749252026-01-06 10:05:3511 days ago1767693935
0xc4444C5D...589DcAF22
0 ETH
View All Internal Transactions
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

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

Contract Source Code Verified (Exact Match)

Contract Name:
BeaconProofs

Compiler Version
v0.8.28+commit.7893614a

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import { BeaconProofsLib } from "./BeaconProofsLib.sol";
import { IBeaconProofs } from "../interfaces/IBeaconProofs.sol";

/**
 * @title Verifies merkle proofs of beacon chain data.
 * @author Origin Protocol Inc
 */
contract BeaconProofs is IBeaconProofs {
    /// @notice Verifies the validator index is for the given validator public key.
    /// Also verify the validator's withdrawal credential points to the withdrawal address.
    /// BeaconBlock.state.validators[validatorIndex].pubkey
    /// @param beaconBlockRoot The root of the beacon block
    /// @param pubKeyHash Hash of validator's public key using the Beacon Chain's format
    /// @param proof The merkle proof for the validator public key to the beacon block root.
    /// This is 53 witness hashes of 32 bytes each concatenated together starting from the leaf node.
    /// @param validatorIndex The validator index
    /// @param withdrawalCredentials a value containing the validator type and withdrawal address.
    function verifyValidator(
        bytes32 beaconBlockRoot,
        bytes32 pubKeyHash,
        bytes calldata proof,
        uint40 validatorIndex,
        bytes32 withdrawalCredentials
    ) external view {
        BeaconProofsLib.verifyValidator(
            beaconBlockRoot,
            pubKeyHash,
            proof,
            validatorIndex,
            withdrawalCredentials
        );
    }

    function verifyValidatorWithdrawable(
        bytes32 beaconBlockRoot,
        uint40 validatorIndex,
        uint64 withdrawableEpoch,
        bytes calldata withdrawableEpochProof
    ) external view {
        BeaconProofsLib.verifyValidatorWithdrawableEpoch(
            beaconBlockRoot,
            validatorIndex,
            withdrawableEpoch,
            withdrawableEpochProof
        );
    }

    /// @notice Verifies the balances container to the beacon block root
    /// BeaconBlock.state.balances
    /// @param beaconBlockRoot The root of the beacon block
    /// @param balancesContainerRoot The merkle root of the the balances container
    /// @param balancesContainerProof The merkle proof for the balances container to the beacon block root.
    /// This is 9 witness hashes of 32 bytes each concatenated together starting from the leaf node.
    function verifyBalancesContainer(
        bytes32 beaconBlockRoot,
        bytes32 balancesContainerRoot,
        bytes calldata balancesContainerProof
    ) external view {
        BeaconProofsLib.verifyBalancesContainer(
            beaconBlockRoot,
            balancesContainerRoot,
            balancesContainerProof
        );
    }

    /// @notice Verifies the validator balance to the root of the Balances container.
    /// @param balancesContainerRoot The merkle root of the Balances container.
    /// @param validatorBalanceLeaf The leaf node containing the validator balance with three other balances.
    /// @param balanceProof The merkle proof for the validator balance to the Balances container root.
    /// This is 39 witness hashes of 32 bytes each concatenated together starting from the leaf node.
    /// @param validatorIndex The validator index to verify the balance for
    /// @return validatorBalanceGwei The balance in Gwei of the validator at the given index
    function verifyValidatorBalance(
        bytes32 balancesContainerRoot,
        bytes32 validatorBalanceLeaf,
        bytes calldata balanceProof,
        uint40 validatorIndex
    ) external view returns (uint256 validatorBalanceGwei) {
        validatorBalanceGwei = BeaconProofsLib.verifyValidatorBalance(
            balancesContainerRoot,
            validatorBalanceLeaf,
            balanceProof,
            validatorIndex
        );
    }

    /// @notice Verifies the pending deposits container to the beacon block root.
    /// BeaconBlock.state.pendingDeposits
    /// @param beaconBlockRoot The root of the beacon block.
    /// @param pendingDepositsContainerRoot The merkle root of the the pending deposits container.
    /// @param proof The merkle proof for the pending deposits container to the beacon block root.
    /// This is 9 witness hashes of 32 bytes each concatenated together starting from the leaf node.
    function verifyPendingDepositsContainer(
        bytes32 beaconBlockRoot,
        bytes32 pendingDepositsContainerRoot,
        bytes calldata proof
    ) external view {
        BeaconProofsLib.verifyPendingDepositsContainer(
            beaconBlockRoot,
            pendingDepositsContainerRoot,
            proof
        );
    }

    /// @notice Verified a pending deposit to the root of the Pending Deposits container.
    /// @param pendingDepositsContainerRoot The merkle root of the Pending Deposits container.
    /// @param pendingDepositRoot The leaf node containing the validator balance with three other balances.
    /// @param proof The merkle proof for the pending deposit root to the Pending Deposits container root.
    /// This is 28 witness hashes of 32 bytes each concatenated together starting from the leaf node.
    /// @param pendingDepositIndex The pending deposit index in the Pending Deposits container
    function verifyPendingDeposit(
        bytes32 pendingDepositsContainerRoot,
        bytes32 pendingDepositRoot,
        bytes calldata proof,
        uint32 pendingDepositIndex
    ) external view {
        BeaconProofsLib.verifyPendingDeposit(
            pendingDepositsContainerRoot,
            pendingDepositRoot,
            proof,
            pendingDepositIndex
        );
    }

    /// @notice If the deposit queue is not empty,
    /// verify the slot of the first pending deposit to the beacon block root.
    /// BeaconBlock.state.pendingDeposits[0].slot
    /// If the deposit queue is empty, verify the root of the first pending deposit is empty
    /// BeaconBlock.state.PendingDeposits[0]
    /// @param beaconBlockRoot The root of the beacon block.
    /// @param slot The beacon chain slot of the first deposit in the beacon chain's deposit queue.
    /// Can be anything if the deposit queue is empty.
    /// @param firstPendingDepositSlotProof The merkle proof to the beacon block root. Can be either:
    /// - 40 witness hashes for BeaconBlock.state.PendingDeposits[0].slot when the deposit queue is not empty.
    /// - 37 witness hashes for BeaconBlock.state.PendingDeposits[0] when the deposit queue is empty.
    /// The 32 byte witness hashes are concatenated together starting from the leaf node.
    /// @return isEmptyDepositQueue True if the deposit queue is empty, false otherwise.
    function verifyFirstPendingDeposit(
        bytes32 beaconBlockRoot,
        uint64 slot,
        bytes calldata firstPendingDepositSlotProof
    ) external view returns (bool isEmptyDepositQueue) {
        isEmptyDepositQueue = BeaconProofsLib.verifyFirstPendingDeposit(
            beaconBlockRoot,
            slot,
            firstPendingDepositSlotProof
        );
    }

    /// @notice Merkleizes a beacon chain pending deposit.
    /// @param pubKeyHash Hash of validator's public key using the Beacon Chain's format
    /// @param withdrawalCredentials The 32 byte withdrawal credentials.
    /// @param amountGwei The amount of the deposit in Gwei.
    /// @param signature The 96 byte BLS signature.
    /// @param slot The beacon chain slot the deposit was made in.
    /// @return root The merkle root of the pending deposit.
    function merkleizePendingDeposit(
        bytes32 pubKeyHash,
        bytes calldata withdrawalCredentials,
        uint64 amountGwei,
        bytes calldata signature,
        uint64 slot
    ) external pure returns (bytes32) {
        return
            BeaconProofsLib.merkleizePendingDeposit(
                pubKeyHash,
                withdrawalCredentials,
                amountGwei,
                signature,
                slot
            );
    }

    /// @notice Merkleizes a BLS signature used for validator deposits.
    /// @param signature The 96 byte BLS signature.
    /// @return root The merkle root of the signature.
    function merkleizeSignature(bytes calldata signature)
        external
        pure
        returns (bytes32 root)
    {
        return BeaconProofsLib.merkleizeSignature(signature);
    }
}

// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import { Merkle } from "./Merkle.sol";
import { Endian } from "./Endian.sol";

/**
 * @title Library to verify merkle proofs of beacon chain data.
 * @author Origin Protocol Inc
 */
library BeaconProofsLib {
    // Known generalized indices in the beacon block
    /// @dev BeaconBlock.state.PendingDeposits[0]
    /// Beacon block container: height 3, state at at index 3
    /// Beacon state container: height 6, pending deposits at index 34
    /// Pending deposits container: height 28, first deposit at index 0
    /// ((2 ^ 3 + 3) * 2 ^ 6 + 34) * 2 ^ 28 + 0 = 198105366528
    uint256 internal constant FIRST_PENDING_DEPOSIT_GENERALIZED_INDEX =
        198105366528;
    /// @dev BeaconBlock.state.PendingDeposits[0].pubkey
    /// Pending Deposit container: height 3, pubkey at index 4
    /// (((2 ^ 3 + 3) * 2 ^ 6 + 34) * 2 ^ 28 + 0) * 2 ^ 3 + 4  = 1584842932228
    uint256 internal constant FIRST_PENDING_DEPOSIT_SLOT_GENERALIZED_INDEX =
        1584842932228;
    /// @dev BeaconBlock.state.validators
    /// Beacon block container: height 3, state at at index 3
    /// Beacon state container: height 6, validators at index 11
    /// (2 ^ 3 + 3) * 2 ^ 6 + 11 = 715
    uint256 internal constant VALIDATORS_CONTAINER_GENERALIZED_INDEX = 715;
    /// @dev BeaconBlock.state.balances
    /// Beacon block container: height 3, state at at index 3
    /// Beacon state container: height 6, balances at index 12
    /// (2 ^ 3 + 3) * 2 ^ 6 + 12 = 716
    uint256 internal constant BALANCES_CONTAINER_GENERALIZED_INDEX = 716;

    /// @dev BeaconBlock.state.pendingDeposits
    /// Beacon block container: height 3, state at at index 3
    /// Beacon state container: height 6, balances at index 34
    /// (2 ^ 3 + 3) * 2 ^ 6 + 34 = 738
    uint256 internal constant PENDING_DEPOSITS_CONTAINER_GENERALIZED_INDEX =
        738;

    /// @dev Number of bytes in the proof to the first pending deposit.
    /// 37 witness hashes of 32 bytes each concatenated together.
    /// BeaconBlock.state.PendingDeposits[0]
    /// 37 * 32 bytes = 1184 bytes
    uint256 internal constant FIRST_PENDING_DEPOSIT_PROOF_LENGTH = 1184;
    /// @dev Number of bytes in the proof from the slot of the first pending deposit to the beacon block root.
    /// 40 witness hashes of 32 bytes each concatenated together.
    /// BeaconBlock.state.PendingDeposits[0].slot
    /// 40 * 32 bytes = 1280 bytes
    uint256 internal constant FIRST_PENDING_DEPOSIT_SLOT_PROOF_LENGTH = 1280;

    /// @dev Merkle height of the Balances container
    /// BeaconBlock.state.balances
    uint256 internal constant BALANCES_HEIGHT = 39;
    /// @dev Merkle height of the Validators container list
    /// BeaconBlock.state.validators
    uint256 internal constant VALIDATORS_LIST_HEIGHT = 41;
    /// @dev Merkle height of the Pending Deposits container list
    /// BeaconBlock.state.pendingDeposits
    uint256 internal constant PENDING_DEPOSITS_LIST_HEIGHT = 28;
    /// @dev Merkle height of the Validator container
    /// BeaconBlock.state.validators[validatorIndex]
    uint256 internal constant VALIDATOR_CONTAINER_HEIGHT = 3;

    /// @dev Position of the pubkey field in the Validator container.
    /// BeaconBlock.state.validators[validatorIndex].pubkey
    uint256 internal constant VALIDATOR_PUBKEY_INDEX = 0;
    /// @dev Position of the withdrawable epoch field in the Validator container.
    /// BeaconBlock.state.validators[validatorIndex].withdrawableEpoch
    uint256 internal constant VALIDATOR_WITHDRAWABLE_EPOCH_INDEX = 7;

    /// @notice Verifies the validator index is for the given validator public key.
    /// Also verify the validator's withdrawal credential points to the withdrawal address.
    /// BeaconBlock.state.validators[validatorIndex].pubkey
    /// @param beaconBlockRoot The root of the beacon block
    /// @param pubKeyHash Hash of validator's public key using the Beacon Chain's format
    /// @param proof The merkle proof for the validator public key to the beacon block root.
    /// This is 53 witness hashes of 32 bytes each concatenated together starting from the leaf node.
    /// @param validatorIndex The validator index
    /// @param withdrawalCredentials a value containing the validator type and withdrawal address.
    function verifyValidator(
        bytes32 beaconBlockRoot,
        bytes32 pubKeyHash,
        bytes calldata proof,
        uint40 validatorIndex,
        bytes32 withdrawalCredentials
    ) internal view {
        require(beaconBlockRoot != bytes32(0), "Invalid block root");

        // BeaconBlock.state.validators[validatorIndex]
        uint256 generalizedIndex = concatGenIndices(
            VALIDATORS_CONTAINER_GENERALIZED_INDEX,
            VALIDATORS_LIST_HEIGHT,
            validatorIndex
        );
        // BeaconBlock.state.validators[validatorIndex].pubkey
        generalizedIndex = concatGenIndices(
            generalizedIndex,
            VALIDATOR_CONTAINER_HEIGHT,
            VALIDATOR_PUBKEY_INDEX
        );

        // Get the withdrawal credentials from the first witness in the pubkey merkle proof.
        bytes32 withdrawalCredentialsFromProof = bytes32(proof[:32]);

        require(
            withdrawalCredentialsFromProof == withdrawalCredentials,
            "Invalid withdrawal cred"
        );

        require(
            // 53 * 32 bytes = 1696 bytes
            proof.length == 1696 &&
                Merkle.verifyInclusionSha256({
                    proof: proof,
                    root: beaconBlockRoot,
                    leaf: pubKeyHash,
                    index: generalizedIndex
                }),
            "Invalid validator proof"
        );
    }

    /// @notice Verifies a validator's withdrawable epoch to the beacon block root
    /// for a given validator index.
    /// BeaconBlock.state.validators[validatorIndex].withdrawableEpoch
    /// @param beaconBlockRoot The root of the beacon block
    /// @param validatorIndex The validator index to verify the withdrawable epoch for.
    /// @param withdrawableEpoch The withdrawable epoch to verify in big endian uint64 format
    /// @param proof The merkle proof for the validator's withdrawable epoch to the beacon block root.
    /// This is 53 witness hashes of 32 bytes each concatenated together starting from the leaf node.
    function verifyValidatorWithdrawableEpoch(
        bytes32 beaconBlockRoot,
        uint40 validatorIndex,
        uint64 withdrawableEpoch,
        bytes calldata proof
    ) internal view {
        require(beaconBlockRoot != bytes32(0), "Invalid block root");

        // BeaconBlock.state.validators[validatorIndex]
        uint256 exitEpochGenIndex = concatGenIndices(
            VALIDATORS_CONTAINER_GENERALIZED_INDEX,
            VALIDATORS_LIST_HEIGHT,
            validatorIndex
        );
        // BeaconBlock.state.validators[validatorIndex].withdrawableEpoch
        exitEpochGenIndex = concatGenIndices(
            exitEpochGenIndex,
            VALIDATOR_CONTAINER_HEIGHT,
            VALIDATOR_WITHDRAWABLE_EPOCH_INDEX
        );

        require(
            // 53 * 32 bytes = 1696 bytes
            proof.length == 1696 &&
                Merkle.verifyInclusionSha256({
                    proof: proof,
                    root: beaconBlockRoot,
                    leaf: Endian.toLittleEndianUint64(withdrawableEpoch),
                    index: exitEpochGenIndex
                }),
            "Invalid withdrawable proof"
        );
    }

    /// @notice Verifies the balances container to the beacon block root.
    /// BeaconBlock.state.balances
    /// @param beaconBlockRoot The root of the beacon block.
    /// @param balancesContainerRoot The merkle root of the the balances container.
    /// @param proof The merkle proof for the balances container to the beacon block root.
    /// This is 9 witness hashes of 32 bytes each concatenated together starting from the leaf node.
    function verifyBalancesContainer(
        bytes32 beaconBlockRoot,
        bytes32 balancesContainerRoot,
        bytes calldata proof
    ) internal view {
        require(beaconBlockRoot != bytes32(0), "Invalid block root");

        // BeaconBlock.state.balances
        require(
            // 9 * 32 bytes = 288 bytes
            proof.length == 288 &&
                Merkle.verifyInclusionSha256({
                    proof: proof,
                    root: beaconBlockRoot,
                    leaf: balancesContainerRoot,
                    index: BALANCES_CONTAINER_GENERALIZED_INDEX
                }),
            "Invalid balance container proof"
        );
    }

    /// @notice Verifies the validator balance to the root of the Balances container.
    /// @param balancesContainerRoot The merkle root of the Balances container.
    /// @param validatorBalanceLeaf The leaf node containing the validator balance with three other balances.
    /// @param proof The merkle proof for the validator balance to the Balances container root.
    /// This is 39 witness hashes of 32 bytes each concatenated together starting from the leaf node.
    /// @param validatorIndex The validator index to verify the balance for.
    /// @return validatorBalanceGwei The balance in Gwei of the validator at the given index.
    function verifyValidatorBalance(
        bytes32 balancesContainerRoot,
        bytes32 validatorBalanceLeaf,
        bytes calldata proof,
        uint40 validatorIndex
    ) internal view returns (uint256 validatorBalanceGwei) {
        require(balancesContainerRoot != bytes32(0), "Invalid container root");

        // Four balances are stored in each leaf so the validator index is divided by 4
        uint64 balanceIndex = validatorIndex / 4;

        // Get the index within the balances container, not the Beacon Block
        // BeaconBlock.state.balances[balanceIndex]
        uint256 generalizedIndex = concatGenIndices(
            1,
            BALANCES_HEIGHT,
            balanceIndex
        );

        validatorBalanceGwei = balanceAtIndex(
            validatorBalanceLeaf,
            validatorIndex
        );

        require(
            // 39 * 32 bytes = 1248 bytes
            proof.length == 1248 &&
                Merkle.verifyInclusionSha256({
                    proof: proof,
                    root: balancesContainerRoot,
                    leaf: validatorBalanceLeaf,
                    index: generalizedIndex
                }),
            "Invalid balance proof"
        );
    }

    /// @notice Verifies the pending deposits container to the beacon block root.
    /// BeaconBlock.state.pendingDeposits
    /// @param beaconBlockRoot The root of the beacon block.
    /// @param pendingDepositsContainerRoot The merkle root of the the pending deposits container.
    /// @param proof The merkle proof for the pending deposits container to the beacon block root.
    /// This is 9 witness hashes of 32 bytes each concatenated together starting from the leaf node.
    function verifyPendingDepositsContainer(
        bytes32 beaconBlockRoot,
        bytes32 pendingDepositsContainerRoot,
        bytes calldata proof
    ) internal view {
        require(beaconBlockRoot != bytes32(0), "Invalid block root");

        // BeaconBlock.state.pendingDeposits
        require(
            // 9 * 32 bytes = 288 bytes
            proof.length == 288 &&
                Merkle.verifyInclusionSha256({
                    proof: proof,
                    root: beaconBlockRoot,
                    leaf: pendingDepositsContainerRoot,
                    index: PENDING_DEPOSITS_CONTAINER_GENERALIZED_INDEX
                }),
            "Invalid deposit container proof"
        );
    }

    /// @notice Verifies a pending deposit in the pending deposits container.
    /// BeaconBlock.state.pendingDeposits[depositIndex]
    /// @param pendingDepositsContainerRoot The merkle root of the pending deposits list container
    /// @param pendingDepositRoot The merkle root of the pending deposit to verify
    /// @param proof The merkle proof for the pending deposit root to the pending deposits list container root.
    /// This is 28 witness hashes of 32 bytes each concatenated together starting from the leaf node.
    /// @param pendingDepositIndex The index in the pending deposits list container for the deposit to verify.
    function verifyPendingDeposit(
        bytes32 pendingDepositsContainerRoot,
        bytes32 pendingDepositRoot,
        bytes calldata proof,
        uint32 pendingDepositIndex
    ) internal view {
        require(pendingDepositsContainerRoot != bytes32(0), "Invalid root");
        // ssz-merkleizing a list which has a variable length, an additional
        // sha256(pending_deposits_root, pending_deposits_length) operation is done to get the
        // actual pending deposits root so the max pending deposit index is 2^(28 - 1)
        require(
            pendingDepositIndex < 2**(PENDING_DEPOSITS_LIST_HEIGHT - 1),
            "Invalid deposit index"
        );

        // BeaconBlock.state.pendingDeposits[depositIndex]
        uint256 generalizedIndex = concatGenIndices(
            1,
            PENDING_DEPOSITS_LIST_HEIGHT,
            pendingDepositIndex
        );

        require(
            // 28 * 32 bytes = 896 bytes
            proof.length == 896 &&
                Merkle.verifyInclusionSha256({
                    proof: proof,
                    root: pendingDepositsContainerRoot,
                    leaf: pendingDepositRoot,
                    index: generalizedIndex
                }),
            "Invalid deposit proof"
        );
    }

    /// @notice If the deposit queue is not empty,
    /// verify the slot of the first pending deposit to the beacon block root.
    /// BeaconBlock.state.pendingDeposits[0].slot
    /// If the deposit queue is empty, verify the root of the first pending deposit is empty
    /// BeaconBlock.state.PendingDeposits[0]
    /// @param beaconBlockRoot The root of the beacon block.
    /// @param slot The beacon chain slot of the first deposit in the beacon chain's deposit queue.
    /// Can be anything if the deposit queue is empty.
    /// @param proof The merkle proof to the beacon block root. Can be either:
    /// - 40 witness hashes for BeaconBlock.state.PendingDeposits[0].slot when the deposit queue is not empty.
    /// - 37 witness hashes for BeaconBlock.state.PendingDeposits[0] when the deposit queue is empty.
    /// The 32 byte witness hashes are concatenated together starting from the leaf node.
    /// @return isEmptyDepositQueue True if the deposit queue is empty, false otherwise.
    function verifyFirstPendingDeposit(
        bytes32 beaconBlockRoot,
        uint64 slot,
        bytes calldata proof
    ) internal view returns (bool isEmptyDepositQueue) {
        require(beaconBlockRoot != bytes32(0), "Invalid block root");

        // If the deposit queue is empty
        if (proof.length == FIRST_PENDING_DEPOSIT_PROOF_LENGTH) {
            require(
                Merkle.verifyInclusionSha256({
                    proof: proof,
                    root: beaconBlockRoot,
                    leaf: bytes32(0),
                    index: FIRST_PENDING_DEPOSIT_GENERALIZED_INDEX
                }),
                "Invalid empty deposits proof"
            );
            return true;
        }

        // Verify the public key of the first pending deposit
        // BeaconBlock.state.PendingDeposits[0].slot
        require(
            proof.length == FIRST_PENDING_DEPOSIT_SLOT_PROOF_LENGTH &&
                Merkle.verifyInclusionSha256({
                    proof: proof,
                    root: beaconBlockRoot,
                    leaf: Endian.toLittleEndianUint64(slot),
                    index: FIRST_PENDING_DEPOSIT_SLOT_GENERALIZED_INDEX
                }),
            "Invalid deposit slot proof"
        );
    }

    /// @notice Merkleizes a beacon chain pending deposit.
    /// @param pubKeyHash Hash of validator's public key using the Beacon Chain's format
    /// @param withdrawalCredentials The 32 byte withdrawal credentials.
    /// @param amountGwei The amount of the deposit in Gwei.
    /// @param signature The 96 byte BLS signature.
    /// @param slot The beacon chain slot the deposit was made in.
    /// @return root The merkle root of the pending deposit.
    function merkleizePendingDeposit(
        bytes32 pubKeyHash,
        bytes calldata withdrawalCredentials,
        uint64 amountGwei,
        bytes calldata signature,
        uint64 slot
    ) internal pure returns (bytes32 root) {
        bytes32[] memory leaves = new bytes32[](8);
        leaves[0] = pubKeyHash;
        leaves[1] = bytes32(withdrawalCredentials[:32]);
        leaves[2] = Endian.toLittleEndianUint64(amountGwei);
        leaves[3] = merkleizeSignature(signature);
        leaves[4] = Endian.toLittleEndianUint64(slot);
        leaves[5] = bytes32(0);
        leaves[6] = bytes32(0);
        leaves[7] = bytes32(0);

        root = Merkle.merkleizeSha256(leaves);
    }

    /// @notice Merkleizes a BLS signature used for validator deposits.
    /// @param signature The 96 byte BLS signature.
    /// @return root The merkle root of the signature.
    function merkleizeSignature(bytes calldata signature)
        internal
        pure
        returns (bytes32)
    {
        require(signature.length == 96, "Invalid signature");

        bytes32[] memory leaves = new bytes32[](4);
        leaves[0] = bytes32(signature[:32]);
        leaves[1] = bytes32(signature[32:64]);
        leaves[2] = bytes32(signature[64:96]);
        leaves[3] = bytes32(0);

        return Merkle.merkleizeSha256(leaves);
    }

    ////////////////////////////////////////////////////
    ///       Internal Helper Functions
    ////////////////////////////////////////////////////

    function balanceAtIndex(bytes32 validatorBalanceLeaf, uint40 validatorIndex)
        internal
        pure
        returns (uint256)
    {
        uint256 bitShiftAmount = (validatorIndex % 4) * 64;
        return
            Endian.fromLittleEndianUint64(
                bytes32((uint256(validatorBalanceLeaf) << bitShiftAmount))
            );
    }

    /// @notice Concatenates two beacon chain generalized indices into one.
    /// @param genIndex The first generalized index or 1 if calculating for a single container.
    /// @param height The merkle tree height of the second container. eg 39 for balances, 41 for validators.
    /// @param index The index within the second container. eg the validator index.
    /// @return genIndex The concatenated generalized index.
    function concatGenIndices(
        uint256 genIndex,
        uint256 height,
        uint256 index
    ) internal pure returns (uint256) {
        return (genIndex << height) | index;
    }
}

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

/**
 * @title Library to handle conversion between little-endian and big-endian formats.
 * @author Origin Protocol Inc
 */
library Endian {
    /**
     * @notice Converts a little endian-formatted uint64 to a big endian-formatted uint64
     * @param lenum little endian-formatted uint64 input, provided as 'bytes32' type
     * @return n The big endian-formatted uint64
     * @dev Note that the input is formatted as a 'bytes32' type (i.e. 256 bits),
     * but it is immediately truncated to a uint64 (i.e. 64 bits)
     * through a right-shift/shr operation.
     */
    function fromLittleEndianUint64(bytes32 lenum)
        internal
        pure
        returns (uint64 n)
    {
        // the number needs to be stored in little-endian encoding (ie in bytes 0-8)
        n = uint64(uint256(lenum >> 192));
        // forgefmt: disable-next-item
        return
            (n >> 56) |
            ((0x00FF000000000000 & n) >> 40) |
            ((0x0000FF0000000000 & n) >> 24) |
            ((0x000000FF00000000 & n) >> 8) |
            ((0x00000000FF000000 & n) << 8) |
            ((0x0000000000FF0000 & n) << 24) |
            ((0x000000000000FF00 & n) << 40) |
            ((0x00000000000000FF & n) << 56);
    }

    function toLittleEndianUint64(uint64 benum)
        internal
        pure
        returns (bytes32 n)
    {
        // Convert to little-endian by reversing byte order
        uint64 reversed = (benum >> 56) |
            ((0x00FF000000000000 & benum) >> 40) |
            ((0x0000FF0000000000 & benum) >> 24) |
            ((0x000000FF00000000 & benum) >> 8) |
            ((0x00000000FF000000 & benum) << 8) |
            ((0x0000000000FF0000 & benum) << 24) |
            ((0x000000000000FF00 & benum) << 40) |
            ((0x00000000000000FF & benum) << 56);

        // Store the little-endian uint64 in the least significant 64 bits of bytes32
        n = bytes32(uint256(reversed));
        // Shift to most significant bits
        n = n << 192;
    }
}

// SPDX-License-Identifier: MIT
// Adapted from OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The tree and the proofs can be generated using our
 * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
 * You will find a quickstart guide in the readme.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 * OpenZeppelin's JavaScript library generates merkle trees that are safe
 * against this attack out of the box.
 */
library Merkle {
    error InvalidProofLength();

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. The tree is built assuming `leaf` is
     * the 0 indexed `index`'th leaf from the bottom left of the tree.
     *
     * Note this is for a Merkle tree using the sha256 hash function
     */
    function verifyInclusionSha256(
        bytes memory proof,
        bytes32 root,
        bytes32 leaf,
        uint256 index
    ) internal view returns (bool) {
        return processInclusionProofSha256(proof, leaf, index) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. The tree is built assuming `leaf` is
     * the 0 indexed `index`'th leaf from the bottom left of the tree.
     *
     * _Available since v4.4._
     *
     * Note this is for a Merkle tree using the sha256 hash function
     */
    function processInclusionProofSha256(
        bytes memory proof,
        bytes32 leaf,
        uint256 index
    ) internal view returns (bytes32) {
        require(
            proof.length != 0 && proof.length % 32 == 0,
            InvalidProofLength()
        );
        bytes32[1] memory computedHash = [leaf];
        for (uint256 i = 32; i <= proof.length; i += 32) {
            if (index % 2 == 0) {
                // if ith bit of index is 0, then computedHash is a left sibling
                // solhint-disable-next-line no-inline-assembly
                assembly {
                    mstore(0x00, mload(computedHash))
                    mstore(0x20, mload(add(proof, i)))
                    if iszero(
                        staticcall(
                            sub(gas(), 2000),
                            2,
                            0x00,
                            0x40,
                            computedHash,
                            0x20
                        )
                    ) {
                        revert(0, 0)
                    }
                }
            } else {
                // if ith bit of index is 1, then computedHash is a right sibling
                // solhint-disable-next-line no-inline-assembly
                assembly {
                    mstore(0x00, mload(add(proof, i)))
                    mstore(0x20, mload(computedHash))
                    if iszero(
                        staticcall(
                            sub(gas(), 2000),
                            2,
                            0x00,
                            0x40,
                            computedHash,
                            0x20
                        )
                    ) {
                        revert(0, 0)
                    }
                }
            }
            index = index / 2;
        }
        return computedHash[0];
    }

    /**
     * @notice Returns the merkle root of a tree created from a set of leaves using sha256 as its hash function.
     *  @param leaves the leaves of the merkle tree
     *  @return The computed Merkle root of the tree.
     *  @dev A pre-condition to this function is that leaves.length is a power of two.
     *  If not, the function will merkleize the inputs incorrectly.
     */
    function merkleizeSha256(bytes32[] memory leaves)
        internal
        pure
        returns (bytes32)
    {
        //there are half as many nodes in the layer above the leaves
        uint256 numNodesInLayer = leaves.length / 2;
        //create a layer to store the internal nodes
        bytes32[] memory layer = new bytes32[](numNodesInLayer);
        //fill the layer with the pairwise hashes of the leaves
        for (uint256 i = 0; i < numNodesInLayer; i++) {
            layer[i] = sha256(
                abi.encodePacked(leaves[2 * i], leaves[2 * i + 1])
            );
        }
        //the next layer above has half as many nodes
        numNodesInLayer /= 2;
        //while we haven't computed the root
        while (numNodesInLayer != 0) {
            //overwrite the first numNodesInLayer nodes in layer with the pairwise hashes of their children
            for (uint256 i = 0; i < numNodesInLayer; i++) {
                layer[i] = sha256(
                    abi.encodePacked(layer[2 * i], layer[2 * i + 1])
                );
            }
            //the next layer above has half as many nodes
            numNodesInLayer /= 2;
        }
        //the first node in the layer is the root
        return layer[0];
    }
}

// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

interface IBeaconProofs {
    function verifyValidator(
        bytes32 beaconBlockRoot,
        bytes32 pubKeyHash,
        bytes calldata validatorPubKeyProof,
        uint40 validatorIndex,
        bytes32 withdrawalCredentials
    ) external view;

    function verifyValidatorWithdrawable(
        bytes32 beaconBlockRoot,
        uint40 validatorIndex,
        uint64 withdrawableEpoch,
        bytes calldata withdrawableEpochProof
    ) external view;

    function verifyBalancesContainer(
        bytes32 beaconBlockRoot,
        bytes32 balancesContainerLeaf,
        bytes calldata balancesContainerProof
    ) external view;

    function verifyValidatorBalance(
        bytes32 balancesContainerRoot,
        bytes32 validatorBalanceLeaf,
        bytes calldata balanceProof,
        uint40 validatorIndex
    ) external view returns (uint256 validatorBalance);

    function verifyPendingDepositsContainer(
        bytes32 beaconBlockRoot,
        bytes32 pendingDepositsContainerRoot,
        bytes calldata proof
    ) external view;

    function verifyPendingDeposit(
        bytes32 pendingDepositsContainerRoot,
        bytes32 pendingDepositRoot,
        bytes calldata proof,
        uint32 pendingDepositIndex
    ) external view;

    function verifyFirstPendingDeposit(
        bytes32 beaconBlockRoot,
        uint64 slot,
        bytes calldata firstPendingDepositSlotProof
    ) external view returns (bool isEmptyDepositQueue);

    function merkleizePendingDeposit(
        bytes32 pubKeyHash,
        bytes calldata withdrawalCredentials,
        uint64 amountGwei,
        bytes calldata signature,
        uint64 slot
    ) external pure returns (bytes32 root);

    function merkleizeSignature(bytes calldata signature)
        external
        pure
        returns (bytes32 root);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "evmVersion": "paris",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"name":"InvalidProofLength","type":"error"},{"inputs":[{"internalType":"bytes32","name":"pubKeyHash","type":"bytes32"},{"internalType":"bytes","name":"withdrawalCredentials","type":"bytes"},{"internalType":"uint64","name":"amountGwei","type":"uint64"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint64","name":"slot","type":"uint64"}],"name":"merkleizePendingDeposit","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"merkleizeSignature","outputs":[{"internalType":"bytes32","name":"root","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"beaconBlockRoot","type":"bytes32"},{"internalType":"bytes32","name":"balancesContainerRoot","type":"bytes32"},{"internalType":"bytes","name":"balancesContainerProof","type":"bytes"}],"name":"verifyBalancesContainer","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"beaconBlockRoot","type":"bytes32"},{"internalType":"uint64","name":"slot","type":"uint64"},{"internalType":"bytes","name":"firstPendingDepositSlotProof","type":"bytes"}],"name":"verifyFirstPendingDeposit","outputs":[{"internalType":"bool","name":"isEmptyDepositQueue","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"pendingDepositsContainerRoot","type":"bytes32"},{"internalType":"bytes32","name":"pendingDepositRoot","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"},{"internalType":"uint32","name":"pendingDepositIndex","type":"uint32"}],"name":"verifyPendingDeposit","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"beaconBlockRoot","type":"bytes32"},{"internalType":"bytes32","name":"pendingDepositsContainerRoot","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"verifyPendingDepositsContainer","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"beaconBlockRoot","type":"bytes32"},{"internalType":"bytes32","name":"pubKeyHash","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"},{"internalType":"uint40","name":"validatorIndex","type":"uint40"},{"internalType":"bytes32","name":"withdrawalCredentials","type":"bytes32"}],"name":"verifyValidator","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"balancesContainerRoot","type":"bytes32"},{"internalType":"bytes32","name":"validatorBalanceLeaf","type":"bytes32"},{"internalType":"bytes","name":"balanceProof","type":"bytes"},{"internalType":"uint40","name":"validatorIndex","type":"uint40"}],"name":"verifyValidatorBalance","outputs":[{"internalType":"uint256","name":"validatorBalanceGwei","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"beaconBlockRoot","type":"bytes32"},{"internalType":"uint40","name":"validatorIndex","type":"uint40"},{"internalType":"uint64","name":"withdrawableEpoch","type":"uint64"},{"internalType":"bytes","name":"withdrawableEpochProof","type":"bytes"}],"name":"verifyValidatorWithdrawable","outputs":[],"stateMutability":"view","type":"function"}]

6080604052348015600f57600080fd5b5061178c8061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80638a050dd4116100665780638a050dd4146100f957806391ad640d1461010c578063afe768871461011f578063d98a556414610132578063f34ad34c1461015557600080fd5b8063258b83d8146100985780632b00e796146100be578063334a88fb146100d357806354ba95b2146100e6575b600080fd5b6100ab6100a6366004611112565b610168565b6040519081526020015b60405180910390f35b6100d16100cc366004611153565b61017d565b005b6100d16100e13660046111d6565b61018f565b6100d16100f4366004611244565b6101a3565b6100d16101073660046112b5565b6101b9565b6100d161011a366004611153565b6101c6565b6100ab61012d366004611328565b6101d2565b6101456101403660046113c7565b6101ef565b60405190151581526020016100b5565b6100ab610163366004611408565b610206565b6000610174838361021f565b90505b92915050565b61018984848484610365565b50505050565b61019c8585858585610420565b5050505050565b6101b18686868686866104f8565b505050505050565b61019c8585858585610638565b61018984848484610778565b60006101e388888888888888610833565b98975050505050505050565b60006101fd858585856109ab565b95945050505050565b60006102158686868686610b19565b9695505050505050565b60006060821461026a5760405162461bcd60e51b8152602060048201526011602482015270496e76616c6964207369676e617475726560781b60448201526064015b60405180910390fd5b60408051600480825260a082019092526000916020820160808036833701905050905061029b602060008587611485565b6102a4916114af565b816000815181106102b7576102b76114cd565b6020908102919091018101919091526102d4906040908587611485565b6102dd916114af565b816001815181106102f0576102f06114cd565b6020908102919091010152610309606060408587611485565b610312916114af565b81600281518110610325576103256114cd565b6020026020010181815250506000801b81600381518110610348576103486114cd565b60200260200101818152505061035d81610c2a565b949350505050565b836103825760405162461bcd60e51b8152600401610261906114e3565b610120811480156103d457506103d482828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508892508791506102e29050610ec3565b6101895760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964206465706f73697420636f6e7461696e65722070726f6f66006044820152606401610261565b8461043d5760405162461bcd60e51b8152600401610261906114e3565b600764ffffffffff851666059600000000001760031b176106a0821480156104ac57506104ac83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a92506104a69150889050610edb565b84610ec3565b6101b15760405162461bcd60e51b815260206004820152601a60248201527f496e76616c696420776974686472617761626c652070726f6f660000000000006044820152606401610261565b856105155760405162461bcd60e51b8152600401610261906114e3565b64ffffffffff821666059600000000001760031b60006105386020828789611485565b610541916114af565b90508281146105925760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207769746864726177616c20637265640000000000000000006044820152606401610261565b6106a0851480156105e257506105e286868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b9150869050610ec3565b61062e5760405162461bcd60e51b815260206004820152601760248201527f496e76616c69642076616c696461746f722070726f6f660000000000000000006044820152606401610261565b5050505050505050565b846106745760405162461bcd60e51b815260206004820152600c60248201526b125b9d985b1a59081c9bdbdd60a21b6044820152606401610261565b6106806001601c611525565b61068b90600261161f565b8163ffffffff16106106d75760405162461bcd60e51b8152602060048201526015602482015274092dcecc2d8d2c840c8cae0dee6d2e840d2dcc8caf605b1b6044820152606401610261565b63ffffffff811663100000001761038083148015610734575061073484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a9250899150859050610ec3565b6101b15760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103232b837b9b4ba10383937b7b360591b6044820152606401610261565b836107955760405162461bcd60e51b8152600401610261906114e3565b610120811480156107e757506107e782828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508892508791506102cc9050610ec3565b6101895760405162461bcd60e51b815260206004820152601f60248201527f496e76616c69642062616c616e636520636f6e7461696e65722070726f6f66006044820152606401610261565b60408051600880825261012082019092526000918291906020820161010080368337019050509050888160008151811061086f5761086f6114cd565b60209081029190910181019190915261088b906000898b611485565b610894916114af565b816001815181106108a7576108a76114cd565b6020026020010181815250506108bc86610edb565b816002815181106108cf576108cf6114cd565b6020026020010181815250506108e5858561021f565b816003815181106108f8576108f86114cd565b60200260200101818152505061090d83610edb565b81600481518110610920576109206114cd565b6020026020010181815250506000801b81600581518110610943576109436114cd565b6020026020010181815250506000801b81600681518110610966576109666114cd565b6020026020010181815250506000801b81600781518110610989576109896114cd565b60200260200101818152505061099e81610c2a565b9998505050505050505050565b6000846109ca5760405162461bcd60e51b8152600401610261906114e3565b61049f198201610a6f57610a1b83838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508a93509150642e200000009050610ec3565b610a675760405162461bcd60e51b815260206004820152601c60248201527f496e76616c696420656d707479206465706f736974732070726f6f66000000006044820152606401610261565b50600161035d565b61050082148015610acd5750610acd83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250899250610ac19150889050610edb565b65017100000004610ec3565b61035d5760405162461bcd60e51b815260206004820152601a60248201527f496e76616c6964206465706f73697420736c6f742070726f6f660000000000006044820152606401610261565b600085610b615760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a590818dbdb9d185a5b995c881c9bdbdd60521b6044820152606401610261565b6000610b6e600484611641565b64ffffffffff1690506480000000008117610b898785610f51565b92506104e085148015610bdb5750610bdb86868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b9150859050610ec3565b610c1f5760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103130b630b731b290383937b7b360591b6044820152606401610261565b505095945050505050565b60008060028351610c3b919061166b565b90506000816001600160401b03811115610c5757610c5761146f565b604051908082528060200260200182016040528015610c80578160200160208202803683370190505b50905060005b82811015610d7d57600285610c9b838361167f565b81518110610cab57610cab6114cd565b602002602001015186836002610cc1919061167f565b610ccc906001611696565b81518110610cdc57610cdc6114cd565b6020026020010151604051602001610cfe929190918252602082015260400190565b60408051601f1981840301815290829052610d18916116a9565b602060405180830381855afa158015610d35573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610d5891906116d8565b828281518110610d6a57610d6a6114cd565b6020908102919091010152600101610c86565b50610d8960028361166b565b91505b8115610e9f5760005b82811015610e8c57600282610daa838361167f565b81518110610dba57610dba6114cd565b602002602001015183836002610dd0919061167f565b610ddb906001611696565b81518110610deb57610deb6114cd565b6020026020010151604051602001610e0d929190918252602082015260400190565b60408051601f1981840301815290829052610e27916116a9565b602060405180830381855afa158015610e44573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610e6791906116d8565b828281518110610e7957610e796114cd565b6020908102919091010152600101610d95565b50610e9860028361166b565b9150610d8c565b80600081518110610eb257610eb26114cd565b602002602001015192505050919050565b600083610ed1868585610fed565b1495945050505050565b603881811c60ff16602883811c61ff001691909117601884811c62ff00001691909117600885811c63ff000000169190911764ff000000009186901b919091161765ff00000000009185901b919091161766ff0000000000009184901b919091161760ff60381b9290911b919091161760c01b90565b600080610f5f6004846116f1565b610f6a90604061171b565b64ffffffffff169050610fdc84821b60f881901c60e882901c61ff00161760d882901c62ff0000161760c882901c63ff000000161764ff0000000060b883901c161765ff000000000060a883901c161766ff000000000000609883901c161760ff60381b60889290921c919091161790565b6001600160401b0316949350505050565b6000835160001415801561100c57506020845161100a9190611742565b155b611029576040516313717da960e21b815260040160405180910390fd5b604080516020808201909252848152905b855181116110c05761104d600285611742565b60000361107d578151600052808601516020526020826040600060026107d05a03fa61107857600080fd5b6110a1565b8086015160005281516020526020826040600060026107d05a03fa6110a157600080fd5b6110ac60028561166b565b93506110b9602082611696565b905061103a565b5051949350505050565b60008083601f8401126110dc57600080fd5b5081356001600160401b038111156110f357600080fd5b60208301915083602082850101111561110b57600080fd5b9250929050565b6000806020838503121561112557600080fd5b82356001600160401b0381111561113b57600080fd5b611147858286016110ca565b90969095509350505050565b6000806000806060858703121561116957600080fd5b843593506020850135925060408501356001600160401b0381111561118d57600080fd5b611199878288016110ca565b95989497509550505050565b803564ffffffffff811681146111ba57600080fd5b919050565b80356001600160401b03811681146111ba57600080fd5b6000806000806000608086880312156111ee57600080fd5b853594506111fe602087016111a5565b935061120c604087016111bf565b925060608601356001600160401b0381111561122757600080fd5b611233888289016110ca565b969995985093965092949392505050565b60008060008060008060a0878903121561125d57600080fd5b863595506020870135945060408701356001600160401b0381111561128157600080fd5b61128d89828a016110ca565b90955093506112a09050606088016111a5565b95989497509295919493608090920135925050565b6000806000806000608086880312156112cd57600080fd5b853594506020860135935060408601356001600160401b038111156112f157600080fd5b6112fd888289016110ca565b909450925050606086013563ffffffff8116811461131a57600080fd5b809150509295509295909350565b600080600080600080600060a0888a03121561134357600080fd5b8735965060208801356001600160401b0381111561136057600080fd5b61136c8a828b016110ca565b909750955061137f9050604089016111bf565b935060608801356001600160401b0381111561139a57600080fd5b6113a68a828b016110ca565b90945092506113b99050608089016111bf565b905092959891949750929550565b600080600080606085870312156113dd57600080fd5b843593506113ed602086016111bf565b925060408501356001600160401b0381111561118d57600080fd5b60008060008060006080868803121561142057600080fd5b853594506020860135935060408601356001600160401b0381111561144457600080fd5b611450888289016110ca565b90945092506114639050606087016111a5565b90509295509295909350565b634e487b7160e01b600052604160045260246000fd5b6000808585111561149557600080fd5b838611156114a257600080fd5b5050820193919092039150565b8035602083101561017757600019602084900360031b1b1692915050565b634e487b7160e01b600052603260045260246000fd5b602080825260129082015271125b9d985b1a5908189b1bd8dac81c9bdbdd60721b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b818103818111156101775761017761150f565b6001815b6001841115611573578085048111156115575761155761150f565b600184161561156557908102905b60019390931c92800261153c565b935093915050565b60008261158a57506001610177565b8161159757506000610177565b81600181146115ad57600281146115b7576115d3565b6001915050610177565b60ff8411156115c8576115c861150f565b50506001821b610177565b5060208310610133831016604e8410600b84101617156115f6575081810a610177565b6116036000198484611538565b80600019048211156116175761161761150f565b029392505050565b6000610174838361157b565b634e487b7160e01b600052601260045260246000fd5b600064ffffffffff8316806116585761165861162b565b8064ffffffffff84160491505092915050565b60008261167a5761167a61162b565b500490565b80820281158282048414176101775761017761150f565b808201808211156101775761017761150f565b6000825160005b818110156116ca57602081860181015185830152016116b0565b506000920191825250919050565b6000602082840312156116ea57600080fd5b5051919050565b600064ffffffffff8316806117085761170861162b565b8064ffffffffff84160691505092915050565b64ffffffffff818116838216029081169081811461173b5761173b61150f565b5092915050565b6000826117515761175161162b565b50069056fea26469706673582212205e6c180b3544abbcda0a898d1a795e4ddbd861b7b533fbede356a76fa464c51064736f6c634300081c0033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100935760003560e01c80638a050dd4116100665780638a050dd4146100f957806391ad640d1461010c578063afe768871461011f578063d98a556414610132578063f34ad34c1461015557600080fd5b8063258b83d8146100985780632b00e796146100be578063334a88fb146100d357806354ba95b2146100e6575b600080fd5b6100ab6100a6366004611112565b610168565b6040519081526020015b60405180910390f35b6100d16100cc366004611153565b61017d565b005b6100d16100e13660046111d6565b61018f565b6100d16100f4366004611244565b6101a3565b6100d16101073660046112b5565b6101b9565b6100d161011a366004611153565b6101c6565b6100ab61012d366004611328565b6101d2565b6101456101403660046113c7565b6101ef565b60405190151581526020016100b5565b6100ab610163366004611408565b610206565b6000610174838361021f565b90505b92915050565b61018984848484610365565b50505050565b61019c8585858585610420565b5050505050565b6101b18686868686866104f8565b505050505050565b61019c8585858585610638565b61018984848484610778565b60006101e388888888888888610833565b98975050505050505050565b60006101fd858585856109ab565b95945050505050565b60006102158686868686610b19565b9695505050505050565b60006060821461026a5760405162461bcd60e51b8152602060048201526011602482015270496e76616c6964207369676e617475726560781b60448201526064015b60405180910390fd5b60408051600480825260a082019092526000916020820160808036833701905050905061029b602060008587611485565b6102a4916114af565b816000815181106102b7576102b76114cd565b6020908102919091018101919091526102d4906040908587611485565b6102dd916114af565b816001815181106102f0576102f06114cd565b6020908102919091010152610309606060408587611485565b610312916114af565b81600281518110610325576103256114cd565b6020026020010181815250506000801b81600381518110610348576103486114cd565b60200260200101818152505061035d81610c2a565b949350505050565b836103825760405162461bcd60e51b8152600401610261906114e3565b610120811480156103d457506103d482828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508892508791506102e29050610ec3565b6101895760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964206465706f73697420636f6e7461696e65722070726f6f66006044820152606401610261565b8461043d5760405162461bcd60e51b8152600401610261906114e3565b600764ffffffffff851666059600000000001760031b176106a0821480156104ac57506104ac83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a92506104a69150889050610edb565b84610ec3565b6101b15760405162461bcd60e51b815260206004820152601a60248201527f496e76616c696420776974686472617761626c652070726f6f660000000000006044820152606401610261565b856105155760405162461bcd60e51b8152600401610261906114e3565b64ffffffffff821666059600000000001760031b60006105386020828789611485565b610541916114af565b90508281146105925760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207769746864726177616c20637265640000000000000000006044820152606401610261565b6106a0851480156105e257506105e286868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b9150869050610ec3565b61062e5760405162461bcd60e51b815260206004820152601760248201527f496e76616c69642076616c696461746f722070726f6f660000000000000000006044820152606401610261565b5050505050505050565b846106745760405162461bcd60e51b815260206004820152600c60248201526b125b9d985b1a59081c9bdbdd60a21b6044820152606401610261565b6106806001601c611525565b61068b90600261161f565b8163ffffffff16106106d75760405162461bcd60e51b8152602060048201526015602482015274092dcecc2d8d2c840c8cae0dee6d2e840d2dcc8caf605b1b6044820152606401610261565b63ffffffff811663100000001761038083148015610734575061073484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a9250899150859050610ec3565b6101b15760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103232b837b9b4ba10383937b7b360591b6044820152606401610261565b836107955760405162461bcd60e51b8152600401610261906114e3565b610120811480156107e757506107e782828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508892508791506102cc9050610ec3565b6101895760405162461bcd60e51b815260206004820152601f60248201527f496e76616c69642062616c616e636520636f6e7461696e65722070726f6f66006044820152606401610261565b60408051600880825261012082019092526000918291906020820161010080368337019050509050888160008151811061086f5761086f6114cd565b60209081029190910181019190915261088b906000898b611485565b610894916114af565b816001815181106108a7576108a76114cd565b6020026020010181815250506108bc86610edb565b816002815181106108cf576108cf6114cd565b6020026020010181815250506108e5858561021f565b816003815181106108f8576108f86114cd565b60200260200101818152505061090d83610edb565b81600481518110610920576109206114cd565b6020026020010181815250506000801b81600581518110610943576109436114cd565b6020026020010181815250506000801b81600681518110610966576109666114cd565b6020026020010181815250506000801b81600781518110610989576109896114cd565b60200260200101818152505061099e81610c2a565b9998505050505050505050565b6000846109ca5760405162461bcd60e51b8152600401610261906114e3565b61049f198201610a6f57610a1b83838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508a93509150642e200000009050610ec3565b610a675760405162461bcd60e51b815260206004820152601c60248201527f496e76616c696420656d707479206465706f736974732070726f6f66000000006044820152606401610261565b50600161035d565b61050082148015610acd5750610acd83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250899250610ac19150889050610edb565b65017100000004610ec3565b61035d5760405162461bcd60e51b815260206004820152601a60248201527f496e76616c6964206465706f73697420736c6f742070726f6f660000000000006044820152606401610261565b600085610b615760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a590818dbdb9d185a5b995c881c9bdbdd60521b6044820152606401610261565b6000610b6e600484611641565b64ffffffffff1690506480000000008117610b898785610f51565b92506104e085148015610bdb5750610bdb86868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b9150859050610ec3565b610c1f5760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103130b630b731b290383937b7b360591b6044820152606401610261565b505095945050505050565b60008060028351610c3b919061166b565b90506000816001600160401b03811115610c5757610c5761146f565b604051908082528060200260200182016040528015610c80578160200160208202803683370190505b50905060005b82811015610d7d57600285610c9b838361167f565b81518110610cab57610cab6114cd565b602002602001015186836002610cc1919061167f565b610ccc906001611696565b81518110610cdc57610cdc6114cd565b6020026020010151604051602001610cfe929190918252602082015260400190565b60408051601f1981840301815290829052610d18916116a9565b602060405180830381855afa158015610d35573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610d5891906116d8565b828281518110610d6a57610d6a6114cd565b6020908102919091010152600101610c86565b50610d8960028361166b565b91505b8115610e9f5760005b82811015610e8c57600282610daa838361167f565b81518110610dba57610dba6114cd565b602002602001015183836002610dd0919061167f565b610ddb906001611696565b81518110610deb57610deb6114cd565b6020026020010151604051602001610e0d929190918252602082015260400190565b60408051601f1981840301815290829052610e27916116a9565b602060405180830381855afa158015610e44573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610e6791906116d8565b828281518110610e7957610e796114cd565b6020908102919091010152600101610d95565b50610e9860028361166b565b9150610d8c565b80600081518110610eb257610eb26114cd565b602002602001015192505050919050565b600083610ed1868585610fed565b1495945050505050565b603881811c60ff16602883811c61ff001691909117601884811c62ff00001691909117600885811c63ff000000169190911764ff000000009186901b919091161765ff00000000009185901b919091161766ff0000000000009184901b919091161760ff60381b9290911b919091161760c01b90565b600080610f5f6004846116f1565b610f6a90604061171b565b64ffffffffff169050610fdc84821b60f881901c60e882901c61ff00161760d882901c62ff0000161760c882901c63ff000000161764ff0000000060b883901c161765ff000000000060a883901c161766ff000000000000609883901c161760ff60381b60889290921c919091161790565b6001600160401b0316949350505050565b6000835160001415801561100c57506020845161100a9190611742565b155b611029576040516313717da960e21b815260040160405180910390fd5b604080516020808201909252848152905b855181116110c05761104d600285611742565b60000361107d578151600052808601516020526020826040600060026107d05a03fa61107857600080fd5b6110a1565b8086015160005281516020526020826040600060026107d05a03fa6110a157600080fd5b6110ac60028561166b565b93506110b9602082611696565b905061103a565b5051949350505050565b60008083601f8401126110dc57600080fd5b5081356001600160401b038111156110f357600080fd5b60208301915083602082850101111561110b57600080fd5b9250929050565b6000806020838503121561112557600080fd5b82356001600160401b0381111561113b57600080fd5b611147858286016110ca565b90969095509350505050565b6000806000806060858703121561116957600080fd5b843593506020850135925060408501356001600160401b0381111561118d57600080fd5b611199878288016110ca565b95989497509550505050565b803564ffffffffff811681146111ba57600080fd5b919050565b80356001600160401b03811681146111ba57600080fd5b6000806000806000608086880312156111ee57600080fd5b853594506111fe602087016111a5565b935061120c604087016111bf565b925060608601356001600160401b0381111561122757600080fd5b611233888289016110ca565b969995985093965092949392505050565b60008060008060008060a0878903121561125d57600080fd5b863595506020870135945060408701356001600160401b0381111561128157600080fd5b61128d89828a016110ca565b90955093506112a09050606088016111a5565b95989497509295919493608090920135925050565b6000806000806000608086880312156112cd57600080fd5b853594506020860135935060408601356001600160401b038111156112f157600080fd5b6112fd888289016110ca565b909450925050606086013563ffffffff8116811461131a57600080fd5b809150509295509295909350565b600080600080600080600060a0888a03121561134357600080fd5b8735965060208801356001600160401b0381111561136057600080fd5b61136c8a828b016110ca565b909750955061137f9050604089016111bf565b935060608801356001600160401b0381111561139a57600080fd5b6113a68a828b016110ca565b90945092506113b99050608089016111bf565b905092959891949750929550565b600080600080606085870312156113dd57600080fd5b843593506113ed602086016111bf565b925060408501356001600160401b0381111561118d57600080fd5b60008060008060006080868803121561142057600080fd5b853594506020860135935060408601356001600160401b0381111561144457600080fd5b611450888289016110ca565b90945092506114639050606087016111a5565b90509295509295909350565b634e487b7160e01b600052604160045260246000fd5b6000808585111561149557600080fd5b838611156114a257600080fd5b5050820193919092039150565b8035602083101561017757600019602084900360031b1b1692915050565b634e487b7160e01b600052603260045260246000fd5b602080825260129082015271125b9d985b1a5908189b1bd8dac81c9bdbdd60721b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b818103818111156101775761017761150f565b6001815b6001841115611573578085048111156115575761155761150f565b600184161561156557908102905b60019390931c92800261153c565b935093915050565b60008261158a57506001610177565b8161159757506000610177565b81600181146115ad57600281146115b7576115d3565b6001915050610177565b60ff8411156115c8576115c861150f565b50506001821b610177565b5060208310610133831016604e8410600b84101617156115f6575081810a610177565b6116036000198484611538565b80600019048211156116175761161761150f565b029392505050565b6000610174838361157b565b634e487b7160e01b600052601260045260246000fd5b600064ffffffffff8316806116585761165861162b565b8064ffffffffff84160491505092915050565b60008261167a5761167a61162b565b500490565b80820281158282048414176101775761017761150f565b808201808211156101775761017761150f565b6000825160005b818110156116ca57602081860181015185830152016116b0565b506000920191825250919050565b6000602082840312156116ea57600080fd5b5051919050565b600064ffffffffff8316806117085761170861162b565b8064ffffffffff84160691505092915050565b64ffffffffff818116838216029081169081811461173b5761173b61150f565b5092915050565b6000826117515761175161162b565b50069056fea26469706673582212205e6c180b3544abbcda0a898d1a795e4ddbd861b7b533fbede356a76fa464c51064736f6c634300081c0033

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

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.