Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Loading...
Loading
Minimal Proxy Contract for 0x933fbfeb4ed1f111d12a39c2ab48657e6fc875c6
Contract Name:
FeeRecipient
Compiler Version
v0.8.13+commit.abaa5c0e
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.8.10; import "./interfaces/IFeeDispatcher.sol"; contract FeeRecipient { /// @notice Constructor replay prevention bool internal initialized; /// @notice Address where funds are sent to be dispatched IFeeDispatcher internal dispatcher; /// @notice Public Key root assigned to this receiver bytes32 internal publicKeyRoot; error AlreadyInitialized(); /// @notice Initializes the receiver /// @param _dispatcher Address that will handle the fee dispatching /// @param _publicKeyRoot Public Key root assigned to this receiver function init(address _dispatcher, bytes32 _publicKeyRoot) external { if (initialized) { revert AlreadyInitialized(); } initialized = true; dispatcher = IFeeDispatcher(_dispatcher); publicKeyRoot = _publicKeyRoot; } /// @notice Empty calldata fallback receive() external payable {} /// @notice Non-empty calldata fallback fallback() external payable {} /// @notice Triggers a withdrawal by sending its funds + its public key root to the dispatcher /// @dev Can be called by any wallet as recipients are not parameters function withdraw() external { dispatcher.dispatch{value: address(this).balance}(publicKeyRoot); } /// @notice Retrieve the assigned public key root function getPublicKeyRoot() external view returns (bytes32) { return publicKeyRoot; } /// @notice retrieve the assigned withdrawer function getWithdrawer() external view returns (address) { return dispatcher.getWithdrawer(publicKeyRoot); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.8.10; import "./libs/DispatchersStorageLib.sol"; import "./interfaces/IStakingContractFeeDetails.sol"; import "./interfaces/IFeeDispatcher.sol"; /// @title Consensus Layer Fee Recipient /// @author Kiln /// @notice This contract can be used to receive fees from a validator and split them with a node operator contract ConsensusLayerFeeDispatcher is IFeeDispatcher { using DispatchersStorageLib for bytes32; event Withdrawal( address indexed withdrawer, address indexed feeRecipient, bytes32 pubKeyRoot, uint256 rewards, uint256 nodeOperatorFee, uint256 treasuryFee ); error TreasuryReceiveError(bytes errorData); error FeeRecipientReceiveError(bytes errorData); error WithdrawerReceiveError(bytes errorData); error ZeroBalanceWithdrawal(); error AlreadyInitialized(); error InvalidCall(); error NotImplemented(); bytes32 internal constant STAKING_CONTRACT_ADDRESS_SLOT = keccak256("ConsensusLayerFeeRecipient.stakingContractAddress"); uint256 internal constant BASIS_POINTS = 10_000; bytes32 internal constant VERSION_SLOT = keccak256("ConsensusLayerFeeRecipient.version"); /// @notice Ensures an initialisation call has been called only once per _version value /// @param _version The current initialisation value modifier init(uint256 _version) { if (_version != VERSION_SLOT.getUint256() + 1) { revert AlreadyInitialized(); } VERSION_SLOT.setUint256(_version); _; } /// @notice Constructor method allowing us to prevent calls to initCLFR by setting the appropriate version constructor(uint256 _version) { VERSION_SLOT.setUint256(_version); } /// @notice Initialize the contract by storing the staking contract /// @param _stakingContract Address of the Staking Contract function initCLD(address _stakingContract) external init(1) { STAKING_CONTRACT_ADDRESS_SLOT.setAddress(_stakingContract); } /// @notice Performs a withdrawal on this contract's balance function dispatch(bytes32) external payable { revert NotImplemented(); /* uint256 balance = address(this).balance; // this has taken into account msg.value if (balance == 0) { revert ZeroBalanceWithdrawal(); } IStakingContractFeeDetails stakingContract = IStakingContractFeeDetails( STAKING_CONTRACT_ADDRESS_SLOT.getAddress() ); address withdrawer = stakingContract.getWithdrawerFromPublicKeyRoot(_publicKeyRoot); address operator = stakingContract.getOperatorFeeRecipient(_publicKeyRoot); address treasury = stakingContract.getTreasury(); uint256 globalFee; if (balance >= 32 ether) { // withdrawing a healthy & exited validator globalFee = ((balance - 32 ether) * stakingContract.getGlobalFee()) / BASIS_POINTS; } else if (balance <= 16 ether) { // withdrawing from what looks like skimming globalFee = (balance * stakingContract.getGlobalFee()) / BASIS_POINTS; } uint256 operatorFee = (globalFee * stakingContract.getOperatorFee()) / BASIS_POINTS; (bool status, bytes memory data) = withdrawer.call{value: balance - globalFee}(""); if (status == false) { revert WithdrawerReceiveError(data); } if (globalFee > 0) { (status, data) = treasury.call{value: globalFee - operatorFee}(""); if (status == false) { revert FeeRecipientReceiveError(data); } } if (operatorFee > 0) { (status, data) = operator.call{value: operatorFee}(""); if (status == false) { revert TreasuryReceiveError(data); } } emit Withdrawal(withdrawer, operator, balance - globalFee, operatorFee, globalFee - operatorFee); */ } /// @notice Retrieve the staking contract address function getStakingContract() external view returns (address) { return STAKING_CONTRACT_ADDRESS_SLOT.getAddress(); } /// @notice Retrieve the assigned withdrawer for the given public key root /// @param _publicKeyRoot Public key root to get the owner function getWithdrawer(bytes32 _publicKeyRoot) external view returns (address) { IStakingContractFeeDetails stakingContract = IStakingContractFeeDetails( STAKING_CONTRACT_ADDRESS_SLOT.getAddress() ); return stakingContract.getWithdrawerFromPublicKeyRoot(_publicKeyRoot); } receive() external payable { revert InvalidCall(); } fallback() external payable { revert InvalidCall(); } }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.10; library DispatchersStorageLib { function getUint256(bytes32 position) internal view returns (uint256 data) { assembly { data := sload(position) } } function setUint256(bytes32 position, uint256 data) internal { assembly { sstore(position, data) } } function getAddress(bytes32 position) internal view returns (address data) { assembly { data := sload(position) } } function setAddress(bytes32 position, address data) internal { assembly { sstore(position, data) } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.10; interface IStakingContractFeeDetails { function getWithdrawerFromPublicKeyRoot(bytes32 _publicKeyRoot) external view returns (address); function getTreasury() external view returns (address); function getOperatorFeeRecipient(bytes32 pubKeyRoot) external view returns (address); function getGlobalFee() external view returns (uint256); function getOperatorFee() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.10; interface IFeeDispatcher { function dispatch(bytes32 _publicKeyRoot) external payable; function getWithdrawer(bytes32 _publicKeyRoot) external view returns (address); }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.8.10; import "./libs/DispatchersStorageLib.sol"; import "./interfaces/IStakingContractFeeDetails.sol"; import "./interfaces/IFeeDispatcher.sol"; /// @title Execution Layer Fee Recipient /// @author Kiln /// @notice This contract can be used to receive fees from a validator and split them with a node operator contract ExecutionLayerFeeDispatcher is IFeeDispatcher { using DispatchersStorageLib for bytes32; event Withdrawal( address indexed withdrawer, address indexed feeRecipient, bytes32 pubKeyRoot, uint256 rewards, uint256 nodeOperatorFee, uint256 treasuryFee ); error TreasuryReceiveError(bytes errorData); error FeeRecipientReceiveError(bytes errorData); error WithdrawerReceiveError(bytes errorData); error ZeroBalanceWithdrawal(); error AlreadyInitialized(); error InvalidCall(); bytes32 internal constant STAKING_CONTRACT_ADDRESS_SLOT = keccak256("ExecutionLayerFeeRecipient.stakingContractAddress"); uint256 internal constant BASIS_POINTS = 10_000; bytes32 internal constant VERSION_SLOT = keccak256("ExecutionLayerFeeRecipient.version"); /// @notice Ensures an initialisation call has been called only once per _version value /// @param _version The current initialisation value modifier init(uint256 _version) { if (_version != VERSION_SLOT.getUint256() + 1) { revert AlreadyInitialized(); } VERSION_SLOT.setUint256(_version); _; } /// @notice Constructor method allowing us to prevent calls to initCLFR by setting the appropriate version constructor(uint256 _version) { VERSION_SLOT.setUint256(_version); } /// @notice Initialize the contract by storing the staking contract and the public key in storage /// @param _stakingContract Address of the Staking Contract function initELD(address _stakingContract) external init(1) { STAKING_CONTRACT_ADDRESS_SLOT.setAddress(_stakingContract); } /// @notice Performs a withdrawal on this contract's balance function dispatch(bytes32 _publicKeyRoot) external payable { uint256 balance = address(this).balance; if (balance == 0) { revert ZeroBalanceWithdrawal(); } IStakingContractFeeDetails stakingContract = IStakingContractFeeDetails( STAKING_CONTRACT_ADDRESS_SLOT.getAddress() ); address withdrawer = stakingContract.getWithdrawerFromPublicKeyRoot(_publicKeyRoot); address operator = stakingContract.getOperatorFeeRecipient(_publicKeyRoot); address treasury = stakingContract.getTreasury(); uint256 globalFee = (balance * stakingContract.getGlobalFee()) / BASIS_POINTS; uint256 operatorFee = (globalFee * stakingContract.getOperatorFee()) / BASIS_POINTS; (bool status, bytes memory data) = withdrawer.call{value: balance - globalFee}(""); if (status == false) { revert WithdrawerReceiveError(data); } if (globalFee > 0) { (status, data) = treasury.call{value: globalFee - operatorFee}(""); if (status == false) { revert FeeRecipientReceiveError(data); } } if (operatorFee > 0) { (status, data) = operator.call{value: operatorFee}(""); if (status == false) { revert TreasuryReceiveError(data); } } emit Withdrawal( withdrawer, operator, _publicKeyRoot, balance - globalFee, operatorFee, globalFee - operatorFee ); } /// @notice Retrieve the staking contract address function getStakingContract() external view returns (address) { return STAKING_CONTRACT_ADDRESS_SLOT.getAddress(); } /// @notice Retrieve the assigned withdrawer for the given public key root /// @param _publicKeyRoot Public key root to get the owner function getWithdrawer(bytes32 _publicKeyRoot) external view returns (address) { IStakingContractFeeDetails stakingContract = IStakingContractFeeDetails( STAKING_CONTRACT_ADDRESS_SLOT.getAddress() ); return stakingContract.getWithdrawerFromPublicKeyRoot(_publicKeyRoot); } receive() external payable { revert InvalidCall(); } fallback() external payable { revert InvalidCall(); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "metadata": { "useLiteralContent": true } }
[{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"getPublicKeyRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWithdrawer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_dispatcher","type":"address"},{"internalType":"bytes32","name":"_publicKeyRoot","type":"bytes32"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Loading...
Loading
Loading...
Loading
Latest 25 from a total of 30 withdrawals (32.647875681 ETH withdrawn)
Validator Index | Block | Amount | |
---|---|---|---|
1012631 | 20282735 | 167 days ago | 32 ETH |
1012631 | 20218346 | 176 days ago | 0.016841869 ETH |
1012631 | 20154204 | 185 days ago | 0.018748688 ETH |
1012631 | 20090529 | 194 days ago | 0.018664024 ETH |
1012631 | 20027474 | 203 days ago | 0.018587836 ETH |
1012631 | 19964854 | 212 days ago | 0.063156822 ETH |
1012631 | 19902006 | 220 days ago | 0.018446794 ETH |
1012631 | 19839349 | 229 days ago | 0.063084664 ETH |
1012631 | 19777204 | 238 days ago | 0.062671369 ETH |
1012631 | 19715689 | 246 days ago | 0.018237815 ETH |
1012631 | 19654603 | 255 days ago | 0.018144532 ETH |
1012631 | 19593719 | 263 days ago | 0.018279506 ETH |
1012631 | 19532685 | 272 days ago | 0.018036162 ETH |
1012631 | 19471977 | 281 days ago | 0.018207176 ETH |
1012631 | 19411056 | 289 days ago | 0.018300977 ETH |
1012631 | 19350472 | 298 days ago | 0.018102518 ETH |
1012631 | 19290815 | 306 days ago | 0.017873053 ETH |
1012631 | 19232377 | 314 days ago | 0.017662077 ETH |
1012631 | 19175048 | 322 days ago | 0.017485345 ETH |
1012631 | 19118742 | 330 days ago | 0.017460676 ETH |
1012631 | 19063072 | 338 days ago | 0.017322235 ETH |
1012631 | 19007858 | 346 days ago | 0.017532621 ETH |
1012631 | 18952115 | 353 days ago | 0.017385903 ETH |
1012631 | 18896893 | 361 days ago | 0.017390276 ETH |
1012631 | 18841901 | 369 days ago | 0.017319646 ETH |
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
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.