Contract Name:
BatchDeposit2
Contract Source Code:
<i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: GPL-3.0-or-later
// Contract: BatchDeposit2
// Repository: https://gitlab.com/Blockdaemon/open-source/eth2-batch-deposit-contract
pragma solidity 0.8.28;
import {IBatchDeposit2} from "./interfaces/IBatchDeposit2.sol";
import {IERC165} from "./interfaces/IERC165.sol";
contract BatchDeposit2 is IBatchDeposit2, IERC165 {
// 0xd0 == 0x30 + 0x20 + 0x60 + 0x20 (pubkey + credentials + signature + root)
uint256 public constant DEPOSIT_DATA_SIZE = 0xd0;
address public immutable DEPOSIT_CONTRACT;
error DeadlineExceeded();
error DepositFailed();
error ExcessiveBalance();
error FundingNotAccepted();
error InvalidLength();
error ZeroAddress();
constructor(address depositContract) {
require(depositContract != address(0), ZeroAddress());
DEPOSIT_CONTRACT = depositContract;
}
receive() external payable override {
revert FundingNotAccepted();
}
fallback() external payable override {
revert FundingNotAccepted();
}
function batchDeposit(uint256 deadline, uint256[] calldata values, bytes calldata argv) external payable override {
require(block.number <= deadline, DeadlineExceeded());
require(argv.length == values.length * DEPOSIT_DATA_SIZE, InvalidLength());
uint256 balanceBefore = address(this).balance;
address depositContract = DEPOSIT_CONTRACT;
assembly {
// copy selector
mstore(0x0080, 0x2289511800000000000000000000000000000000000000000000000000000000)
// copy pubkey offset
mstore(0x0084, 0x0000000000000000000000000000000000000000000000000000000000000080)
// copy withdrawal_credentials offset
mstore(0x00a4, 0x00000000000000000000000000000000000000000000000000000000000000e0)
// copy signature offset
mstore(0x00c4, 0x0000000000000000000000000000000000000000000000000000000000000120)
// copy pubkey length
mstore(0x0104, 0x0000000000000000000000000000000000000000000000000000000000000030)
// copy withdrawal_credentials length
mstore(0x0164, 0x0000000000000000000000000000000000000000000000000000000000000020)
// copy signature length
mstore(0x01a4, 0x0000000000000000000000000000000000000000000000000000000000000060)
let argvOffset := argv.offset
let valuesOffset := values.offset
for { let i := 0 } lt(i, values.length) { i := add(i, 1) } {
// copy pubkey
calldatacopy(0x0124, add(argvOffset, 0), 0x30)
// copy withdrawal credentials
calldatacopy(0x0184, add(argvOffset, 0x30), 0x20)
// copy signature
calldatacopy(0x01c4, add(argvOffset, 0x50), 0x60)
// copy deposit_data_root
calldatacopy(0x0e4, add(argvOffset, 0xb0), 0x20)
if iszero(call(gas(), depositContract, calldataload(valuesOffset), 0x80, 0x1a4, 0, 0)) {
// DepositFailed()
mstore(0x00, 0x79cacff100000000000000000000000000000000000000000000000000000000)
revert(0x00, 0x04)
}
// adjust offsets
argvOffset := add(argvOffset, 0xd0)
valuesOffset := add(valuesOffset, 0x20)
}
}
uint256 balanceAfter = address(this).balance;
require(balanceBefore == balanceAfter + msg.value, ExcessiveBalance());
}
function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
return interfaceId == type(IERC165).interfaceId || interfaceId == type(IBatchDeposit2).interfaceId;
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.28;
interface IBatchDeposit2 {
receive() external payable;
fallback() external payable;
function batchDeposit(uint256 deadline, uint256[] calldata values, bytes calldata args) external payable;
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.28;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}