Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers.
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
|||
|---|---|---|---|---|---|---|---|---|
| Transfer* | 24238766 | 2 days ago | 0 ETH | |||||
| Transfer* | 24238766 | 2 days ago | 0 ETH | |||||
| Transfer* | 24238766 | 2 days ago | 0 ETH | |||||
| Transfer* | 24238766 | 2 days ago | 0 ETH | |||||
| Transfer* | 24238766 | 2 days ago | 0 ETH | |||||
| Transfer* | 24238766 | 2 days ago | 0 ETH | |||||
| Transfer* | 24238766 | 2 days ago | 0 ETH | |||||
| Transfer* | 24238766 | 2 days ago | 0 ETH | |||||
| Transfer* | 24238766 | 2 days ago | 0 ETH | |||||
| Transfer* | 24238766 | 2 days ago | 0 ETH | |||||
| Merkleize Pendin... | 24238766 | 2 days ago | 0 ETH | |||||
| Transfer* | 24174925 | 11 days ago | 0 ETH | |||||
| Transfer* | 24174925 | 11 days ago | 0 ETH | |||||
| Transfer* | 24174925 | 11 days ago | 0 ETH | |||||
| Transfer* | 24174925 | 11 days ago | 0 ETH | |||||
| Transfer* | 24174925 | 11 days ago | 0 ETH | |||||
| Transfer* | 24174925 | 11 days ago | 0 ETH | |||||
| Transfer* | 24174925 | 11 days ago | 0 ETH | |||||
| Transfer* | 24174925 | 11 days ago | 0 ETH | |||||
| Transfer* | 24174925 | 11 days ago | 0 ETH | |||||
| Transfer* | 24174925 | 11 days ago | 0 ETH | |||||
| Transfer* | 24174925 | 11 days ago | 0 ETH | |||||
| Transfer* | 24174925 | 11 days ago | 0 ETH | |||||
| Transfer* | 24174925 | 11 days ago | 0 ETH | |||||
| Transfer* | 24174925 | 11 days ago | 0 ETH |
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
BeaconProofs
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import { BeaconProofsLib } from "./BeaconProofsLib.sol";
import { IBeaconProofs } from "../interfaces/IBeaconProofs.sol";
/**
* @title Verifies merkle proofs of beacon chain data.
* @author Origin Protocol Inc
*/
contract BeaconProofs is IBeaconProofs {
/// @notice Verifies the validator index is for the given validator public key.
/// Also verify the validator's withdrawal credential points to the withdrawal address.
/// BeaconBlock.state.validators[validatorIndex].pubkey
/// @param beaconBlockRoot The root of the beacon block
/// @param pubKeyHash Hash of validator's public key using the Beacon Chain's format
/// @param proof The merkle proof for the validator public key to the beacon block root.
/// This is 53 witness hashes of 32 bytes each concatenated together starting from the leaf node.
/// @param validatorIndex The validator index
/// @param withdrawalCredentials a value containing the validator type and withdrawal address.
function verifyValidator(
bytes32 beaconBlockRoot,
bytes32 pubKeyHash,
bytes calldata proof,
uint40 validatorIndex,
bytes32 withdrawalCredentials
) external view {
BeaconProofsLib.verifyValidator(
beaconBlockRoot,
pubKeyHash,
proof,
validatorIndex,
withdrawalCredentials
);
}
function verifyValidatorWithdrawable(
bytes32 beaconBlockRoot,
uint40 validatorIndex,
uint64 withdrawableEpoch,
bytes calldata withdrawableEpochProof
) external view {
BeaconProofsLib.verifyValidatorWithdrawableEpoch(
beaconBlockRoot,
validatorIndex,
withdrawableEpoch,
withdrawableEpochProof
);
}
/// @notice Verifies the balances container to the beacon block root
/// BeaconBlock.state.balances
/// @param beaconBlockRoot The root of the beacon block
/// @param balancesContainerRoot The merkle root of the the balances container
/// @param balancesContainerProof The merkle proof for the balances container to the beacon block root.
/// This is 9 witness hashes of 32 bytes each concatenated together starting from the leaf node.
function verifyBalancesContainer(
bytes32 beaconBlockRoot,
bytes32 balancesContainerRoot,
bytes calldata balancesContainerProof
) external view {
BeaconProofsLib.verifyBalancesContainer(
beaconBlockRoot,
balancesContainerRoot,
balancesContainerProof
);
}
/// @notice Verifies the validator balance to the root of the Balances container.
/// @param balancesContainerRoot The merkle root of the Balances container.
/// @param validatorBalanceLeaf The leaf node containing the validator balance with three other balances.
/// @param balanceProof The merkle proof for the validator balance to the Balances container root.
/// This is 39 witness hashes of 32 bytes each concatenated together starting from the leaf node.
/// @param validatorIndex The validator index to verify the balance for
/// @return validatorBalanceGwei The balance in Gwei of the validator at the given index
function verifyValidatorBalance(
bytes32 balancesContainerRoot,
bytes32 validatorBalanceLeaf,
bytes calldata balanceProof,
uint40 validatorIndex
) external view returns (uint256 validatorBalanceGwei) {
validatorBalanceGwei = BeaconProofsLib.verifyValidatorBalance(
balancesContainerRoot,
validatorBalanceLeaf,
balanceProof,
validatorIndex
);
}
/// @notice Verifies the pending deposits container to the beacon block root.
/// BeaconBlock.state.pendingDeposits
/// @param beaconBlockRoot The root of the beacon block.
/// @param pendingDepositsContainerRoot The merkle root of the the pending deposits container.
/// @param proof The merkle proof for the pending deposits container to the beacon block root.
/// This is 9 witness hashes of 32 bytes each concatenated together starting from the leaf node.
function verifyPendingDepositsContainer(
bytes32 beaconBlockRoot,
bytes32 pendingDepositsContainerRoot,
bytes calldata proof
) external view {
BeaconProofsLib.verifyPendingDepositsContainer(
beaconBlockRoot,
pendingDepositsContainerRoot,
proof
);
}
/// @notice Verified a pending deposit to the root of the Pending Deposits container.
/// @param pendingDepositsContainerRoot The merkle root of the Pending Deposits container.
/// @param pendingDepositRoot The leaf node containing the validator balance with three other balances.
/// @param proof The merkle proof for the pending deposit root to the Pending Deposits container root.
/// This is 28 witness hashes of 32 bytes each concatenated together starting from the leaf node.
/// @param pendingDepositIndex The pending deposit index in the Pending Deposits container
function verifyPendingDeposit(
bytes32 pendingDepositsContainerRoot,
bytes32 pendingDepositRoot,
bytes calldata proof,
uint32 pendingDepositIndex
) external view {
BeaconProofsLib.verifyPendingDeposit(
pendingDepositsContainerRoot,
pendingDepositRoot,
proof,
pendingDepositIndex
);
}
/// @notice If the deposit queue is not empty,
/// verify the slot of the first pending deposit to the beacon block root.
/// BeaconBlock.state.pendingDeposits[0].slot
/// If the deposit queue is empty, verify the root of the first pending deposit is empty
/// BeaconBlock.state.PendingDeposits[0]
/// @param beaconBlockRoot The root of the beacon block.
/// @param slot The beacon chain slot of the first deposit in the beacon chain's deposit queue.
/// Can be anything if the deposit queue is empty.
/// @param firstPendingDepositSlotProof The merkle proof to the beacon block root. Can be either:
/// - 40 witness hashes for BeaconBlock.state.PendingDeposits[0].slot when the deposit queue is not empty.
/// - 37 witness hashes for BeaconBlock.state.PendingDeposits[0] when the deposit queue is empty.
/// The 32 byte witness hashes are concatenated together starting from the leaf node.
/// @return isEmptyDepositQueue True if the deposit queue is empty, false otherwise.
function verifyFirstPendingDeposit(
bytes32 beaconBlockRoot,
uint64 slot,
bytes calldata firstPendingDepositSlotProof
) external view returns (bool isEmptyDepositQueue) {
isEmptyDepositQueue = BeaconProofsLib.verifyFirstPendingDeposit(
beaconBlockRoot,
slot,
firstPendingDepositSlotProof
);
}
/// @notice Merkleizes a beacon chain pending deposit.
/// @param pubKeyHash Hash of validator's public key using the Beacon Chain's format
/// @param withdrawalCredentials The 32 byte withdrawal credentials.
/// @param amountGwei The amount of the deposit in Gwei.
/// @param signature The 96 byte BLS signature.
/// @param slot The beacon chain slot the deposit was made in.
/// @return root The merkle root of the pending deposit.
function merkleizePendingDeposit(
bytes32 pubKeyHash,
bytes calldata withdrawalCredentials,
uint64 amountGwei,
bytes calldata signature,
uint64 slot
) external pure returns (bytes32) {
return
BeaconProofsLib.merkleizePendingDeposit(
pubKeyHash,
withdrawalCredentials,
amountGwei,
signature,
slot
);
}
/// @notice Merkleizes a BLS signature used for validator deposits.
/// @param signature The 96 byte BLS signature.
/// @return root The merkle root of the signature.
function merkleizeSignature(bytes calldata signature)
external
pure
returns (bytes32 root)
{
return BeaconProofsLib.merkleizeSignature(signature);
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import { Merkle } from "./Merkle.sol";
import { Endian } from "./Endian.sol";
/**
* @title Library to verify merkle proofs of beacon chain data.
* @author Origin Protocol Inc
*/
library BeaconProofsLib {
// Known generalized indices in the beacon block
/// @dev BeaconBlock.state.PendingDeposits[0]
/// Beacon block container: height 3, state at at index 3
/// Beacon state container: height 6, pending deposits at index 34
/// Pending deposits container: height 28, first deposit at index 0
/// ((2 ^ 3 + 3) * 2 ^ 6 + 34) * 2 ^ 28 + 0 = 198105366528
uint256 internal constant FIRST_PENDING_DEPOSIT_GENERALIZED_INDEX =
198105366528;
/// @dev BeaconBlock.state.PendingDeposits[0].pubkey
/// Pending Deposit container: height 3, pubkey at index 4
/// (((2 ^ 3 + 3) * 2 ^ 6 + 34) * 2 ^ 28 + 0) * 2 ^ 3 + 4 = 1584842932228
uint256 internal constant FIRST_PENDING_DEPOSIT_SLOT_GENERALIZED_INDEX =
1584842932228;
/// @dev BeaconBlock.state.validators
/// Beacon block container: height 3, state at at index 3
/// Beacon state container: height 6, validators at index 11
/// (2 ^ 3 + 3) * 2 ^ 6 + 11 = 715
uint256 internal constant VALIDATORS_CONTAINER_GENERALIZED_INDEX = 715;
/// @dev BeaconBlock.state.balances
/// Beacon block container: height 3, state at at index 3
/// Beacon state container: height 6, balances at index 12
/// (2 ^ 3 + 3) * 2 ^ 6 + 12 = 716
uint256 internal constant BALANCES_CONTAINER_GENERALIZED_INDEX = 716;
/// @dev BeaconBlock.state.pendingDeposits
/// Beacon block container: height 3, state at at index 3
/// Beacon state container: height 6, balances at index 34
/// (2 ^ 3 + 3) * 2 ^ 6 + 34 = 738
uint256 internal constant PENDING_DEPOSITS_CONTAINER_GENERALIZED_INDEX =
738;
/// @dev Number of bytes in the proof to the first pending deposit.
/// 37 witness hashes of 32 bytes each concatenated together.
/// BeaconBlock.state.PendingDeposits[0]
/// 37 * 32 bytes = 1184 bytes
uint256 internal constant FIRST_PENDING_DEPOSIT_PROOF_LENGTH = 1184;
/// @dev Number of bytes in the proof from the slot of the first pending deposit to the beacon block root.
/// 40 witness hashes of 32 bytes each concatenated together.
/// BeaconBlock.state.PendingDeposits[0].slot
/// 40 * 32 bytes = 1280 bytes
uint256 internal constant FIRST_PENDING_DEPOSIT_SLOT_PROOF_LENGTH = 1280;
/// @dev Merkle height of the Balances container
/// BeaconBlock.state.balances
uint256 internal constant BALANCES_HEIGHT = 39;
/// @dev Merkle height of the Validators container list
/// BeaconBlock.state.validators
uint256 internal constant VALIDATORS_LIST_HEIGHT = 41;
/// @dev Merkle height of the Pending Deposits container list
/// BeaconBlock.state.pendingDeposits
uint256 internal constant PENDING_DEPOSITS_LIST_HEIGHT = 28;
/// @dev Merkle height of the Validator container
/// BeaconBlock.state.validators[validatorIndex]
uint256 internal constant VALIDATOR_CONTAINER_HEIGHT = 3;
/// @dev Position of the pubkey field in the Validator container.
/// BeaconBlock.state.validators[validatorIndex].pubkey
uint256 internal constant VALIDATOR_PUBKEY_INDEX = 0;
/// @dev Position of the withdrawable epoch field in the Validator container.
/// BeaconBlock.state.validators[validatorIndex].withdrawableEpoch
uint256 internal constant VALIDATOR_WITHDRAWABLE_EPOCH_INDEX = 7;
/// @notice Verifies the validator index is for the given validator public key.
/// Also verify the validator's withdrawal credential points to the withdrawal address.
/// BeaconBlock.state.validators[validatorIndex].pubkey
/// @param beaconBlockRoot The root of the beacon block
/// @param pubKeyHash Hash of validator's public key using the Beacon Chain's format
/// @param proof The merkle proof for the validator public key to the beacon block root.
/// This is 53 witness hashes of 32 bytes each concatenated together starting from the leaf node.
/// @param validatorIndex The validator index
/// @param withdrawalCredentials a value containing the validator type and withdrawal address.
function verifyValidator(
bytes32 beaconBlockRoot,
bytes32 pubKeyHash,
bytes calldata proof,
uint40 validatorIndex,
bytes32 withdrawalCredentials
) internal view {
require(beaconBlockRoot != bytes32(0), "Invalid block root");
// BeaconBlock.state.validators[validatorIndex]
uint256 generalizedIndex = concatGenIndices(
VALIDATORS_CONTAINER_GENERALIZED_INDEX,
VALIDATORS_LIST_HEIGHT,
validatorIndex
);
// BeaconBlock.state.validators[validatorIndex].pubkey
generalizedIndex = concatGenIndices(
generalizedIndex,
VALIDATOR_CONTAINER_HEIGHT,
VALIDATOR_PUBKEY_INDEX
);
// Get the withdrawal credentials from the first witness in the pubkey merkle proof.
bytes32 withdrawalCredentialsFromProof = bytes32(proof[:32]);
require(
withdrawalCredentialsFromProof == withdrawalCredentials,
"Invalid withdrawal cred"
);
require(
// 53 * 32 bytes = 1696 bytes
proof.length == 1696 &&
Merkle.verifyInclusionSha256({
proof: proof,
root: beaconBlockRoot,
leaf: pubKeyHash,
index: generalizedIndex
}),
"Invalid validator proof"
);
}
/// @notice Verifies a validator's withdrawable epoch to the beacon block root
/// for a given validator index.
/// BeaconBlock.state.validators[validatorIndex].withdrawableEpoch
/// @param beaconBlockRoot The root of the beacon block
/// @param validatorIndex The validator index to verify the withdrawable epoch for.
/// @param withdrawableEpoch The withdrawable epoch to verify in big endian uint64 format
/// @param proof The merkle proof for the validator's withdrawable epoch to the beacon block root.
/// This is 53 witness hashes of 32 bytes each concatenated together starting from the leaf node.
function verifyValidatorWithdrawableEpoch(
bytes32 beaconBlockRoot,
uint40 validatorIndex,
uint64 withdrawableEpoch,
bytes calldata proof
) internal view {
require(beaconBlockRoot != bytes32(0), "Invalid block root");
// BeaconBlock.state.validators[validatorIndex]
uint256 exitEpochGenIndex = concatGenIndices(
VALIDATORS_CONTAINER_GENERALIZED_INDEX,
VALIDATORS_LIST_HEIGHT,
validatorIndex
);
// BeaconBlock.state.validators[validatorIndex].withdrawableEpoch
exitEpochGenIndex = concatGenIndices(
exitEpochGenIndex,
VALIDATOR_CONTAINER_HEIGHT,
VALIDATOR_WITHDRAWABLE_EPOCH_INDEX
);
require(
// 53 * 32 bytes = 1696 bytes
proof.length == 1696 &&
Merkle.verifyInclusionSha256({
proof: proof,
root: beaconBlockRoot,
leaf: Endian.toLittleEndianUint64(withdrawableEpoch),
index: exitEpochGenIndex
}),
"Invalid withdrawable proof"
);
}
/// @notice Verifies the balances container to the beacon block root.
/// BeaconBlock.state.balances
/// @param beaconBlockRoot The root of the beacon block.
/// @param balancesContainerRoot The merkle root of the the balances container.
/// @param proof The merkle proof for the balances container to the beacon block root.
/// This is 9 witness hashes of 32 bytes each concatenated together starting from the leaf node.
function verifyBalancesContainer(
bytes32 beaconBlockRoot,
bytes32 balancesContainerRoot,
bytes calldata proof
) internal view {
require(beaconBlockRoot != bytes32(0), "Invalid block root");
// BeaconBlock.state.balances
require(
// 9 * 32 bytes = 288 bytes
proof.length == 288 &&
Merkle.verifyInclusionSha256({
proof: proof,
root: beaconBlockRoot,
leaf: balancesContainerRoot,
index: BALANCES_CONTAINER_GENERALIZED_INDEX
}),
"Invalid balance container proof"
);
}
/// @notice Verifies the validator balance to the root of the Balances container.
/// @param balancesContainerRoot The merkle root of the Balances container.
/// @param validatorBalanceLeaf The leaf node containing the validator balance with three other balances.
/// @param proof The merkle proof for the validator balance to the Balances container root.
/// This is 39 witness hashes of 32 bytes each concatenated together starting from the leaf node.
/// @param validatorIndex The validator index to verify the balance for.
/// @return validatorBalanceGwei The balance in Gwei of the validator at the given index.
function verifyValidatorBalance(
bytes32 balancesContainerRoot,
bytes32 validatorBalanceLeaf,
bytes calldata proof,
uint40 validatorIndex
) internal view returns (uint256 validatorBalanceGwei) {
require(balancesContainerRoot != bytes32(0), "Invalid container root");
// Four balances are stored in each leaf so the validator index is divided by 4
uint64 balanceIndex = validatorIndex / 4;
// Get the index within the balances container, not the Beacon Block
// BeaconBlock.state.balances[balanceIndex]
uint256 generalizedIndex = concatGenIndices(
1,
BALANCES_HEIGHT,
balanceIndex
);
validatorBalanceGwei = balanceAtIndex(
validatorBalanceLeaf,
validatorIndex
);
require(
// 39 * 32 bytes = 1248 bytes
proof.length == 1248 &&
Merkle.verifyInclusionSha256({
proof: proof,
root: balancesContainerRoot,
leaf: validatorBalanceLeaf,
index: generalizedIndex
}),
"Invalid balance proof"
);
}
/// @notice Verifies the pending deposits container to the beacon block root.
/// BeaconBlock.state.pendingDeposits
/// @param beaconBlockRoot The root of the beacon block.
/// @param pendingDepositsContainerRoot The merkle root of the the pending deposits container.
/// @param proof The merkle proof for the pending deposits container to the beacon block root.
/// This is 9 witness hashes of 32 bytes each concatenated together starting from the leaf node.
function verifyPendingDepositsContainer(
bytes32 beaconBlockRoot,
bytes32 pendingDepositsContainerRoot,
bytes calldata proof
) internal view {
require(beaconBlockRoot != bytes32(0), "Invalid block root");
// BeaconBlock.state.pendingDeposits
require(
// 9 * 32 bytes = 288 bytes
proof.length == 288 &&
Merkle.verifyInclusionSha256({
proof: proof,
root: beaconBlockRoot,
leaf: pendingDepositsContainerRoot,
index: PENDING_DEPOSITS_CONTAINER_GENERALIZED_INDEX
}),
"Invalid deposit container proof"
);
}
/// @notice Verifies a pending deposit in the pending deposits container.
/// BeaconBlock.state.pendingDeposits[depositIndex]
/// @param pendingDepositsContainerRoot The merkle root of the pending deposits list container
/// @param pendingDepositRoot The merkle root of the pending deposit to verify
/// @param proof The merkle proof for the pending deposit root to the pending deposits list container root.
/// This is 28 witness hashes of 32 bytes each concatenated together starting from the leaf node.
/// @param pendingDepositIndex The index in the pending deposits list container for the deposit to verify.
function verifyPendingDeposit(
bytes32 pendingDepositsContainerRoot,
bytes32 pendingDepositRoot,
bytes calldata proof,
uint32 pendingDepositIndex
) internal view {
require(pendingDepositsContainerRoot != bytes32(0), "Invalid root");
// ssz-merkleizing a list which has a variable length, an additional
// sha256(pending_deposits_root, pending_deposits_length) operation is done to get the
// actual pending deposits root so the max pending deposit index is 2^(28 - 1)
require(
pendingDepositIndex < 2**(PENDING_DEPOSITS_LIST_HEIGHT - 1),
"Invalid deposit index"
);
// BeaconBlock.state.pendingDeposits[depositIndex]
uint256 generalizedIndex = concatGenIndices(
1,
PENDING_DEPOSITS_LIST_HEIGHT,
pendingDepositIndex
);
require(
// 28 * 32 bytes = 896 bytes
proof.length == 896 &&
Merkle.verifyInclusionSha256({
proof: proof,
root: pendingDepositsContainerRoot,
leaf: pendingDepositRoot,
index: generalizedIndex
}),
"Invalid deposit proof"
);
}
/// @notice If the deposit queue is not empty,
/// verify the slot of the first pending deposit to the beacon block root.
/// BeaconBlock.state.pendingDeposits[0].slot
/// If the deposit queue is empty, verify the root of the first pending deposit is empty
/// BeaconBlock.state.PendingDeposits[0]
/// @param beaconBlockRoot The root of the beacon block.
/// @param slot The beacon chain slot of the first deposit in the beacon chain's deposit queue.
/// Can be anything if the deposit queue is empty.
/// @param proof The merkle proof to the beacon block root. Can be either:
/// - 40 witness hashes for BeaconBlock.state.PendingDeposits[0].slot when the deposit queue is not empty.
/// - 37 witness hashes for BeaconBlock.state.PendingDeposits[0] when the deposit queue is empty.
/// The 32 byte witness hashes are concatenated together starting from the leaf node.
/// @return isEmptyDepositQueue True if the deposit queue is empty, false otherwise.
function verifyFirstPendingDeposit(
bytes32 beaconBlockRoot,
uint64 slot,
bytes calldata proof
) internal view returns (bool isEmptyDepositQueue) {
require(beaconBlockRoot != bytes32(0), "Invalid block root");
// If the deposit queue is empty
if (proof.length == FIRST_PENDING_DEPOSIT_PROOF_LENGTH) {
require(
Merkle.verifyInclusionSha256({
proof: proof,
root: beaconBlockRoot,
leaf: bytes32(0),
index: FIRST_PENDING_DEPOSIT_GENERALIZED_INDEX
}),
"Invalid empty deposits proof"
);
return true;
}
// Verify the public key of the first pending deposit
// BeaconBlock.state.PendingDeposits[0].slot
require(
proof.length == FIRST_PENDING_DEPOSIT_SLOT_PROOF_LENGTH &&
Merkle.verifyInclusionSha256({
proof: proof,
root: beaconBlockRoot,
leaf: Endian.toLittleEndianUint64(slot),
index: FIRST_PENDING_DEPOSIT_SLOT_GENERALIZED_INDEX
}),
"Invalid deposit slot proof"
);
}
/// @notice Merkleizes a beacon chain pending deposit.
/// @param pubKeyHash Hash of validator's public key using the Beacon Chain's format
/// @param withdrawalCredentials The 32 byte withdrawal credentials.
/// @param amountGwei The amount of the deposit in Gwei.
/// @param signature The 96 byte BLS signature.
/// @param slot The beacon chain slot the deposit was made in.
/// @return root The merkle root of the pending deposit.
function merkleizePendingDeposit(
bytes32 pubKeyHash,
bytes calldata withdrawalCredentials,
uint64 amountGwei,
bytes calldata signature,
uint64 slot
) internal pure returns (bytes32 root) {
bytes32[] memory leaves = new bytes32[](8);
leaves[0] = pubKeyHash;
leaves[1] = bytes32(withdrawalCredentials[:32]);
leaves[2] = Endian.toLittleEndianUint64(amountGwei);
leaves[3] = merkleizeSignature(signature);
leaves[4] = Endian.toLittleEndianUint64(slot);
leaves[5] = bytes32(0);
leaves[6] = bytes32(0);
leaves[7] = bytes32(0);
root = Merkle.merkleizeSha256(leaves);
}
/// @notice Merkleizes a BLS signature used for validator deposits.
/// @param signature The 96 byte BLS signature.
/// @return root The merkle root of the signature.
function merkleizeSignature(bytes calldata signature)
internal
pure
returns (bytes32)
{
require(signature.length == 96, "Invalid signature");
bytes32[] memory leaves = new bytes32[](4);
leaves[0] = bytes32(signature[:32]);
leaves[1] = bytes32(signature[32:64]);
leaves[2] = bytes32(signature[64:96]);
leaves[3] = bytes32(0);
return Merkle.merkleizeSha256(leaves);
}
////////////////////////////////////////////////////
/// Internal Helper Functions
////////////////////////////////////////////////////
function balanceAtIndex(bytes32 validatorBalanceLeaf, uint40 validatorIndex)
internal
pure
returns (uint256)
{
uint256 bitShiftAmount = (validatorIndex % 4) * 64;
return
Endian.fromLittleEndianUint64(
bytes32((uint256(validatorBalanceLeaf) << bitShiftAmount))
);
}
/// @notice Concatenates two beacon chain generalized indices into one.
/// @param genIndex The first generalized index or 1 if calculating for a single container.
/// @param height The merkle tree height of the second container. eg 39 for balances, 41 for validators.
/// @param index The index within the second container. eg the validator index.
/// @return genIndex The concatenated generalized index.
function concatGenIndices(
uint256 genIndex,
uint256 height,
uint256 index
) internal pure returns (uint256) {
return (genIndex << height) | index;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @title Library to handle conversion between little-endian and big-endian formats.
* @author Origin Protocol Inc
*/
library Endian {
/**
* @notice Converts a little endian-formatted uint64 to a big endian-formatted uint64
* @param lenum little endian-formatted uint64 input, provided as 'bytes32' type
* @return n The big endian-formatted uint64
* @dev Note that the input is formatted as a 'bytes32' type (i.e. 256 bits),
* but it is immediately truncated to a uint64 (i.e. 64 bits)
* through a right-shift/shr operation.
*/
function fromLittleEndianUint64(bytes32 lenum)
internal
pure
returns (uint64 n)
{
// the number needs to be stored in little-endian encoding (ie in bytes 0-8)
n = uint64(uint256(lenum >> 192));
// forgefmt: disable-next-item
return
(n >> 56) |
((0x00FF000000000000 & n) >> 40) |
((0x0000FF0000000000 & n) >> 24) |
((0x000000FF00000000 & n) >> 8) |
((0x00000000FF000000 & n) << 8) |
((0x0000000000FF0000 & n) << 24) |
((0x000000000000FF00 & n) << 40) |
((0x00000000000000FF & n) << 56);
}
function toLittleEndianUint64(uint64 benum)
internal
pure
returns (bytes32 n)
{
// Convert to little-endian by reversing byte order
uint64 reversed = (benum >> 56) |
((0x00FF000000000000 & benum) >> 40) |
((0x0000FF0000000000 & benum) >> 24) |
((0x000000FF00000000 & benum) >> 8) |
((0x00000000FF000000 & benum) << 8) |
((0x0000000000FF0000 & benum) << 24) |
((0x000000000000FF00 & benum) << 40) |
((0x00000000000000FF & benum) << 56);
// Store the little-endian uint64 in the least significant 64 bits of bytes32
n = bytes32(uint256(reversed));
// Shift to most significant bits
n = n << 192;
}
}// SPDX-License-Identifier: MIT
// Adapted from OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol)
pragma solidity ^0.8.0;
/**
* @dev These functions deal with verification of Merkle Tree proofs.
*
* The tree and the proofs can be generated using our
* https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
* You will find a quickstart guide in the readme.
*
* WARNING: You should avoid using leaf values that are 64 bytes long prior to
* hashing, or use a hash function other than keccak256 for hashing leaves.
* This is because the concatenation of a sorted pair of internal nodes in
* the merkle tree could be reinterpreted as a leaf value.
* OpenZeppelin's JavaScript library generates merkle trees that are safe
* against this attack out of the box.
*/
library Merkle {
error InvalidProofLength();
/**
* @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
* from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
* hash matches the root of the tree. The tree is built assuming `leaf` is
* the 0 indexed `index`'th leaf from the bottom left of the tree.
*
* Note this is for a Merkle tree using the sha256 hash function
*/
function verifyInclusionSha256(
bytes memory proof,
bytes32 root,
bytes32 leaf,
uint256 index
) internal view returns (bool) {
return processInclusionProofSha256(proof, leaf, index) == root;
}
/**
* @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
* from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
* hash matches the root of the tree. The tree is built assuming `leaf` is
* the 0 indexed `index`'th leaf from the bottom left of the tree.
*
* _Available since v4.4._
*
* Note this is for a Merkle tree using the sha256 hash function
*/
function processInclusionProofSha256(
bytes memory proof,
bytes32 leaf,
uint256 index
) internal view returns (bytes32) {
require(
proof.length != 0 && proof.length % 32 == 0,
InvalidProofLength()
);
bytes32[1] memory computedHash = [leaf];
for (uint256 i = 32; i <= proof.length; i += 32) {
if (index % 2 == 0) {
// if ith bit of index is 0, then computedHash is a left sibling
// solhint-disable-next-line no-inline-assembly
assembly {
mstore(0x00, mload(computedHash))
mstore(0x20, mload(add(proof, i)))
if iszero(
staticcall(
sub(gas(), 2000),
2,
0x00,
0x40,
computedHash,
0x20
)
) {
revert(0, 0)
}
}
} else {
// if ith bit of index is 1, then computedHash is a right sibling
// solhint-disable-next-line no-inline-assembly
assembly {
mstore(0x00, mload(add(proof, i)))
mstore(0x20, mload(computedHash))
if iszero(
staticcall(
sub(gas(), 2000),
2,
0x00,
0x40,
computedHash,
0x20
)
) {
revert(0, 0)
}
}
}
index = index / 2;
}
return computedHash[0];
}
/**
* @notice Returns the merkle root of a tree created from a set of leaves using sha256 as its hash function.
* @param leaves the leaves of the merkle tree
* @return The computed Merkle root of the tree.
* @dev A pre-condition to this function is that leaves.length is a power of two.
* If not, the function will merkleize the inputs incorrectly.
*/
function merkleizeSha256(bytes32[] memory leaves)
internal
pure
returns (bytes32)
{
//there are half as many nodes in the layer above the leaves
uint256 numNodesInLayer = leaves.length / 2;
//create a layer to store the internal nodes
bytes32[] memory layer = new bytes32[](numNodesInLayer);
//fill the layer with the pairwise hashes of the leaves
for (uint256 i = 0; i < numNodesInLayer; i++) {
layer[i] = sha256(
abi.encodePacked(leaves[2 * i], leaves[2 * i + 1])
);
}
//the next layer above has half as many nodes
numNodesInLayer /= 2;
//while we haven't computed the root
while (numNodesInLayer != 0) {
//overwrite the first numNodesInLayer nodes in layer with the pairwise hashes of their children
for (uint256 i = 0; i < numNodesInLayer; i++) {
layer[i] = sha256(
abi.encodePacked(layer[2 * i], layer[2 * i + 1])
);
}
//the next layer above has half as many nodes
numNodesInLayer /= 2;
}
//the first node in the layer is the root
return layer[0];
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
interface IBeaconProofs {
function verifyValidator(
bytes32 beaconBlockRoot,
bytes32 pubKeyHash,
bytes calldata validatorPubKeyProof,
uint40 validatorIndex,
bytes32 withdrawalCredentials
) external view;
function verifyValidatorWithdrawable(
bytes32 beaconBlockRoot,
uint40 validatorIndex,
uint64 withdrawableEpoch,
bytes calldata withdrawableEpochProof
) external view;
function verifyBalancesContainer(
bytes32 beaconBlockRoot,
bytes32 balancesContainerLeaf,
bytes calldata balancesContainerProof
) external view;
function verifyValidatorBalance(
bytes32 balancesContainerRoot,
bytes32 validatorBalanceLeaf,
bytes calldata balanceProof,
uint40 validatorIndex
) external view returns (uint256 validatorBalance);
function verifyPendingDepositsContainer(
bytes32 beaconBlockRoot,
bytes32 pendingDepositsContainerRoot,
bytes calldata proof
) external view;
function verifyPendingDeposit(
bytes32 pendingDepositsContainerRoot,
bytes32 pendingDepositRoot,
bytes calldata proof,
uint32 pendingDepositIndex
) external view;
function verifyFirstPendingDeposit(
bytes32 beaconBlockRoot,
uint64 slot,
bytes calldata firstPendingDepositSlotProof
) external view returns (bool isEmptyDepositQueue);
function merkleizePendingDeposit(
bytes32 pubKeyHash,
bytes calldata withdrawalCredentials,
uint64 amountGwei,
bytes calldata signature,
uint64 slot
) external pure returns (bytes32 root);
function merkleizeSignature(bytes calldata signature)
external
pure
returns (bytes32 root);
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"InvalidProofLength","type":"error"},{"inputs":[{"internalType":"bytes32","name":"pubKeyHash","type":"bytes32"},{"internalType":"bytes","name":"withdrawalCredentials","type":"bytes"},{"internalType":"uint64","name":"amountGwei","type":"uint64"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint64","name":"slot","type":"uint64"}],"name":"merkleizePendingDeposit","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"merkleizeSignature","outputs":[{"internalType":"bytes32","name":"root","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"beaconBlockRoot","type":"bytes32"},{"internalType":"bytes32","name":"balancesContainerRoot","type":"bytes32"},{"internalType":"bytes","name":"balancesContainerProof","type":"bytes"}],"name":"verifyBalancesContainer","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"beaconBlockRoot","type":"bytes32"},{"internalType":"uint64","name":"slot","type":"uint64"},{"internalType":"bytes","name":"firstPendingDepositSlotProof","type":"bytes"}],"name":"verifyFirstPendingDeposit","outputs":[{"internalType":"bool","name":"isEmptyDepositQueue","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"pendingDepositsContainerRoot","type":"bytes32"},{"internalType":"bytes32","name":"pendingDepositRoot","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"},{"internalType":"uint32","name":"pendingDepositIndex","type":"uint32"}],"name":"verifyPendingDeposit","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"beaconBlockRoot","type":"bytes32"},{"internalType":"bytes32","name":"pendingDepositsContainerRoot","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"verifyPendingDepositsContainer","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"beaconBlockRoot","type":"bytes32"},{"internalType":"bytes32","name":"pubKeyHash","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"},{"internalType":"uint40","name":"validatorIndex","type":"uint40"},{"internalType":"bytes32","name":"withdrawalCredentials","type":"bytes32"}],"name":"verifyValidator","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"balancesContainerRoot","type":"bytes32"},{"internalType":"bytes32","name":"validatorBalanceLeaf","type":"bytes32"},{"internalType":"bytes","name":"balanceProof","type":"bytes"},{"internalType":"uint40","name":"validatorIndex","type":"uint40"}],"name":"verifyValidatorBalance","outputs":[{"internalType":"uint256","name":"validatorBalanceGwei","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"beaconBlockRoot","type":"bytes32"},{"internalType":"uint40","name":"validatorIndex","type":"uint40"},{"internalType":"uint64","name":"withdrawableEpoch","type":"uint64"},{"internalType":"bytes","name":"withdrawableEpochProof","type":"bytes"}],"name":"verifyValidatorWithdrawable","outputs":[],"stateMutability":"view","type":"function"}]Contract Creation Code
6080604052348015600f57600080fd5b5061178c8061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80638a050dd4116100665780638a050dd4146100f957806391ad640d1461010c578063afe768871461011f578063d98a556414610132578063f34ad34c1461015557600080fd5b8063258b83d8146100985780632b00e796146100be578063334a88fb146100d357806354ba95b2146100e6575b600080fd5b6100ab6100a6366004611112565b610168565b6040519081526020015b60405180910390f35b6100d16100cc366004611153565b61017d565b005b6100d16100e13660046111d6565b61018f565b6100d16100f4366004611244565b6101a3565b6100d16101073660046112b5565b6101b9565b6100d161011a366004611153565b6101c6565b6100ab61012d366004611328565b6101d2565b6101456101403660046113c7565b6101ef565b60405190151581526020016100b5565b6100ab610163366004611408565b610206565b6000610174838361021f565b90505b92915050565b61018984848484610365565b50505050565b61019c8585858585610420565b5050505050565b6101b18686868686866104f8565b505050505050565b61019c8585858585610638565b61018984848484610778565b60006101e388888888888888610833565b98975050505050505050565b60006101fd858585856109ab565b95945050505050565b60006102158686868686610b19565b9695505050505050565b60006060821461026a5760405162461bcd60e51b8152602060048201526011602482015270496e76616c6964207369676e617475726560781b60448201526064015b60405180910390fd5b60408051600480825260a082019092526000916020820160808036833701905050905061029b602060008587611485565b6102a4916114af565b816000815181106102b7576102b76114cd565b6020908102919091018101919091526102d4906040908587611485565b6102dd916114af565b816001815181106102f0576102f06114cd565b6020908102919091010152610309606060408587611485565b610312916114af565b81600281518110610325576103256114cd565b6020026020010181815250506000801b81600381518110610348576103486114cd565b60200260200101818152505061035d81610c2a565b949350505050565b836103825760405162461bcd60e51b8152600401610261906114e3565b610120811480156103d457506103d482828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508892508791506102e29050610ec3565b6101895760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964206465706f73697420636f6e7461696e65722070726f6f66006044820152606401610261565b8461043d5760405162461bcd60e51b8152600401610261906114e3565b600764ffffffffff851666059600000000001760031b176106a0821480156104ac57506104ac83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a92506104a69150889050610edb565b84610ec3565b6101b15760405162461bcd60e51b815260206004820152601a60248201527f496e76616c696420776974686472617761626c652070726f6f660000000000006044820152606401610261565b856105155760405162461bcd60e51b8152600401610261906114e3565b64ffffffffff821666059600000000001760031b60006105386020828789611485565b610541916114af565b90508281146105925760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207769746864726177616c20637265640000000000000000006044820152606401610261565b6106a0851480156105e257506105e286868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b9150869050610ec3565b61062e5760405162461bcd60e51b815260206004820152601760248201527f496e76616c69642076616c696461746f722070726f6f660000000000000000006044820152606401610261565b5050505050505050565b846106745760405162461bcd60e51b815260206004820152600c60248201526b125b9d985b1a59081c9bdbdd60a21b6044820152606401610261565b6106806001601c611525565b61068b90600261161f565b8163ffffffff16106106d75760405162461bcd60e51b8152602060048201526015602482015274092dcecc2d8d2c840c8cae0dee6d2e840d2dcc8caf605b1b6044820152606401610261565b63ffffffff811663100000001761038083148015610734575061073484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a9250899150859050610ec3565b6101b15760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103232b837b9b4ba10383937b7b360591b6044820152606401610261565b836107955760405162461bcd60e51b8152600401610261906114e3565b610120811480156107e757506107e782828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508892508791506102cc9050610ec3565b6101895760405162461bcd60e51b815260206004820152601f60248201527f496e76616c69642062616c616e636520636f6e7461696e65722070726f6f66006044820152606401610261565b60408051600880825261012082019092526000918291906020820161010080368337019050509050888160008151811061086f5761086f6114cd565b60209081029190910181019190915261088b906000898b611485565b610894916114af565b816001815181106108a7576108a76114cd565b6020026020010181815250506108bc86610edb565b816002815181106108cf576108cf6114cd565b6020026020010181815250506108e5858561021f565b816003815181106108f8576108f86114cd565b60200260200101818152505061090d83610edb565b81600481518110610920576109206114cd565b6020026020010181815250506000801b81600581518110610943576109436114cd565b6020026020010181815250506000801b81600681518110610966576109666114cd565b6020026020010181815250506000801b81600781518110610989576109896114cd565b60200260200101818152505061099e81610c2a565b9998505050505050505050565b6000846109ca5760405162461bcd60e51b8152600401610261906114e3565b61049f198201610a6f57610a1b83838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508a93509150642e200000009050610ec3565b610a675760405162461bcd60e51b815260206004820152601c60248201527f496e76616c696420656d707479206465706f736974732070726f6f66000000006044820152606401610261565b50600161035d565b61050082148015610acd5750610acd83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250899250610ac19150889050610edb565b65017100000004610ec3565b61035d5760405162461bcd60e51b815260206004820152601a60248201527f496e76616c6964206465706f73697420736c6f742070726f6f660000000000006044820152606401610261565b600085610b615760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a590818dbdb9d185a5b995c881c9bdbdd60521b6044820152606401610261565b6000610b6e600484611641565b64ffffffffff1690506480000000008117610b898785610f51565b92506104e085148015610bdb5750610bdb86868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b9150859050610ec3565b610c1f5760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103130b630b731b290383937b7b360591b6044820152606401610261565b505095945050505050565b60008060028351610c3b919061166b565b90506000816001600160401b03811115610c5757610c5761146f565b604051908082528060200260200182016040528015610c80578160200160208202803683370190505b50905060005b82811015610d7d57600285610c9b838361167f565b81518110610cab57610cab6114cd565b602002602001015186836002610cc1919061167f565b610ccc906001611696565b81518110610cdc57610cdc6114cd565b6020026020010151604051602001610cfe929190918252602082015260400190565b60408051601f1981840301815290829052610d18916116a9565b602060405180830381855afa158015610d35573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610d5891906116d8565b828281518110610d6a57610d6a6114cd565b6020908102919091010152600101610c86565b50610d8960028361166b565b91505b8115610e9f5760005b82811015610e8c57600282610daa838361167f565b81518110610dba57610dba6114cd565b602002602001015183836002610dd0919061167f565b610ddb906001611696565b81518110610deb57610deb6114cd565b6020026020010151604051602001610e0d929190918252602082015260400190565b60408051601f1981840301815290829052610e27916116a9565b602060405180830381855afa158015610e44573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610e6791906116d8565b828281518110610e7957610e796114cd565b6020908102919091010152600101610d95565b50610e9860028361166b565b9150610d8c565b80600081518110610eb257610eb26114cd565b602002602001015192505050919050565b600083610ed1868585610fed565b1495945050505050565b603881811c60ff16602883811c61ff001691909117601884811c62ff00001691909117600885811c63ff000000169190911764ff000000009186901b919091161765ff00000000009185901b919091161766ff0000000000009184901b919091161760ff60381b9290911b919091161760c01b90565b600080610f5f6004846116f1565b610f6a90604061171b565b64ffffffffff169050610fdc84821b60f881901c60e882901c61ff00161760d882901c62ff0000161760c882901c63ff000000161764ff0000000060b883901c161765ff000000000060a883901c161766ff000000000000609883901c161760ff60381b60889290921c919091161790565b6001600160401b0316949350505050565b6000835160001415801561100c57506020845161100a9190611742565b155b611029576040516313717da960e21b815260040160405180910390fd5b604080516020808201909252848152905b855181116110c05761104d600285611742565b60000361107d578151600052808601516020526020826040600060026107d05a03fa61107857600080fd5b6110a1565b8086015160005281516020526020826040600060026107d05a03fa6110a157600080fd5b6110ac60028561166b565b93506110b9602082611696565b905061103a565b5051949350505050565b60008083601f8401126110dc57600080fd5b5081356001600160401b038111156110f357600080fd5b60208301915083602082850101111561110b57600080fd5b9250929050565b6000806020838503121561112557600080fd5b82356001600160401b0381111561113b57600080fd5b611147858286016110ca565b90969095509350505050565b6000806000806060858703121561116957600080fd5b843593506020850135925060408501356001600160401b0381111561118d57600080fd5b611199878288016110ca565b95989497509550505050565b803564ffffffffff811681146111ba57600080fd5b919050565b80356001600160401b03811681146111ba57600080fd5b6000806000806000608086880312156111ee57600080fd5b853594506111fe602087016111a5565b935061120c604087016111bf565b925060608601356001600160401b0381111561122757600080fd5b611233888289016110ca565b969995985093965092949392505050565b60008060008060008060a0878903121561125d57600080fd5b863595506020870135945060408701356001600160401b0381111561128157600080fd5b61128d89828a016110ca565b90955093506112a09050606088016111a5565b95989497509295919493608090920135925050565b6000806000806000608086880312156112cd57600080fd5b853594506020860135935060408601356001600160401b038111156112f157600080fd5b6112fd888289016110ca565b909450925050606086013563ffffffff8116811461131a57600080fd5b809150509295509295909350565b600080600080600080600060a0888a03121561134357600080fd5b8735965060208801356001600160401b0381111561136057600080fd5b61136c8a828b016110ca565b909750955061137f9050604089016111bf565b935060608801356001600160401b0381111561139a57600080fd5b6113a68a828b016110ca565b90945092506113b99050608089016111bf565b905092959891949750929550565b600080600080606085870312156113dd57600080fd5b843593506113ed602086016111bf565b925060408501356001600160401b0381111561118d57600080fd5b60008060008060006080868803121561142057600080fd5b853594506020860135935060408601356001600160401b0381111561144457600080fd5b611450888289016110ca565b90945092506114639050606087016111a5565b90509295509295909350565b634e487b7160e01b600052604160045260246000fd5b6000808585111561149557600080fd5b838611156114a257600080fd5b5050820193919092039150565b8035602083101561017757600019602084900360031b1b1692915050565b634e487b7160e01b600052603260045260246000fd5b602080825260129082015271125b9d985b1a5908189b1bd8dac81c9bdbdd60721b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b818103818111156101775761017761150f565b6001815b6001841115611573578085048111156115575761155761150f565b600184161561156557908102905b60019390931c92800261153c565b935093915050565b60008261158a57506001610177565b8161159757506000610177565b81600181146115ad57600281146115b7576115d3565b6001915050610177565b60ff8411156115c8576115c861150f565b50506001821b610177565b5060208310610133831016604e8410600b84101617156115f6575081810a610177565b6116036000198484611538565b80600019048211156116175761161761150f565b029392505050565b6000610174838361157b565b634e487b7160e01b600052601260045260246000fd5b600064ffffffffff8316806116585761165861162b565b8064ffffffffff84160491505092915050565b60008261167a5761167a61162b565b500490565b80820281158282048414176101775761017761150f565b808201808211156101775761017761150f565b6000825160005b818110156116ca57602081860181015185830152016116b0565b506000920191825250919050565b6000602082840312156116ea57600080fd5b5051919050565b600064ffffffffff8316806117085761170861162b565b8064ffffffffff84160691505092915050565b64ffffffffff818116838216029081169081811461173b5761173b61150f565b5092915050565b6000826117515761175161162b565b50069056fea26469706673582212205e6c180b3544abbcda0a898d1a795e4ddbd861b7b533fbede356a76fa464c51064736f6c634300081c0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100935760003560e01c80638a050dd4116100665780638a050dd4146100f957806391ad640d1461010c578063afe768871461011f578063d98a556414610132578063f34ad34c1461015557600080fd5b8063258b83d8146100985780632b00e796146100be578063334a88fb146100d357806354ba95b2146100e6575b600080fd5b6100ab6100a6366004611112565b610168565b6040519081526020015b60405180910390f35b6100d16100cc366004611153565b61017d565b005b6100d16100e13660046111d6565b61018f565b6100d16100f4366004611244565b6101a3565b6100d16101073660046112b5565b6101b9565b6100d161011a366004611153565b6101c6565b6100ab61012d366004611328565b6101d2565b6101456101403660046113c7565b6101ef565b60405190151581526020016100b5565b6100ab610163366004611408565b610206565b6000610174838361021f565b90505b92915050565b61018984848484610365565b50505050565b61019c8585858585610420565b5050505050565b6101b18686868686866104f8565b505050505050565b61019c8585858585610638565b61018984848484610778565b60006101e388888888888888610833565b98975050505050505050565b60006101fd858585856109ab565b95945050505050565b60006102158686868686610b19565b9695505050505050565b60006060821461026a5760405162461bcd60e51b8152602060048201526011602482015270496e76616c6964207369676e617475726560781b60448201526064015b60405180910390fd5b60408051600480825260a082019092526000916020820160808036833701905050905061029b602060008587611485565b6102a4916114af565b816000815181106102b7576102b76114cd565b6020908102919091018101919091526102d4906040908587611485565b6102dd916114af565b816001815181106102f0576102f06114cd565b6020908102919091010152610309606060408587611485565b610312916114af565b81600281518110610325576103256114cd565b6020026020010181815250506000801b81600381518110610348576103486114cd565b60200260200101818152505061035d81610c2a565b949350505050565b836103825760405162461bcd60e51b8152600401610261906114e3565b610120811480156103d457506103d482828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508892508791506102e29050610ec3565b6101895760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964206465706f73697420636f6e7461696e65722070726f6f66006044820152606401610261565b8461043d5760405162461bcd60e51b8152600401610261906114e3565b600764ffffffffff851666059600000000001760031b176106a0821480156104ac57506104ac83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a92506104a69150889050610edb565b84610ec3565b6101b15760405162461bcd60e51b815260206004820152601a60248201527f496e76616c696420776974686472617761626c652070726f6f660000000000006044820152606401610261565b856105155760405162461bcd60e51b8152600401610261906114e3565b64ffffffffff821666059600000000001760031b60006105386020828789611485565b610541916114af565b90508281146105925760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207769746864726177616c20637265640000000000000000006044820152606401610261565b6106a0851480156105e257506105e286868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b9150869050610ec3565b61062e5760405162461bcd60e51b815260206004820152601760248201527f496e76616c69642076616c696461746f722070726f6f660000000000000000006044820152606401610261565b5050505050505050565b846106745760405162461bcd60e51b815260206004820152600c60248201526b125b9d985b1a59081c9bdbdd60a21b6044820152606401610261565b6106806001601c611525565b61068b90600261161f565b8163ffffffff16106106d75760405162461bcd60e51b8152602060048201526015602482015274092dcecc2d8d2c840c8cae0dee6d2e840d2dcc8caf605b1b6044820152606401610261565b63ffffffff811663100000001761038083148015610734575061073484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a9250899150859050610ec3565b6101b15760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103232b837b9b4ba10383937b7b360591b6044820152606401610261565b836107955760405162461bcd60e51b8152600401610261906114e3565b610120811480156107e757506107e782828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508892508791506102cc9050610ec3565b6101895760405162461bcd60e51b815260206004820152601f60248201527f496e76616c69642062616c616e636520636f6e7461696e65722070726f6f66006044820152606401610261565b60408051600880825261012082019092526000918291906020820161010080368337019050509050888160008151811061086f5761086f6114cd565b60209081029190910181019190915261088b906000898b611485565b610894916114af565b816001815181106108a7576108a76114cd565b6020026020010181815250506108bc86610edb565b816002815181106108cf576108cf6114cd565b6020026020010181815250506108e5858561021f565b816003815181106108f8576108f86114cd565b60200260200101818152505061090d83610edb565b81600481518110610920576109206114cd565b6020026020010181815250506000801b81600581518110610943576109436114cd565b6020026020010181815250506000801b81600681518110610966576109666114cd565b6020026020010181815250506000801b81600781518110610989576109896114cd565b60200260200101818152505061099e81610c2a565b9998505050505050505050565b6000846109ca5760405162461bcd60e51b8152600401610261906114e3565b61049f198201610a6f57610a1b83838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508a93509150642e200000009050610ec3565b610a675760405162461bcd60e51b815260206004820152601c60248201527f496e76616c696420656d707479206465706f736974732070726f6f66000000006044820152606401610261565b50600161035d565b61050082148015610acd5750610acd83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250899250610ac19150889050610edb565b65017100000004610ec3565b61035d5760405162461bcd60e51b815260206004820152601a60248201527f496e76616c6964206465706f73697420736c6f742070726f6f660000000000006044820152606401610261565b600085610b615760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a590818dbdb9d185a5b995c881c9bdbdd60521b6044820152606401610261565b6000610b6e600484611641565b64ffffffffff1690506480000000008117610b898785610f51565b92506104e085148015610bdb5750610bdb86868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b9150859050610ec3565b610c1f5760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103130b630b731b290383937b7b360591b6044820152606401610261565b505095945050505050565b60008060028351610c3b919061166b565b90506000816001600160401b03811115610c5757610c5761146f565b604051908082528060200260200182016040528015610c80578160200160208202803683370190505b50905060005b82811015610d7d57600285610c9b838361167f565b81518110610cab57610cab6114cd565b602002602001015186836002610cc1919061167f565b610ccc906001611696565b81518110610cdc57610cdc6114cd565b6020026020010151604051602001610cfe929190918252602082015260400190565b60408051601f1981840301815290829052610d18916116a9565b602060405180830381855afa158015610d35573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610d5891906116d8565b828281518110610d6a57610d6a6114cd565b6020908102919091010152600101610c86565b50610d8960028361166b565b91505b8115610e9f5760005b82811015610e8c57600282610daa838361167f565b81518110610dba57610dba6114cd565b602002602001015183836002610dd0919061167f565b610ddb906001611696565b81518110610deb57610deb6114cd565b6020026020010151604051602001610e0d929190918252602082015260400190565b60408051601f1981840301815290829052610e27916116a9565b602060405180830381855afa158015610e44573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610e6791906116d8565b828281518110610e7957610e796114cd565b6020908102919091010152600101610d95565b50610e9860028361166b565b9150610d8c565b80600081518110610eb257610eb26114cd565b602002602001015192505050919050565b600083610ed1868585610fed565b1495945050505050565b603881811c60ff16602883811c61ff001691909117601884811c62ff00001691909117600885811c63ff000000169190911764ff000000009186901b919091161765ff00000000009185901b919091161766ff0000000000009184901b919091161760ff60381b9290911b919091161760c01b90565b600080610f5f6004846116f1565b610f6a90604061171b565b64ffffffffff169050610fdc84821b60f881901c60e882901c61ff00161760d882901c62ff0000161760c882901c63ff000000161764ff0000000060b883901c161765ff000000000060a883901c161766ff000000000000609883901c161760ff60381b60889290921c919091161790565b6001600160401b0316949350505050565b6000835160001415801561100c57506020845161100a9190611742565b155b611029576040516313717da960e21b815260040160405180910390fd5b604080516020808201909252848152905b855181116110c05761104d600285611742565b60000361107d578151600052808601516020526020826040600060026107d05a03fa61107857600080fd5b6110a1565b8086015160005281516020526020826040600060026107d05a03fa6110a157600080fd5b6110ac60028561166b565b93506110b9602082611696565b905061103a565b5051949350505050565b60008083601f8401126110dc57600080fd5b5081356001600160401b038111156110f357600080fd5b60208301915083602082850101111561110b57600080fd5b9250929050565b6000806020838503121561112557600080fd5b82356001600160401b0381111561113b57600080fd5b611147858286016110ca565b90969095509350505050565b6000806000806060858703121561116957600080fd5b843593506020850135925060408501356001600160401b0381111561118d57600080fd5b611199878288016110ca565b95989497509550505050565b803564ffffffffff811681146111ba57600080fd5b919050565b80356001600160401b03811681146111ba57600080fd5b6000806000806000608086880312156111ee57600080fd5b853594506111fe602087016111a5565b935061120c604087016111bf565b925060608601356001600160401b0381111561122757600080fd5b611233888289016110ca565b969995985093965092949392505050565b60008060008060008060a0878903121561125d57600080fd5b863595506020870135945060408701356001600160401b0381111561128157600080fd5b61128d89828a016110ca565b90955093506112a09050606088016111a5565b95989497509295919493608090920135925050565b6000806000806000608086880312156112cd57600080fd5b853594506020860135935060408601356001600160401b038111156112f157600080fd5b6112fd888289016110ca565b909450925050606086013563ffffffff8116811461131a57600080fd5b809150509295509295909350565b600080600080600080600060a0888a03121561134357600080fd5b8735965060208801356001600160401b0381111561136057600080fd5b61136c8a828b016110ca565b909750955061137f9050604089016111bf565b935060608801356001600160401b0381111561139a57600080fd5b6113a68a828b016110ca565b90945092506113b99050608089016111bf565b905092959891949750929550565b600080600080606085870312156113dd57600080fd5b843593506113ed602086016111bf565b925060408501356001600160401b0381111561118d57600080fd5b60008060008060006080868803121561142057600080fd5b853594506020860135935060408601356001600160401b0381111561144457600080fd5b611450888289016110ca565b90945092506114639050606087016111a5565b90509295509295909350565b634e487b7160e01b600052604160045260246000fd5b6000808585111561149557600080fd5b838611156114a257600080fd5b5050820193919092039150565b8035602083101561017757600019602084900360031b1b1692915050565b634e487b7160e01b600052603260045260246000fd5b602080825260129082015271125b9d985b1a5908189b1bd8dac81c9bdbdd60721b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b818103818111156101775761017761150f565b6001815b6001841115611573578085048111156115575761155761150f565b600184161561156557908102905b60019390931c92800261153c565b935093915050565b60008261158a57506001610177565b8161159757506000610177565b81600181146115ad57600281146115b7576115d3565b6001915050610177565b60ff8411156115c8576115c861150f565b50506001821b610177565b5060208310610133831016604e8410600b84101617156115f6575081810a610177565b6116036000198484611538565b80600019048211156116175761161761150f565b029392505050565b6000610174838361157b565b634e487b7160e01b600052601260045260246000fd5b600064ffffffffff8316806116585761165861162b565b8064ffffffffff84160491505092915050565b60008261167a5761167a61162b565b500490565b80820281158282048414176101775761017761150f565b808201808211156101775761017761150f565b6000825160005b818110156116ca57602081860181015185830152016116b0565b506000920191825250919050565b6000602082840312156116ea57600080fd5b5051919050565b600064ffffffffff8316806117085761170861162b565b8064ffffffffff84160691505092915050565b64ffffffffff818116838216029081169081811461173b5761173b61150f565b5092915050565b6000826117515761175161162b565b50069056fea26469706673582212205e6c180b3544abbcda0a898d1a795e4ddbd861b7b533fbede356a76fa464c51064736f6c634300081c0033
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.