ETH Price: $1,975.77 (+0.69%)
 

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
Batch Deposit244991742026-02-20 16:11:3539 hrs ago1771603895IN
0xcD7a6C11...D2C546756
32 ETH0.000019770.26192782
Batch Deposit244840542026-02-18 13:35:113 days ago1771421711IN
0xcD7a6C11...D2C546756
249 ETH0.000006750.08299132
Batch Deposit244840542026-02-18 13:35:113 days ago1771421711IN
0xcD7a6C11...D2C546756
913 ETH0.000006260.08299132
Batch Deposit244840542026-02-18 13:35:113 days ago1771421711IN
0xcD7a6C11...D2C546756
249 ETH0.000006510.08299132
Batch Deposit244829992026-02-18 10:03:233 days ago1771409003IN
0xcD7a6C11...D2C546756
1,500 ETH0.000002490.03305947
Batch Deposit244828952026-02-18 9:42:233 days ago1771407743IN
0xcD7a6C11...D2C546756
5 ETH0.000002940.03493213
Batch Deposit244820732026-02-18 6:57:474 days ago1771397867IN
0xcD7a6C11...D2C546756
1.3 ETH0.000161062.13456318
Batch Deposit244492352026-02-13 17:04:478 days ago1771002287IN
0xcD7a6C11...D2C546756
32 ETH0.000028340.33583633
Batch Deposit244423912026-02-12 18:09:599 days ago1770919799IN
0xcD7a6C11...D2C546756
32 ETH0.000113171.29516755
Batch Deposit244398132026-02-12 9:30:479 days ago1770888647IN
0xcD7a6C11...D2C546756
1,000 ETH0.000004120.05467994
Batch Deposit244385252026-02-12 5:11:4710 days ago1770873107IN
0xcD7a6C11...D2C546756
30 ETH0.000004050.05376589
Batch Deposit244292542026-02-10 22:08:4711 days ago1770761327IN
0xcD7a6C11...D2C546756
900 ETH0.000004610.05878825
Batch Deposit244243282026-02-10 5:36:5912 days ago1770701819IN
0xcD7a6C11...D2C546756
32 ETH0.000002480.03292318
Batch Deposit244243052026-02-10 5:32:1112 days ago1770701531IN
0xcD7a6C11...D2C546756
32 ETH0.000002830.03611958
Batch Deposit244219352026-02-09 21:36:2312 days ago1770672983IN
0xcD7a6C11...D2C546756
913 ETH0.000012920.17127101
Batch Deposit244219352026-02-09 21:36:2312 days ago1770672983IN
0xcD7a6C11...D2C546756
921 ETH0.000013430.17127101
Batch Deposit244058152026-02-07 15:23:2314 days ago1770477803IN
0xcD7a6C11...D2C546756
1.9 ETH0.000006950.09216837
Batch Deposit243996702026-02-06 18:47:4715 days ago1770403667IN
0xcD7a6C11...D2C546756
249 ETH0.000028460.33718865
Batch Deposit243996702026-02-06 18:47:4715 days ago1770403667IN
0xcD7a6C11...D2C546756
249 ETH0.000025450.33718865
Batch Deposit243987122026-02-06 15:34:5915 days ago1770392099IN
0xcD7a6C11...D2C546756
249 ETH0.000058810.77944551
Batch Deposit243987122026-02-06 15:34:5915 days ago1770392099IN
0xcD7a6C11...D2C546756
249 ETH0.000063470.77944551
Batch Deposit243987122026-02-06 15:34:5915 days ago1770392099IN
0xcD7a6C11...D2C546756
249 ETH0.000058830.77944551
Batch Deposit243889612026-02-05 6:51:4717 days ago1770274307IN
0xcD7a6C11...D2C546756
1,000 ETH0.000014450.19156496
Batch Deposit243743432026-02-03 5:48:3519 days ago1770097715IN
0xcD7a6C11...D2C546756
33 ETH0.000007230.09583456
Batch Deposit243309622026-01-28 4:30:4725 days ago1769574647IN
0xcD7a6C11...D2C546756
1 ETH0.000003190.04229209
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
Deposit244991742026-02-20 16:11:3539 hrs ago1771603895
0xcD7a6C11...D2C546756
32 ETH
Deposit244840542026-02-18 13:35:113 days ago1771421711
0xcD7a6C11...D2C546756
249 ETH
Deposit244840542026-02-18 13:35:113 days ago1771421711
0xcD7a6C11...D2C546756
913 ETH
Deposit244840542026-02-18 13:35:113 days ago1771421711
0xcD7a6C11...D2C546756
249 ETH
Deposit244829992026-02-18 10:03:233 days ago1771409003
0xcD7a6C11...D2C546756
1,500 ETH
Deposit244828952026-02-18 9:42:233 days ago1771407743
0xcD7a6C11...D2C546756
5 ETH
Deposit244820732026-02-18 6:57:474 days ago1771397867
0xcD7a6C11...D2C546756
1.3 ETH
Deposit244492352026-02-13 17:04:478 days ago1771002287
0xcD7a6C11...D2C546756
32 ETH
Deposit244423912026-02-12 18:09:599 days ago1770919799
0xcD7a6C11...D2C546756
32 ETH
Deposit244398132026-02-12 9:30:479 days ago1770888647
0xcD7a6C11...D2C546756
1,000 ETH
Deposit244385252026-02-12 5:11:4710 days ago1770873107
0xcD7a6C11...D2C546756
30 ETH
Deposit244292542026-02-10 22:08:4711 days ago1770761327
0xcD7a6C11...D2C546756
900 ETH
Deposit244243282026-02-10 5:36:5912 days ago1770701819
0xcD7a6C11...D2C546756
32 ETH
Deposit244243052026-02-10 5:32:1112 days ago1770701531
0xcD7a6C11...D2C546756
32 ETH
Deposit244219352026-02-09 21:36:2312 days ago1770672983
0xcD7a6C11...D2C546756
913 ETH
Deposit244219352026-02-09 21:36:2312 days ago1770672983
0xcD7a6C11...D2C546756
921 ETH
Deposit244207832026-02-09 17:44:3512 days ago1770659075
0xcD7a6C11...D2C546756
5.05 ETH
Batch Deposit244207832026-02-09 17:44:3512 days ago1770659075
0xcD7a6C11...D2C546756
5.05 ETH
Deposit244058152026-02-07 15:23:2314 days ago1770477803
0xcD7a6C11...D2C546756
1.9 ETH
Deposit243996702026-02-06 18:47:4715 days ago1770403667
0xcD7a6C11...D2C546756
249 ETH
Deposit243996702026-02-06 18:47:4715 days ago1770403667
0xcD7a6C11...D2C546756
249 ETH
Deposit243987122026-02-06 15:34:5915 days ago1770392099
0xcD7a6C11...D2C546756
249 ETH
Deposit243987122026-02-06 15:34:5915 days ago1770392099
0xcD7a6C11...D2C546756
249 ETH
Deposit243987122026-02-06 15:34:5915 days ago1770392099
0xcD7a6C11...D2C546756
249 ETH
Deposit243889612026-02-05 6:51:4717 days ago1770274307
0xcD7a6C11...D2C546756
1,000 ETH
View All Internal Transactions
Loading...
Loading
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:
BatchDeposit

Compiler Version
v0.8.28+commit.7893614a

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.28;

import {IBatchDeposit} from "../interfaces/IBatchDeposit.sol";
import {IDepositContract} from "../vendors/IDepositContract.sol";
import {DepositDataRoot} from "../libs/DepositDataRoot.sol";

contract BatchDeposit is IBatchDeposit {
    using DepositDataRoot for Deposit;

    IDepositContract public constant depositContract =
        IDepositContract(0x00000000219ab540356cBB839Cbe05303d7705Fa);

    receive() external payable {
        revert ETHNotAccepted();
    }

    fallback() external payable {
        revert FallbackMethodNotAccepted();
    }

    function batchDeposit(
        Deposit[] calldata _deposits
    ) external payable override {
        if (_deposits.length == 0) {
            revert NoDepositsProvided();
        }

        // Gas optimization: accumulate total required ETH for all deposits.
        uint256 totalAmount = 0;
        for (uint256 i = 0; i < _deposits.length; ++i) {
            if (_deposits[i].pubKey.length != 48) {
                revert InvalidPubKeyLength();
            }
            if (_deposits[i].withdrawalCredentials.length != 32) {
                revert InvalidWithdrawalCredLength();
            }
            if (_deposits[i].signature.length != 96) {
                revert InvalidSignatureLength();
            }
            if (_deposits[i].amount < 1 ether) {
                revert DepositValueLessThan1ETH();
            }
            if (_deposits[i].amount > 2048 ether) {
                revert DepositValueGreaterThan2048ETH();
            }

            if (_deposits[i].amount % 1 gwei != 0) {
                revert DepositValueMustBeMultipleOfGwei();
            }

            totalAmount += _deposits[i].amount;
        }
        if (totalAmount != msg.value) {
            revert MsgValueNotEqualToTotalDepositAmount();
        }

        // Process each deposit
        for (uint256 i = 0; i < _deposits.length; ++i) {
            bytes32 depositDataRoot = _deposits[i].formatDepositDataRoot();

            // Call the Ethereum deposit contract for this entry.
            depositContract.deposit{value: _deposits[i].amount}(
                _deposits[i].pubKey,
                _deposits[i].withdrawalCredentials,
                _deposits[i].signature,
                depositDataRoot
            );

            emit ValidatorDeposit(
                _deposits[i].pubKey,
                _deposits[i].withdrawalCredentials,
                _deposits[i].amount
            );
        }
    }
}

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.28;

/// @title IBatchDeposit - Interface for batching deposits to the Ethereum deposit contract
/// @notice Facilitates multiple validator deposits to Ethereum's deposit contract in a single transaction
interface IBatchDeposit {
    /// @notice Struct representing a single validator deposit
    /// @param pubKey Validator public key (48 bytes)
    /// @param withdrawalCredentials Withdrawal credentials (32 bytes)
    /// @param signature Validator signature (96 bytes)
    /// @param amount Amount to deposit for the validator (in wei)
    struct Deposit {
        bytes pubKey;
        bytes withdrawalCredentials;
        bytes signature;
        uint256 amount;
    }

    /// @notice Emitted when a validator deposit is made
    /// @param pubKey The public key of the deposited validator
    /// @param withdrawalCredentials The withdrawal credentials associated with the validator
    /// @param amount The amount deposited for the validator
    event ValidatorDeposit(
        bytes indexed pubKey,
        bytes indexed withdrawalCredentials,
        uint256 amount
    );

    /// @notice Thrown when the deposits array is empty
    error NoDepositsProvided();

    /// @notice Thrown when the provided pubKey is not exactly 48 bytes
    error InvalidPubKeyLength();

    /// @notice Thrown when the withdrawal credentials are not exactly 32 bytes
    error InvalidWithdrawalCredLength();

    /// @notice Thrown when the signature is not exactly 96 bytes
    error InvalidSignatureLength();

    /// @notice Thrown when a deposit amount is less than 1 ether (required minimum for Ethereum validators)
    error DepositValueLessThan1ETH();

    /// @notice Thrown when a single deposit amount exceeds 2048 ether (maximum allowed for Ethereum validators)
    /// @notice Note that if the validator already has a balance, this check doesn't take that into account
    error DepositValueGreaterThan2048ETH();

    /// @notice Thrown when the deposit amount is not a multiple of Gwei (1e9 wei)
    error DepositValueMustBeMultipleOfGwei();

    /// @notice Thrown when msg.value does not equal the total of all deposit amounts
    error MsgValueNotEqualToTotalDepositAmount();

    /// @notice Thrown when ETH is sent to the contract directly
    error ETHNotAccepted();

    /// @notice Thrown when a fallback method is called
    error FallbackMethodNotAccepted();

    /// @notice Executes a batch deposit to Ethereum's deposit contract
    /// @dev Validates input data lengths and ensures deposit values comply with Ethereum's validator requirements
    /// @param _deposits An array of Deposit structs representing each validator's deposit data
    function batchDeposit(Deposit[] calldata _deposits) external payable;
}

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.28;

import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol";
import {IBatchDeposit} from "../interfaces/IBatchDeposit.sol";

/**
 * @title DepositDataRoot
 * @author https://github.com/max-taylor
 * @notice This library helps to format the deposit data root for new validator setup
 */
library DepositDataRoot {
    using BytesLib for bytes;

    /**
     * @dev This method converts a uint64 value into a LE bytes array, this is required for compatibility with the beacon deposit contract
     * @dev Code was taken from: https://github.com/ethereum/consensus-specs/blob/dev/solidity_deposit_contract/deposit_contract.sol#L165
     * @param value The value to convert to the LE bytes array
     */
    function _toLittleEndian64(
        uint64 value
    ) internal pure returns (bytes memory ret) {
        ret = new bytes(8);
        bytes8 bytesValue = bytes8(value);

        // Byte swap each item so it's LE not BE
        ret[0] = bytesValue[7];
        ret[1] = bytesValue[6];
        ret[2] = bytesValue[5];
        ret[3] = bytesValue[4];
        ret[4] = bytesValue[3];
        ret[5] = bytesValue[2];
        ret[6] = bytesValue[1];
        ret[7] = bytesValue[0];
    }

    /**
     * @dev This method formats the deposit data root for setting up a new validator in the deposit contract. Logic was token from the deposit contract: https://github.com/ethereum/consensus-specs/blob/dev/solidity_deposit_contract/deposit_contract.sol#L128
     * @param _deposit The deposit data to format
     */
    function formatDepositDataRoot(
        IBatchDeposit.Deposit memory _deposit
    ) internal pure returns (bytes32 node) {
        uint256 deposit_amount = _deposit.amount / 1 gwei;

        bytes memory amount = _toLittleEndian64(uint64(deposit_amount));

        bytes32 pubKeyRoot = sha256(
            abi.encodePacked(_deposit.pubKey, bytes16(0))
        );

        bytes32 signature_root = sha256(
            abi.encodePacked(
                sha256(abi.encodePacked(_deposit.signature.slice(0, 64))),
                sha256(
                    abi.encodePacked(
                        _deposit.signature.slice(64, 32),
                        bytes32(0)
                    )
                )
            )
        );

        node = sha256(
            abi.encodePacked(
                sha256(
                    abi.encodePacked(pubKeyRoot, _deposit.withdrawalCredentials)
                ),
                sha256(abi.encodePacked(amount, bytes24(0), signature_root))
            )
        );
    }
}

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.28;

/**
 * @title IDepositcontract
 * @notice This is the Ethereum 2.0 deposit contract interface.
 * @dev Implementation can be found here: https://github.com/ethereum/consensus-specs/blob/dev/solidity_deposit_contract/deposit_contract.sol
 */
interface IDepositContract {
    /**
     * @notice A processed deposit event.
     */
    event DepositEvent(
        bytes pubkey,
        bytes withdrawal_credentials,
        bytes amount,
        bytes signature,
        bytes index
    );

    /**
     * @notice Submit a Phase 0 DepositData object.
     * @param pubkey A BLS12-381 public key.
     * @param withdrawal_credentials Commitment to a public key for withdrawals.
     * @param signature A BLS12-381 signature.
     * @param deposit_data_root The SHA-256 hash of the SSZ-encoded DepositData object, used as a protection against malformed input.
     */
    function deposit(
        bytes calldata pubkey,
        bytes calldata withdrawal_credentials,
        bytes calldata signature,
        bytes32 deposit_data_root
    ) external payable;

    /**
     * @notice Query the current deposit root hash.
     * @return The deposit root hash.
     */
    function get_deposit_root() external view returns (bytes32);

    /**
     * @notice Query the current deposit count.
     * @return The deposit count encoded as a little endian 64-bit number.
     */
    function get_deposit_count() external view returns (bytes memory);
}

// SPDX-License-Identifier: Unlicense
/*
 * @title Solidity Bytes Arrays Utils
 * @author Gonçalo Sá <goncalo.sa@consensys.net>
 *
 * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.
 *      The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.
 */
pragma solidity >=0.8.0 <0.9.0;


library BytesLib {
    function concat(
        bytes memory _preBytes,
        bytes memory _postBytes
    )
        internal
        pure
        returns (bytes memory)
    {
        bytes memory tempBytes;

        assembly {
            // Get a location of some free memory and store it in tempBytes as
            // Solidity does for memory variables.
            tempBytes := mload(0x40)

            // Store the length of the first bytes array at the beginning of
            // the memory for tempBytes.
            let length := mload(_preBytes)
            mstore(tempBytes, length)

            // Maintain a memory counter for the current write location in the
            // temp bytes array by adding the 32 bytes for the array length to
            // the starting location.
            let mc := add(tempBytes, 0x20)
            // Stop copying when the memory counter reaches the length of the
            // first bytes array.
            let end := add(mc, length)

            for {
                // Initialize a copy counter to the start of the _preBytes data,
                // 32 bytes into its memory.
                let cc := add(_preBytes, 0x20)
            } lt(mc, end) {
                // Increase both counters by 32 bytes each iteration.
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                // Write the _preBytes data into the tempBytes memory 32 bytes
                // at a time.
                mstore(mc, mload(cc))
            }

            // Add the length of _postBytes to the current length of tempBytes
            // and store it as the new length in the first 32 bytes of the
            // tempBytes memory.
            length := mload(_postBytes)
            mstore(tempBytes, add(length, mload(tempBytes)))

            // Move the memory counter back from a multiple of 0x20 to the
            // actual end of the _preBytes data.
            mc := end
            // Stop copying when the memory counter reaches the new combined
            // length of the arrays.
            end := add(mc, length)

            for {
                let cc := add(_postBytes, 0x20)
            } lt(mc, end) {
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                mstore(mc, mload(cc))
            }

            // Update the free-memory pointer by padding our last write location
            // to 32 bytes: add 31 bytes to the end of tempBytes to move to the
            // next 32 byte block, then round down to the nearest multiple of
            // 32. If the sum of the length of the two arrays is zero then add
            // one before rounding down to leave a blank 32 bytes (the length block with 0).
            mstore(0x40, and(
              add(add(end, iszero(add(length, mload(_preBytes)))), 31),
              not(31) // Round down to the nearest 32 bytes.
            ))
        }

        return tempBytes;
    }

    function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {
        assembly {
            // Read the first 32 bytes of _preBytes storage, which is the length
            // of the array. (We don't need to use the offset into the slot
            // because arrays use the entire slot.)
            let fslot := sload(_preBytes.slot)
            // Arrays of 31 bytes or less have an even value in their slot,
            // while longer arrays have an odd value. The actual length is
            // the slot divided by two for odd values, and the lowest order
            // byte divided by two for even values.
            // If the slot is even, bitwise and the slot with 255 and divide by
            // two to get the length. If the slot is odd, bitwise and the slot
            // with -1 and divide by two.
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)
            let newlength := add(slength, mlength)
            // slength can contain both the length and contents of the array
            // if length < 32 bytes so let's prepare for that
            // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
            switch add(lt(slength, 32), lt(newlength, 32))
            case 2 {
                // Since the new array still fits in the slot, we just need to
                // update the contents of the slot.
                // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length
                sstore(
                    _preBytes.slot,
                    // all the modifications to the slot are inside this
                    // next block
                    add(
                        // we can just add to the slot contents because the
                        // bytes we want to change are the LSBs
                        fslot,
                        add(
                            mul(
                                div(
                                    // load the bytes from memory
                                    mload(add(_postBytes, 0x20)),
                                    // zero all bytes to the right
                                    exp(0x100, sub(32, mlength))
                                ),
                                // and now shift left the number of bytes to
                                // leave space for the length in the slot
                                exp(0x100, sub(32, newlength))
                            ),
                            // increase length by the double of the memory
                            // bytes length
                            mul(mlength, 2)
                        )
                    )
                )
            }
            case 1 {
                // The stored value fits in the slot, but the combined value
                // will exceed it.
                // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes.slot)
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

                // save new length
                sstore(_preBytes.slot, add(mul(newlength, 2), 1))

                // The contents of the _postBytes array start 32 bytes into
                // the structure. Our first read should obtain the `submod`
                // bytes that can fit into the unused space in the last word
                // of the stored array. To get this, we read 32 bytes starting
                // from `submod`, so the data we read overlaps with the array
                // contents by `submod` bytes. Masking the lowest-order
                // `submod` bytes allows us to add that value directly to the
                // stored value.

                let submod := sub(32, slength)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(
                    sc,
                    add(
                        and(
                            fslot,
                            0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
                        ),
                        and(mload(mc), mask)
                    )
                )

                for {
                    mc := add(mc, 0x20)
                    sc := add(sc, 1)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } {
                    sstore(sc, mload(mc))
                }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
            default {
                // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes.slot)
                // Start copying to the last used word of the stored array.
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

                // save new length
                sstore(_preBytes.slot, add(mul(newlength, 2), 1))

                // Copy over the first `submod` bytes of the new data as in
                // case 1 above.
                let slengthmod := mod(slength, 32)
                let mlengthmod := mod(mlength, 32)
                let submod := sub(32, slengthmod)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(sc, add(sload(sc), and(mload(mc), mask)))

                for {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } {
                    sstore(sc, mload(mc))
                }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
        }
    }

    function slice(
        bytes memory _bytes,
        uint256 _start,
        uint256 _length
    )
        internal
        pure
        returns (bytes memory)
    {
        require(_length + 31 >= _length, "slice_overflow");
        require(_bytes.length >= _start + _length, "slice_outOfBounds");

        bytes memory tempBytes;

        assembly {
            switch iszero(_length)
            case 0 {
                // Get a location of some free memory and store it in tempBytes as
                // Solidity does for memory variables.
                tempBytes := mload(0x40)

                // The first word of the slice result is potentially a partial
                // word read from the original array. To read it, we calculate
                // the length of that partial word and start copying that many
                // bytes into the array. The first word we copy will start with
                // data we don't care about, but the last `lengthmod` bytes will
                // land at the beginning of the contents of the new array. When
                // we're done copying, we overwrite the full first word with
                // the actual length of the slice.
                let lengthmod := and(_length, 31)

                // The multiplication in the next line is necessary
                // because when slicing multiples of 32 bytes (lengthmod == 0)
                // the following copy loop was copying the origin's length
                // and then ending prematurely not copying everything it should.
                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
                let end := add(mc, _length)

                for {
                    // The multiplication in the next line has the same exact purpose
                    // as the one above.
                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
                } lt(mc, end) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    mstore(mc, mload(cc))
                }

                mstore(tempBytes, _length)

                //update free-memory pointer
                //allocating the array padded to 32 bytes like the compiler does now
                mstore(0x40, and(add(mc, 31), not(31)))
            }
            //if we want a zero-length slice let's just return a zero-length array
            default {
                tempBytes := mload(0x40)
                //zero out the 32 bytes slice we are about to return
                //we need to do it because Solidity does not garbage collect
                mstore(tempBytes, 0)

                mstore(0x40, add(tempBytes, 0x20))
            }
        }

        return tempBytes;
    }

    function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
        require(_bytes.length >= _start + 20, "toAddress_outOfBounds");
        address tempAddress;

        assembly {
            tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
        }

        return tempAddress;
    }

    function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {
        require(_bytes.length >= _start + 1 , "toUint8_outOfBounds");
        uint8 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x1), _start))
        }

        return tempUint;
    }

    function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {
        require(_bytes.length >= _start + 2, "toUint16_outOfBounds");
        uint16 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x2), _start))
        }

        return tempUint;
    }

    function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {
        require(_bytes.length >= _start + 4, "toUint32_outOfBounds");
        uint32 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x4), _start))
        }

        return tempUint;
    }

    function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {
        require(_bytes.length >= _start + 8, "toUint64_outOfBounds");
        uint64 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x8), _start))
        }

        return tempUint;
    }

    function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {
        require(_bytes.length >= _start + 12, "toUint96_outOfBounds");
        uint96 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0xc), _start))
        }

        return tempUint;
    }

    function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {
        require(_bytes.length >= _start + 16, "toUint128_outOfBounds");
        uint128 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x10), _start))
        }

        return tempUint;
    }

    function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {
        require(_bytes.length >= _start + 32, "toUint256_outOfBounds");
        uint256 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x20), _start))
        }

        return tempUint;
    }

    function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {
        require(_bytes.length >= _start + 32, "toBytes32_outOfBounds");
        bytes32 tempBytes32;

        assembly {
            tempBytes32 := mload(add(add(_bytes, 0x20), _start))
        }

        return tempBytes32;
    }

    function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {
        bool success = true;

        assembly {
            let length := mload(_preBytes)

            // if lengths don't match the arrays are not equal
            switch eq(length, mload(_postBytes))
            case 1 {
                // cb is a circuit breaker in the for loop since there's
                //  no said feature for inline assembly loops
                // cb = 1 - don't breaker
                // cb = 0 - break
                let cb := 1

                let mc := add(_preBytes, 0x20)
                let end := add(mc, length)

                for {
                    let cc := add(_postBytes, 0x20)
                // the next line is the loop condition:
                // while(uint256(mc < end) + cb == 2)
                } eq(add(lt(mc, end), cb), 2) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    // if any of these checks fails then arrays are not equal
                    if iszero(eq(mload(mc), mload(cc))) {
                        // unsuccess:
                        success := 0
                        cb := 0
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }

    function equalStorage(
        bytes storage _preBytes,
        bytes memory _postBytes
    )
        internal
        view
        returns (bool)
    {
        bool success = true;

        assembly {
            // we know _preBytes_offset is 0
            let fslot := sload(_preBytes.slot)
            // Decode the length of the stored array like in concatStorage().
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)

            // if lengths don't match the arrays are not equal
            switch eq(slength, mlength)
            case 1 {
                // slength can contain both the length and contents of the array
                // if length < 32 bytes so let's prepare for that
                // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
                if iszero(iszero(slength)) {
                    switch lt(slength, 32)
                    case 1 {
                        // blank the last byte which is the length
                        fslot := mul(div(fslot, 0x100), 0x100)

                        if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {
                            // unsuccess:
                            success := 0
                        }
                    }
                    default {
                        // cb is a circuit breaker in the for loop since there's
                        //  no said feature for inline assembly loops
                        // cb = 1 - don't breaker
                        // cb = 0 - break
                        let cb := 1

                        // get the keccak hash to get the contents of the array
                        mstore(0x0, _preBytes.slot)
                        let sc := keccak256(0x0, 0x20)

                        let mc := add(_postBytes, 0x20)
                        let end := add(mc, mlength)

                        // the next line is the loop condition:
                        // while(uint256(mc < end) + cb == 2)
                        for {} eq(add(lt(mc, end), cb), 2) {
                            sc := add(sc, 1)
                            mc := add(mc, 0x20)
                        } {
                            if iszero(eq(sload(sc), mload(mc))) {
                                // unsuccess:
                                success := 0
                                cb := 0
                            }
                        }
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[],"name":"DepositValueGreaterThan2048ETH","type":"error"},{"inputs":[],"name":"DepositValueLessThan1ETH","type":"error"},{"inputs":[],"name":"DepositValueMustBeMultipleOfGwei","type":"error"},{"inputs":[],"name":"ETHNotAccepted","type":"error"},{"inputs":[],"name":"FallbackMethodNotAccepted","type":"error"},{"inputs":[],"name":"InvalidPubKeyLength","type":"error"},{"inputs":[],"name":"InvalidSignatureLength","type":"error"},{"inputs":[],"name":"InvalidWithdrawalCredLength","type":"error"},{"inputs":[],"name":"MsgValueNotEqualToTotalDepositAmount","type":"error"},{"inputs":[],"name":"NoDepositsProvided","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes","name":"pubKey","type":"bytes"},{"indexed":true,"internalType":"bytes","name":"withdrawalCredentials","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ValidatorDeposit","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"components":[{"internalType":"bytes","name":"pubKey","type":"bytes"},{"internalType":"bytes","name":"withdrawalCredentials","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IBatchDeposit.Deposit[]","name":"_deposits","type":"tuple[]"}],"name":"batchDeposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"depositContract","outputs":[{"internalType":"contract IDepositContract","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60808060405234601557610b0f908161001b8239f35b600080fdfe60806040526004361015610018575b3661063357610623565b60003560e01c8063e2ee27bf146100385763e94ad65b0361000e57610386565b60203660031901126102235760043567ffffffffffffffff8111610223573660238201121561022357806004013567ffffffffffffffff8111610223576024820191602436918360051b01011161022357801561036a576000805b828110610239575034036102285760005b8181106100ad57005b6100c86100c36100be8385876103c7565b61050e565b6106be565b9060606100d68285876103c7565b0135916100ed6100e78386886103c7565b806103ee565b936101066100fc85888a6103c7565b60208101906103ee565b959092610121610117878a8c6103c7565b60408101906103ee565b956f219ab540356cbb839cbe05303d7705fa3b156102235760009661015d926040519a8b98899788976304512a2360e31b8952600489016105bf565b03916f219ab540356cbb839cbe05303d7705fa5af191821561021e57600192610203575b506101e3847f07468d6bd11350def18feb2ba4201196d670bdf016f5e33b4cbf4c202b41fbbd6101fa6101e9876101bc6100e78883886103c7565b60606101db8a6101d36100fc82888d9e989e6103c7565b96909a6103c7565b01359761060e565b9461060e565b604051948552939081906020820190565b0390a3016100a4565b80610212600061021893610489565b8061037b565b84610181565b610602565b600080fd5b6306b2ca4160e51b60005260046000fd5b90603061024a6100e78486886103c7565b90500361035957602061026a6102618486886103c7565b828101906103ee565b9050036103485760606102816101178486886103c7565b90500361033757670de0b6b3a7640000606061029e8486886103c7565b01351061032757686f05b59d3b2000000060606102bc8486886103c7565b013511610316576102df60606102d38486886103c7565b0135633b9aca00900690565b610305576102fe60019160606102f68587896103c7565b013590610445565b9101610093565b6333670f3d60e21b60005260046000fd5b63546027bb60e01b60005260046000fd5b6271ed1d60e31b60005260046000fd5b634be6321b60e01b60005260046000fd5b63233fb10560e21b60005260046000fd5b634f88323960e11b60005260046000fd5b63db9d78e360e01b60005260046000fd5b600091031261022357565b346102235760003660031901126102235760206040516f219ab540356cbb839cbe05303d7705fa8152f35b634e487b7160e01b600052603260045260246000fd5b91908110156103e95760051b81013590607e1981360301821215610223570190565b6103b1565b903590601e1981360301821215610223570180359067ffffffffffffffff82116102235760200191813603831361022357565b90601f820180921161042f57565b634e487b7160e01b600052601160045260246000fd5b9190820180921161042f57565b634e487b7160e01b600052604160045260246000fd5b6080810190811067ffffffffffffffff82111761048457604052565b610452565b90601f8019910116810190811067ffffffffffffffff82111761048457604052565b67ffffffffffffffff811161048457601f01601f191660200190565b81601f82011215610223578035906104de826104ab565b926104ec6040519485610489565b8284526020838301011161022357816000926020809301838601378301015290565b608081360312610223576040519061052582610468565b803567ffffffffffffffff81116102235761054390369083016104c7565b8252602081013567ffffffffffffffff81116102235761056690369083016104c7565b602083015260408101359067ffffffffffffffff82116102235761058f606092369083016104c7565b60408401520135606082015290565b908060209392818452848401376000828201840152601f01601f1916010190565b97969591926105fd946105e16105ef936060989660808d5260808d019161059e565b918a830360208c015261059e565b91878303604089015261059e565b930152565b6040513d6000823e3d90fd5b81604051928392833781016000815203902090565b6248c6b960e61b60005260046000fd5b63686c63cf60e11b60005260046000fd5b9081519160005b83811061065c575050016000815290565b806020809284010151818501520161064b565b61067b90601092610644565b600081520190565b61067b90602092610644565b6020906106a0939281520190610644565b90565b6106b09060389392610644565b906000825260188201520190565b6106e86106e36106d66060840151633b9aca00900490565b67ffffffffffffffff1690565b6108da565b9060206000610720610706610714855160405192839187830161066f565b03601f198101835282610489565b60405191828092610644565b039060025afa1561021e57600051604082016020600061075861070661071461074986516109f9565b60405192839187830190610644565b039060025afa1561021e576020600061078a61070661071461077c84519651610a7c565b604051928391878301610683565b039060025afa1561021e5760006107bf6020926107148351916107066040519384928884019091604092825260208201520190565b039060025afa1561021e5760006107ed6020926107148484519601519161070660405193849288840161068f565b039060025afa1561021e5760006108176020926107148351956107066040519384928884016106a3565b039060025afa1561021e57600061084c6020926107148351916107066040519384928884019091604092825260208201520190565b039060025afa1561021e5760005190565b8051156103e95760200190565b8051600110156103e95760210190565b8051600210156103e95760220190565b8051600310156103e95760230190565b8051600410156103e95760240190565b8051600510156103e95760250190565b8051600610156103e95760260190565b8051600710156103e95760270190565b9060408051906108ea8183610489565b60088252601f1901366020830137610979819367ffffffffffffffff60c01b9060c01b168060071a61091b8461085d565b538060061a6109298461086a565b538060051a6109378461087a565b538060041a6109458461088a565b538060031a6109538461089a565b538060021a610961846108aa565b538060011a61096f846108ba565b5360001a916108ca565b53565b1561098357565b60405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606490fd5b156109c057565b60405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606490fd5b6000610a106040610a0981610421565b101561097c565b81516040820190818311610a685790610a2a9110156109b9565b506040519060208083019101606083015b808310610a5557505060408252601f801991011660405290565b9091602080918451815201920190610a3b565b634e487b7160e01b83526011600452602483fd5b610a8a6020610a0981610421565b80516060610a999110156109b9565b6040519060208201906060604084019101905b808310610ac657505060208252601f01601f191660405290565b9091602080918451815201920190610aac56fea2646970667358221220f6caaf066130938823cb0c0e45a155e30dfff78e69566ba611f2be286414992664736f6c634300081c0033

Deployed Bytecode

0x60806040526004361015610018575b3661063357610623565b60003560e01c8063e2ee27bf146100385763e94ad65b0361000e57610386565b60203660031901126102235760043567ffffffffffffffff8111610223573660238201121561022357806004013567ffffffffffffffff8111610223576024820191602436918360051b01011161022357801561036a576000805b828110610239575034036102285760005b8181106100ad57005b6100c86100c36100be8385876103c7565b61050e565b6106be565b9060606100d68285876103c7565b0135916100ed6100e78386886103c7565b806103ee565b936101066100fc85888a6103c7565b60208101906103ee565b959092610121610117878a8c6103c7565b60408101906103ee565b956f219ab540356cbb839cbe05303d7705fa3b156102235760009661015d926040519a8b98899788976304512a2360e31b8952600489016105bf565b03916f219ab540356cbb839cbe05303d7705fa5af191821561021e57600192610203575b506101e3847f07468d6bd11350def18feb2ba4201196d670bdf016f5e33b4cbf4c202b41fbbd6101fa6101e9876101bc6100e78883886103c7565b60606101db8a6101d36100fc82888d9e989e6103c7565b96909a6103c7565b01359761060e565b9461060e565b604051948552939081906020820190565b0390a3016100a4565b80610212600061021893610489565b8061037b565b84610181565b610602565b600080fd5b6306b2ca4160e51b60005260046000fd5b90603061024a6100e78486886103c7565b90500361035957602061026a6102618486886103c7565b828101906103ee565b9050036103485760606102816101178486886103c7565b90500361033757670de0b6b3a7640000606061029e8486886103c7565b01351061032757686f05b59d3b2000000060606102bc8486886103c7565b013511610316576102df60606102d38486886103c7565b0135633b9aca00900690565b610305576102fe60019160606102f68587896103c7565b013590610445565b9101610093565b6333670f3d60e21b60005260046000fd5b63546027bb60e01b60005260046000fd5b6271ed1d60e31b60005260046000fd5b634be6321b60e01b60005260046000fd5b63233fb10560e21b60005260046000fd5b634f88323960e11b60005260046000fd5b63db9d78e360e01b60005260046000fd5b600091031261022357565b346102235760003660031901126102235760206040516f219ab540356cbb839cbe05303d7705fa8152f35b634e487b7160e01b600052603260045260246000fd5b91908110156103e95760051b81013590607e1981360301821215610223570190565b6103b1565b903590601e1981360301821215610223570180359067ffffffffffffffff82116102235760200191813603831361022357565b90601f820180921161042f57565b634e487b7160e01b600052601160045260246000fd5b9190820180921161042f57565b634e487b7160e01b600052604160045260246000fd5b6080810190811067ffffffffffffffff82111761048457604052565b610452565b90601f8019910116810190811067ffffffffffffffff82111761048457604052565b67ffffffffffffffff811161048457601f01601f191660200190565b81601f82011215610223578035906104de826104ab565b926104ec6040519485610489565b8284526020838301011161022357816000926020809301838601378301015290565b608081360312610223576040519061052582610468565b803567ffffffffffffffff81116102235761054390369083016104c7565b8252602081013567ffffffffffffffff81116102235761056690369083016104c7565b602083015260408101359067ffffffffffffffff82116102235761058f606092369083016104c7565b60408401520135606082015290565b908060209392818452848401376000828201840152601f01601f1916010190565b97969591926105fd946105e16105ef936060989660808d5260808d019161059e565b918a830360208c015261059e565b91878303604089015261059e565b930152565b6040513d6000823e3d90fd5b81604051928392833781016000815203902090565b6248c6b960e61b60005260046000fd5b63686c63cf60e11b60005260046000fd5b9081519160005b83811061065c575050016000815290565b806020809284010151818501520161064b565b61067b90601092610644565b600081520190565b61067b90602092610644565b6020906106a0939281520190610644565b90565b6106b09060389392610644565b906000825260188201520190565b6106e86106e36106d66060840151633b9aca00900490565b67ffffffffffffffff1690565b6108da565b9060206000610720610706610714855160405192839187830161066f565b03601f198101835282610489565b60405191828092610644565b039060025afa1561021e57600051604082016020600061075861070661071461074986516109f9565b60405192839187830190610644565b039060025afa1561021e576020600061078a61070661071461077c84519651610a7c565b604051928391878301610683565b039060025afa1561021e5760006107bf6020926107148351916107066040519384928884019091604092825260208201520190565b039060025afa1561021e5760006107ed6020926107148484519601519161070660405193849288840161068f565b039060025afa1561021e5760006108176020926107148351956107066040519384928884016106a3565b039060025afa1561021e57600061084c6020926107148351916107066040519384928884019091604092825260208201520190565b039060025afa1561021e5760005190565b8051156103e95760200190565b8051600110156103e95760210190565b8051600210156103e95760220190565b8051600310156103e95760230190565b8051600410156103e95760240190565b8051600510156103e95760250190565b8051600610156103e95760260190565b8051600710156103e95760270190565b9060408051906108ea8183610489565b60088252601f1901366020830137610979819367ffffffffffffffff60c01b9060c01b168060071a61091b8461085d565b538060061a6109298461086a565b538060051a6109378461087a565b538060041a6109458461088a565b538060031a6109538461089a565b538060021a610961846108aa565b538060011a61096f846108ba565b5360001a916108ca565b53565b1561098357565b60405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606490fd5b156109c057565b60405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606490fd5b6000610a106040610a0981610421565b101561097c565b81516040820190818311610a685790610a2a9110156109b9565b506040519060208083019101606083015b808310610a5557505060408252601f801991011660405290565b9091602080918451815201920190610a3b565b634e487b7160e01b83526011600452602483fd5b610a8a6020610a0981610421565b80516060610a999110156109b9565b6040519060208201906060604084019101905b808310610ac657505060208252601f01601f191660405290565b9091602080918451815201920190610aac56fea2646970667358221220f6caaf066130938823cb0c0e45a155e30dfff78e69566ba611f2be286414992664736f6c634300081c0033

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.