Address Contract Verified
Address
0x4CA21E4D3A86e7399698F88686f5596dBe74ADEb
Balance
0 ETH
Nonce
1
Code Size
3480 bytes
Creator
0x588ede44...033a at tx 0x1e6cc846...5678f3
Indexed Transactions
0
Contract Bytecode
3480 bytes
0x6080604052600436106100e15760003560e01c80638456cb591161007f578063d8dfeb4511610059578063d8dfeb4514610265578063e94ad65b14610282578063f2fde38b146102b6578063f4fbdfac146102d657600080fd5b80638456cb59146102045780638da5cb5b14610219578063a5ab1d311461025057600080fd5b80634903e8be116100bb5780634903e8be146101a45780634f498c73146101b95780635c975abb146101cc578063715018a6146101ef57600080fd5b80631b9a9323146101505780633f4ba83a1461017857806343ba591d1461018f57600080fd5b3661014b5760405162461bcd60e51b815260206004820152602f60248201527f503270457468324465706f7369746f723a20646f206e6f742073656e6420455460448201526e48206469726563746c79206865726560881b60648201526084015b60405180910390fd5b600080fd5b34801561015c57600080fd5b50610165606081565b6040519081526020015b60405180910390f35b34801561018457600080fd5b5061018d6102eb565b005b34801561019b57600080fd5b50610165606481565b3480156101b057600080fd5b50610165603081565b61018d6101c7366004610b12565b610325565b3480156101d857600080fd5b5060005460ff16604051901515815260200161016f565b3480156101fb57600080fd5b5061018d610806565b34801561021057600080fd5b5061018d610885565b34801561022557600080fd5b5060005461010090046001600160a01b03165b6040516001600160a01b03909116815260200161016f565b34801561025c57600080fd5b50610165602081565b34801561027157600080fd5b506101656801bc16d674ec80000081565b34801561028e57600080fd5b506102387f00000000000000000000000000000000219ab540356cbb839cbe05303d7705fa81565b3480156102c257600080fd5b5061018d6102d1366004610bd6565b6108bd565b3480156102e257600080fd5b50610165600181565b6000546001600160a01b0361010090910416331461031b5760405162461bcd60e51b815260040161014290610c06565b6103236109b8565b565b60005460ff161561036b5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610142565b86801580159061037c575060648111155b6103fc5760405162461bcd60e51b815260206004820152604560248201527f503270457468324465706f7369746f723a20796f752063616e206465706f736960448201527f74206f6e6c79203120746f20313030206e6f64657320706572207472616e736160648201526431ba34b7b760d91b608482015260a401610142565b61040f816801bc16d674ec800000610c51565b34146104925760405162461bcd60e51b815260206004820152604660248201527f503270457468324465706f7369746f723a2074686520616d6f756e74206f662060448201527f45544820646f6573206e6f74206d617463682074686520616d6f756e74206f66606482015265206e6f64657360d01b608482015260a401610142565b85811480156104a057508381145b80156104ab57508181145b6105125760405162461bcd60e51b815260206004820152603260248201527f503270457468324465706f7369746f723a20616d6f756e74206f6620706172616044820152710dacae8cae4e640c8de40dcde40dac2e8c6d60731b6064820152608401610142565b60005b818110156107c15760308a8a8381811061053157610531610c70565b90506020028101906105439190610c86565b9050146105925760405162461bcd60e51b815260206004820152601e60248201527f503270457468324465706f7369746f723a2077726f6e67207075626b657900006044820152606401610142565b60208888838181106105a6576105a6610c70565b90506020028101906105b89190610c86565b90501461061e5760405162461bcd60e51b815260206004820152602e60248201527f503270457468324465706f7369746f723a2077726f6e6720776974686472617760448201526d616c2063726564656e7469616c7360901b6064820152608401610142565b606086868381811061063257610632610c70565b90506020028101906106449190610c86565b90501461069e5760405162461bcd60e51b815260206004820152602260248201527f503270457468324465706f7369746f723a2077726f6e67207369676e61747572604482015261657360f01b6064820152608401610142565b7f00000000000000000000000000000000219ab540356cbb839cbe05303d7705fa6001600160a01b031663228951186801bc16d674ec8000008c8c858181106106e9576106e9610c70565b90506020028101906106fb9190610c86565b8c8c8781811061070d5761070d610c70565b905060200281019061071f9190610c86565b8c8c8981811061073157610731610c70565b90506020028101906107439190610c86565b8c8c8b81811061075557610755610c70565b905060200201356040518963ffffffff1660e01b815260040161077e9796959493929190610cf6565b6000604051808303818588803b15801561079757600080fd5b505af11580156107ab573d6000803e3d6000fd5b5050505050806107ba90610d47565b9050610515565b5060408051338152602081018390527f2d8a08b6430a894aea608bcaa6013d5d3e263bc49110605e4d4ba76930ae5c29910160405180910390a1505050505050505050565b6000546001600160a01b036101009091041633146108365760405162461bcd60e51b815260040161014290610c06565b600080546040516101009091046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360008054610100600160a81b0319169055565b6000546001600160a01b036101009091041633146108b55760405162461bcd60e51b815260040161014290610c06565b610323610a4b565b6000546001600160a01b036101009091041633146108ed5760405162461bcd60e51b815260040161014290610c06565b6001600160a01b0381166109525760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610142565b600080546040516001600160a01b038085169361010090930416917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b60005460ff16610a015760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610142565b6000805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60005460ff1615610a915760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610142565b6000805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610a2e3390565b60008083601f840112610ad857600080fd5b50813567ffffffffffffffff811115610af057600080fd5b6020830191508360208260051b8501011115610b0b57600080fd5b9250929050565b6000806000806000806000806080898b031215610b2e57600080fd5b883567ffffffffffffffff80821115610b4657600080fd5b610b528c838d01610ac6565b909a50985060208b0135915080821115610b6b57600080fd5b610b778c838d01610ac6565b909850965060408b0135915080821115610b9057600080fd5b610b9c8c838d01610ac6565b909650945060608b0135915080821115610bb557600080fd5b50610bc28b828c01610ac6565b999c989b5096995094979396929594505050565b600060208284031215610be857600080fd5b81356001600160a01b0381168114610bff57600080fd5b9392505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615610c6b57610c6b610c3b565b500290565b634e487b7160e01b600052603260045260246000fd5b6000808335601e19843603018112610c9d57600080fd5b83018035915067ffffffffffffffff821115610cb857600080fd5b602001915036819003821315610b0b57600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b608081526000610d0a60808301898b610ccd565b8281036020840152610d1d81888a610ccd565b90508281036040840152610d32818688610ccd565b91505082606083015298975050505050505050565b6000600019821415610d5b57610d5b610c3b565b506001019056fea264697066735822122036465195807c963f1d353c646a2a962e03a99fdd0a38fba080ac4365fe5c7df964736f6c634300080a0033
Verified Source Code Full Match
Compiler: v0.8.10+commit.fc410830
EVM: london
Optimization: Yes (200 runs)
P2pEth2Depositor.sol 115 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import "./@openzeppelin/contracts/access/Ownable.sol";
import "./@openzeppelin/contracts/utils/Pausable.sol";
import "./interfaces/IDepositContract.sol";
contract P2pEth2Depositor is Pausable, Ownable {
/**
* @dev Eth2 Deposit Contract address.
*/
IDepositContract public immutable depositContract;
/**
* @dev Minimal and maximum amount of nodes per transaction.
*/
uint256 public constant nodesMinAmount = 1;
uint256 public constant nodesMaxAmount = 100;
uint256 public constant pubkeyLength = 48;
uint256 public constant credentialsLength = 32;
uint256 public constant signatureLength = 96;
/**
* @dev Collateral size of one node.
*/
uint256 public constant collateral = 32 ether;
/**
* @dev Setting Eth2 Smart Contract address during construction.
*/
constructor(bool mainnet, address depositContract_) {
depositContract = mainnet
? IDepositContract(0x00000000219ab540356cBB839Cbe05303d7705Fa)
: (depositContract_ == 0x0000000000000000000000000000000000000000)
? IDepositContract(0x8c5fecdC472E27Bc447696F431E425D02dd46a8c)
: IDepositContract(depositContract_);
}
/**
* @dev This contract will not accept direct ETH transactions.
*/
receive() external payable {
revert("P2pEth2Depositor: do not send ETH directly here");
}
/**
* @dev Function that allows to deposit up to 100 nodes at once.
*
* - pubkeys - Array of BLS12-381 public keys.
* - withdrawal_credentials - Array of commitments to a public keys for withdrawals.
* - signatures - Array of BLS12-381 signatures.
* - deposit_data_roots - Array of the SHA-256 hashes of the SSZ-encoded DepositData objects.
*/
function deposit(
bytes[] calldata pubkeys,
bytes[] calldata withdrawal_credentials,
bytes[] calldata signatures,
bytes32[] calldata deposit_data_roots
) external payable whenNotPaused {
uint256 nodesAmount = pubkeys.length;
require(nodesAmount > 0 && nodesAmount <= 100, "P2pEth2Depositor: you can deposit only 1 to 100 nodes per transaction");
require(msg.value == collateral * nodesAmount, "P2pEth2Depositor: the amount of ETH does not match the amount of nodes");
require(
withdrawal_credentials.length == nodesAmount &&
signatures.length == nodesAmount &&
deposit_data_roots.length == nodesAmount,
"P2pEth2Depositor: amount of parameters do no match");
for (uint256 i = 0; i < nodesAmount; ++i) {
require(pubkeys[i].length == pubkeyLength, "P2pEth2Depositor: wrong pubkey");
require(withdrawal_credentials[i].length == credentialsLength, "P2pEth2Depositor: wrong withdrawal credentials");
require(signatures[i].length == signatureLength, "P2pEth2Depositor: wrong signatures");
depositContract.deposit{value: collateral}(
pubkeys[i],
withdrawal_credentials[i],
signatures[i],
deposit_data_roots[i]
);
}
emit DepositEvent(msg.sender, nodesAmount);
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function pause() public onlyOwner {
_pause();
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function unpause() public onlyOwner {
_unpause();
}
event DepositEvent(address from, uint256 nodesAmount);
}
IDepositContract.sol 38 lines
// SPDX-License-Identifier: CC0-1.0
pragma solidity 0.8.10;
// 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);
}
Context.sol 24 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
Ownable.sol 68 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor () {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
Pausable.sol 90 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import "./Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor () {
_paused = false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
require(paused(), "Pausable: not paused");
_;
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
Read Contract
collateral 0xd8dfeb45 → uint256
credentialsLength 0xa5ab1d31 → uint256
depositContract 0xe94ad65b → address
nodesMaxAmount 0x43ba591d → uint256
nodesMinAmount 0xf4fbdfac → uint256
owner 0x8da5cb5b → address
paused 0x5c975abb → bool
pubkeyLength 0x4903e8be → uint256
signatureLength 0x1b9a9323 → uint256
Write Contract 5 functions
These functions modify contract state and require a wallet transaction to execute.
deposit 0x4f498c73
bytes[] pubkeys
bytes[] withdrawal_credentials
bytes[] signatures
bytes32[] deposit_data_roots
pause 0x8456cb59
No parameters
renounceOwnership 0x715018a6
No parameters
transferOwnership 0xf2fde38b
address newOwner
unpause 0x3f4ba83a
No parameters
Recent Transactions
No transactions found for this address