ETH Price: $2,583.09 (+1.08%)

Transaction Decoder

Block:
21465300 at Dec-23-2024 12:51:23 PM +UTC
Transaction Fee:
0.001004429468494641 ETH $2.59
Gas Used:
123,599 Gas / 8.126517759 Gwei

Emitted Events:

110 DepositContract.DepositEvent( pubkey=0xAE67C498E33848A8E82FFDFC49C987CAC6A84FF7E9502B81756F695F312714E28107A6FBDEC85CDD632E25055D7E11C7, withdrawal_credentials=0x01000000000000000000000088A4DF73AAC310484C60C4C0AC4904CAB938C20B, amount=0x0040597307000000, signature=0x97BEC5160808F54B89B45D76BA82269A1434F5A48F7BC6E028E674A0933739D1B84925A34A73D627F3BED3DB77A12B310452E230436E0FF43A69E926C6F474F4302D5071DF7D29E7749C370747646438655C0A6FF1ECECD804031039134829D7, index=0x79F01B0000000000 )
111 0x808e7133c700cf3a66e6a25aadb1fbef6be468b4.0x59bed9ab5d78073465dd642a9e3e76dfdb7d53bcae9d09df7d0b8f5234d5a806( 0x59bed9ab5d78073465dd642a9e3e76dfdb7d53bcae9d09df7d0b8f5234d5a806, 000000000000000000000000538d72ded42a76a30f730292da939e0577f22f57, 000000000000000000000000a4a53558aec0c1e6006443b23e438162cd82609e, cbb831476ff7c272573fb6275cc0bc7c72d7792f5e850a08bfa03c26882e6c83, 00000000000000000000000000000000219ab540356cbb839cbe05303d7705fa, 000000000000000000000000000000000000000000000001bc16d674ec800000, 00000000000000000000000000000000000000000000000000000000000000c0, 00000000000000000000000000000000000000000000000000000000000001a4, 2289511800000000000000000000000000000000000000000000000000000000, 0000008000000000000000000000000000000000000000000000000000000000, 000000e000000000000000000000000000000000000000000000000000000000, 00000120ee4c142d20429350eee80c9122467f6bcae5ba037c0a1d484eacc0ce, 808e5dd500000000000000000000000000000000000000000000000000000000, 00000030ae67c498e33848a8e82ffdfc49c987cac6a84ff7e9502b81756f695f, 312714e28107a6fbdec85cdd632e25055d7e11c7000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000002001000000000000000000000088a4df73aac310484c60c4c0ac4904ca, b938c20b00000000000000000000000000000000000000000000000000000000, 0000006097bec5160808f54b89b45d76ba82269a1434f5a48f7bc6e028e674a0, 933739d1b84925a34a73d627f3bed3db77a12b310452e230436e0ff43a69e926, c6f474f4302d5071df7d29e7749c370747646438655c0a6ff1ececd804031039, 134829d700000000000000000000000000000000000000000000000000000000 )

Account State Difference:

  Address   Before After State Difference Code
0x00000000...03d7705Fa
(Beacon Deposit Contract)
54,933,918.337770114865867169 Eth54,933,950.337770114865867169 Eth32
(Lido: Execution Layer Rewards Vault)
2.019109960591832212 Eth2.019247835276332212 Eth0.0001378746845
0x538d72dE...577f22F57
(Bitstamp: Deployer)
53.701046106947695937 Eth
Nonce: 377796
53.700041677479201296 Eth
Nonce: 377797
0.001004429468494641
0x808e7133...F6be468b4
(Bitstamp 9)
64 Eth32 Eth32

Execution Trace

Bitstamp 9.39125215( )
  • Null: 0x000...001.cbb83147( )
  • ETH 32 DepositContract.deposit( pubkey=0xAE67C498E33848A8E82FFDFC49C987CAC6A84FF7E9502B81756F695F312714E28107A6FBDEC85CDD632E25055D7E11C7, withdrawal_credentials=0x01000000000000000000000088A4DF73AAC310484C60C4C0AC4904CAB938C20B, signature=0x97BEC5160808F54B89B45D76BA82269A1434F5A48F7BC6E028E674A0933739D1B84925A34A73D627F3BED3DB77A12B310452E230436E0FF43A69E926C6F474F4302D5071DF7D29E7749C370747646438655C0A6FF1ECECD804031039134829D7, deposit_data_root=EE4C142D20429350EEE80C9122467F6BCAE5BA037C0A1D484EACC0CE808E5DD5 )
    • Null: 0x000...002.ae67c498( )
    • Null: 0x000...002.97bec516( )
    • Null: 0x000...002.302d5071( )
    • Null: 0x000...002.8e5b5d05( )
    • Null: 0x000...002.12d4e251( )
    • Null: 0x000...002.00405973( )
    • Null: 0x000...002.cbb3ce69( )
    • Null: 0x000...002.97967ae5( )
      // ┏━━━┓━┏┓━┏┓━━┏━━━┓━━┏━━━┓━━━━┏━━━┓━━━━━━━━━━━━━━━━━━━┏┓━━━━━┏━━━┓━━━━━━━━━┏┓━━━━━━━━━━━━━━┏┓━
      // ┃┏━━┛┏┛┗┓┃┃━━┃┏━┓┃━━┃┏━┓┃━━━━┗┓┏┓┃━━━━━━━━━━━━━━━━━━┏┛┗┓━━━━┃┏━┓┃━━━━━━━━┏┛┗┓━━━━━━━━━━━━┏┛┗┓
      // ┃┗━━┓┗┓┏┛┃┗━┓┗┛┏┛┃━━┃┃━┃┃━━━━━┃┃┃┃┏━━┓┏━━┓┏━━┓┏━━┓┏┓┗┓┏┛━━━━┃┃━┗┛┏━━┓┏━┓━┗┓┏┛┏━┓┏━━┓━┏━━┓┗┓┏┛
      // ┃┏━━┛━┃┃━┃┏┓┃┏━┛┏┛━━┃┃━┃┃━━━━━┃┃┃┃┃┏┓┃┃┏┓┃┃┏┓┃┃━━┫┣┫━┃┃━━━━━┃┃━┏┓┃┏┓┃┃┏┓┓━┃┃━┃┏┛┗━┓┃━┃┏━┛━┃┃━
      // ┃┗━━┓━┃┗┓┃┃┃┃┃┃┗━┓┏┓┃┗━┛┃━━━━┏┛┗┛┃┃┃━┫┃┗┛┃┃┗┛┃┣━━┃┃┃━┃┗┓━━━━┃┗━┛┃┃┗┛┃┃┃┃┃━┃┗┓┃┃━┃┗┛┗┓┃┗━┓━┃┗┓
      // ┗━━━┛━┗━┛┗┛┗┛┗━━━┛┗┛┗━━━┛━━━━┗━━━┛┗━━┛┃┏━┛┗━━┛┗━━┛┗┛━┗━┛━━━━┗━━━┛┗━━┛┗┛┗┛━┗━┛┗┛━┗━━━┛┗━━┛━┗━┛
      // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┃┃━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
      // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┗┛━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
      
      // SPDX-License-Identifier: CC0-1.0
      
      pragma solidity 0.6.11;
      
      // This interface is designed to be compatible with the Vyper version.
      /// @notice This is the Ethereum 2.0 deposit contract interface.
      /// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs
      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);
      }
      
      // Based on official specification in https://eips.ethereum.org/EIPS/eip-165
      interface ERC165 {
          /// @notice Query if a contract implements an interface
          /// @param interfaceId The interface identifier, as specified in ERC-165
          /// @dev Interface identification is specified in ERC-165. This function
          ///  uses less than 30,000 gas.
          /// @return `true` if the contract implements `interfaceId` and
          ///  `interfaceId` is not 0xffffffff, `false` otherwise
          function supportsInterface(bytes4 interfaceId) external pure returns (bool);
      }
      
      // This is a rewrite of the Vyper Eth2.0 deposit contract in Solidity.
      // It tries to stay as close as possible to the original source code.
      /// @notice This is the Ethereum 2.0 deposit contract interface.
      /// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs
      contract DepositContract is IDepositContract, ERC165 {
          uint constant DEPOSIT_CONTRACT_TREE_DEPTH = 32;
          // NOTE: this also ensures `deposit_count` will fit into 64-bits
          uint constant MAX_DEPOSIT_COUNT = 2**DEPOSIT_CONTRACT_TREE_DEPTH - 1;
      
          bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] branch;
          uint256 deposit_count;
      
          bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] zero_hashes;
      
          constructor() public {
              // Compute hashes in empty sparse Merkle tree
              for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH - 1; height++)
                  zero_hashes[height + 1] = sha256(abi.encodePacked(zero_hashes[height], zero_hashes[height]));
          }
      
          function get_deposit_root() override external view returns (bytes32) {
              bytes32 node;
              uint size = deposit_count;
              for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {
                  if ((size & 1) == 1)
                      node = sha256(abi.encodePacked(branch[height], node));
                  else
                      node = sha256(abi.encodePacked(node, zero_hashes[height]));
                  size /= 2;
              }
              return sha256(abi.encodePacked(
                  node,
                  to_little_endian_64(uint64(deposit_count)),
                  bytes24(0)
              ));
          }
      
          function get_deposit_count() override external view returns (bytes memory) {
              return to_little_endian_64(uint64(deposit_count));
          }
      
          function deposit(
              bytes calldata pubkey,
              bytes calldata withdrawal_credentials,
              bytes calldata signature,
              bytes32 deposit_data_root
          ) override external payable {
              // Extended ABI length checks since dynamic types are used.
              require(pubkey.length == 48, "DepositContract: invalid pubkey length");
              require(withdrawal_credentials.length == 32, "DepositContract: invalid withdrawal_credentials length");
              require(signature.length == 96, "DepositContract: invalid signature length");
      
              // Check deposit amount
              require(msg.value >= 1 ether, "DepositContract: deposit value too low");
              require(msg.value % 1 gwei == 0, "DepositContract: deposit value not multiple of gwei");
              uint deposit_amount = msg.value / 1 gwei;
              require(deposit_amount <= type(uint64).max, "DepositContract: deposit value too high");
      
              // Emit `DepositEvent` log
              bytes memory amount = to_little_endian_64(uint64(deposit_amount));
              emit DepositEvent(
                  pubkey,
                  withdrawal_credentials,
                  amount,
                  signature,
                  to_little_endian_64(uint64(deposit_count))
              );
      
              // Compute deposit data root (`DepositData` hash tree root)
              bytes32 pubkey_root = sha256(abi.encodePacked(pubkey, bytes16(0)));
              bytes32 signature_root = sha256(abi.encodePacked(
                  sha256(abi.encodePacked(signature[:64])),
                  sha256(abi.encodePacked(signature[64:], bytes32(0)))
              ));
              bytes32 node = sha256(abi.encodePacked(
                  sha256(abi.encodePacked(pubkey_root, withdrawal_credentials)),
                  sha256(abi.encodePacked(amount, bytes24(0), signature_root))
              ));
      
              // Verify computed and expected deposit data roots match
              require(node == deposit_data_root, "DepositContract: reconstructed DepositData does not match supplied deposit_data_root");
      
              // Avoid overflowing the Merkle tree (and prevent edge case in computing `branch`)
              require(deposit_count < MAX_DEPOSIT_COUNT, "DepositContract: merkle tree full");
      
              // Add deposit data root to Merkle tree (update a single `branch` node)
              deposit_count += 1;
              uint size = deposit_count;
              for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {
                  if ((size & 1) == 1) {
                      branch[height] = node;
                      return;
                  }
                  node = sha256(abi.encodePacked(branch[height], node));
                  size /= 2;
              }
              // As the loop should always end prematurely with the `return` statement,
              // this code should be unreachable. We assert `false` just to be safe.
              assert(false);
          }
      
          function supportsInterface(bytes4 interfaceId) override external pure returns (bool) {
              return interfaceId == type(ERC165).interfaceId || interfaceId == type(IDepositContract).interfaceId;
          }
      
          function to_little_endian_64(uint64 value) internal pure returns (bytes memory ret) {
              ret = new bytes(8);
              bytes8 bytesValue = bytes8(value);
              // Byteswapping during copying to bytes.
              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];
          }
      }