XHashEth2Depositor

Description:

Smart contract deployed on Ethereum with Factory features.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "contracts/contracts/XHashEth2Depositor.sol": {
      "content": "// SPDX-License-Identifier: MIT\r
\r
pragma solidity ^0.8.0;\r
\r
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";\r
import "../contracts/interfaces/IDepositContract.sol";\r
\r
contract XHashEth2Depositor is ReentrancyGuard {\r
\r
    /**\r
     * @dev Eth2 Deposit Contract address.\r
     */\r
    IDepositContract public depositContract;\r
\r
    /**\r
     * @dev Minimal and maximum amount of nodes per transaction.\r
     */\r
    uint256 public constant pubkeyLength = 48;\r
    uint256 public constant credentialsLength = 32;\r
    uint256 public constant signatureLength = 96;\r
\r
    /**\r
     * @dev min value of one node.\r
     */\r
    uint256 public constant nodesMinValue = 32 ether;\r
\r
    /**\r
     * @dev Setting Eth2 Smart Contract address during construction.\r
     */\r
    constructor(bool mainnet, address depositContract_) {\r
        if (mainnet) {\r
            depositContract = IDepositContract(0x00000000219ab540356cBB839Cbe05303d7705Fa);\r
        } else {\r
            depositContract = IDepositContract(depositContract_);\r
        }\r
    }\r
\r
    /**\r
     * @dev This contract will not accept direct ETH transactions.\r
     */\r
    receive() external payable {\r
        revert("XHashEth2Depositor: do not send ETH directly here");\r
    }\r
\r
    /**\r
     * @dev Function that allows to deposit up to 50 nodes at once.\r
     *\r
     * - pubkeys                - Array of BLS12-381 public keys.\r
     * - withdrawal_credentials - Array of commitments to a public keys for withdrawals.\r
     * - signatures             - Array of BLS12-381 signatures.\r
     * - deposit_data_roots     - Array of the SHA-256 hashes of the SSZ-encoded DepositData objects.\r
     */\r
    function deposit(\r
        bytes[] calldata pubkeys,\r
        bytes[] calldata withdrawal_credentials,\r
        bytes[] calldata signatures,\r
        bytes32[] calldata deposit_data_roots,\r
        uint256[] calldata values\r
    ) external payable nonReentrant {\r
\r
        uint256 nodesAmount = pubkeys.length;\r
\r
        require(nodesAmount > 0 && nodesAmount <= 50, "XHashEth2Depositor: you can deposit only 1 to 50 nodes per transaction");\r
        require(\r
            withdrawal_credentials.length == nodesAmount &&\r
            signatures.length == nodesAmount &&\r
            deposit_data_roots.length == nodesAmount &&\r
            values.length == nodesAmount,\r
            "XHashEth2Depositor: parameter length mismatch"\r
        );\r
\r
        uint256 totalValue = 0;\r
        for (uint256 i = 0; i < nodesAmount; ++i) {\r
            require(pubkeys[i].length == pubkeyLength, "XHashEth2Depositor: wrong pubkey");\r
            require(withdrawal_credentials[i].length == credentialsLength, "XHashEth2Depositor: wrong withdrawal credentials");\r
            require(signatures[i].length == signatureLength, "XHashEth2Depositor: wrong signatures");\r
            require(values[i] >= nodesMinValue, "XHashEth2Depositor: deposit must be at least 32 ETH");\r
            \r
            totalValue += values[i];\r
        }\r
        \r
        require(msg.value == totalValue, "XHashEth2Depositor: incorrect ETH amount");\r
\r
        for (uint256 i = 0; i < nodesAmount; ++i) {\r
            depositContract.deposit{value: values[i]}(\r
                pubkeys[i],\r
                withdrawal_credentials[i],\r
                signatures[i],\r
                deposit_data_roots[i]\r
            );\r
        }\r
\r
        emit DepositEvent(msg.sender, nodesAmount, totalValue);\r
    }\r
\r
    event DepositEvent(address from, uint256 nodesAmount, uint256 totalValue);\r
}"
    },
    "contracts/contracts/interfaces/IDepositContract.sol": {
      "content": "// SPDX-License-Identifier: CC0-1.0\r
\r
pragma solidity ^0.8.0;\r
\r
// This interface is designed to be compatible with the Vyper version.\r
/// @notice This is the Ethereum 2.0 deposit contract interface.\r
/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs\r
interface IDepositContract {\r
    /// @notice A processed deposit event.\r
    event DepositEvent(\r
        bytes pubkey,\r
        bytes withdrawal_credentials,\r
        bytes amount,\r
        bytes signature,\r
        bytes index\r
    );\r
\r
    /// @notice Submit a Phase 0 DepositData object.\r
    /// @param pubkey A BLS12-381 public key.\r
    /// @param withdrawal_credentials Commitment to a public key for withdrawals.\r
    /// @param signature A BLS12-381 signature.\r
    /// @param deposit_data_root The SHA-256 hash of the SSZ-encoded DepositData object.\r
    /// Used as a protection against malformed input.\r
    function deposit(\r
        bytes calldata pubkey,\r
        bytes calldata withdrawal_credentials,\r
        bytes calldata signature,\r
        bytes32 deposit_data_root\r
    ) external payable;\r
\r
    /// @notice Query the current deposit root hash.\r
    /// @return The deposit root hash.\r
    function get_deposit_root() external view returns (bytes32);\r
\r
    /// @notice Query the current deposit count.\r
    /// @return The deposit count encoded as a little endian 64-bit number.\r
    function get_deposit_count() external view returns (bytes memory);\r
}"
    },
    "@openzeppelin/contracts/security/ReentrancyGuard.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

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

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == _ENTERED;
    }
}
"
    }
  },
  "settings": {
    "optimizer": {
      "runs": 200,
      "enabled": false
    },
    "remappings": [],
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "abi"
        ]
      }
    }
  }
}}

Tags:
Factory|addr:0xeb394552537c08002b92db5b9df0327f30c0a2a9|verified:true|block:23415757|tx:0xe9b3093572de48df8cdd99489bc241d6026fe84f12f742222ce3a99bd952de1f|first_check:1758534987

Submitted on: 2025-09-22 11:56:27

Comments

Log in to comment.

No comments yet.