Skip to main content

FeeDistributor

FeeDistributor is a supplementary contract that holds the module's stETH reward shares while they are unallocated or claimable by Node Operators. FeeOracle reports the latest rewards-distribution Merkle root and CID, distribution log, newly claimable shares, and any rebate. The contract stores a history of these reports and transfers the reported rebate to the configured recipient.

Using a valid Merkle proof of a Node Operator's cumulative reward entitlement, Accounting pulls only the undistributed difference into that operator's bond. FeeDistributor records the cumulative shares already distributed to prevent duplicate claims.

State Variables​

INITIALIZED_VERSION​

uint64 internal constant INITIALIZED_VERSION = 3

STETH​

IStETH public immutable STETH

ACCOUNTING​

address public immutable ACCOUNTING

ORACLE​

address public immutable ORACLE

treeRoot​

The latest Merkle Tree root

bytes32 public treeRoot

treeCid​

CID of the last published Merkle tree

string public treeCid

logCid​

CID of the file with log for the last frame reported

string public logCid

distributedShares​

Amount of stETH shares sent to the Accounting in favor of the NO

mapping(uint256 nodeOperatorId => uint256 distributed) public distributedShares

totalClaimableShares​

Total Amount of stETH shares available for claiming by NOs

uint256 public totalClaimableShares

_distributionDataHistory​

Array of the distribution data history

mapping(uint256 index => DistributionData) internal _distributionDataHistory

distributionDataHistoryCount​

The number of records retrievable via getHistoricalDistributionData

uint256 public distributionDataHistoryCount

rebateRecipient​

The address to transfer rebate to

address public rebateRecipient

Functions​

onlyAccounting​

modifier onlyAccounting() ;

onlyOracle​

modifier onlyOracle() ;

constructor​

constructor(address stETH, address accounting, address oracle) ;

initialize​

Initialize contract from scratch. In case of a method call frontrun, the contract instance should be discarded. It is recommended to call this method in the same transaction as the deployment transaction and perform extensive deployment verification before using the contract instance.

function initialize(address admin, address _rebateRecipient) external reinitializer(INITIALIZED_VERSION);

finalizeUpgradeV3​

This method is expected to be called only when the contract is upgraded from version 2 to version 3 for the existing version 2 deployment. If the version 3 contract is deployed from scratch, the initialize method should be used instead. To prevent possible frontrun this method should strictly be called in the same TX as the upgrade transaction and should not be called separately.

function finalizeUpgradeV3() external reinitializer(INITIALIZED_VERSION);

setRebateRecipient​

Set address to send rebate to

function setRebateRecipient(address _rebateRecipient) external onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
_rebateRecipientaddressAddress to send rebate to

distributeFees​

Distribute fees to the Accounting in favor of the Node Operator

function distributeFees(uint256 nodeOperatorId, uint256 cumulativeFeeShares, bytes32[] calldata proof)
external
onlyAccounting
returns (uint256 sharesToDistribute);

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator
cumulativeFeeSharesuint256Total Amount of stETH shares earned as fees
proofbytes32[]Merkle proof of the leaf

Returns

NameTypeDescription
sharesToDistributeuint256Amount of stETH shares distributed

processOracleReport​

Receive the data of the Merkle tree from the Oracle contract and process it

function processOracleReport(
bytes32 _treeRoot,
string calldata _treeCid,
string calldata _logCid,
uint256 distributed,
uint256 rebate,
uint256 refSlot
) external onlyOracle;

Parameters

NameTypeDescription
_treeRootbytes32Root of the Merkle tree
_treeCidstringIPFS CID of the tree
_logCidstringIPFS CID of the log
distributeduint256Amount of the distributed shares
rebateuint256Amount of the rebate shares
refSlotuint256Reference slot of the report

recoverERC20​

Allows sender to recover ERC20 tokens held by the contract

function recoverERC20(address token, uint256 amount) external override;

Parameters

NameTypeDescription
tokenaddressThe address of the ERC20 token to recover
amountuint256The amount of the ERC20 token to recover

getInitializedVersion​

Get the initialized version of the contract

function getInitializedVersion() external view returns (uint64);

pendingSharesToDistribute​

Get the Amount of stETH shares that are pending to be distributed

function pendingSharesToDistribute() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256Amount shares that are pending to distribute

getHistoricalDistributionData​

Get the historical record of distribution data

function getHistoricalDistributionData(uint256 index) external view returns (DistributionData memory);

Parameters

NameTypeDescription
indexuint256Historical entry index

Returns

NameTypeDescription
<none>DistributionDataHistorical distribution data

getFeesToDistribute​

Get the Amount of stETH shares that can be distributed in favor of the Node Operator

function getFeesToDistribute(uint256 nodeOperatorId, uint256 cumulativeFeeShares, bytes32[] calldata proof)
public
view
returns (uint256 sharesToDistribute);

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator
cumulativeFeeSharesuint256Total Amount of stETH shares earned as fees
proofbytes32[]Merkle proof of the leaf

Returns

NameTypeDescription
sharesToDistributeuint256Amount of stETH shares that can be distributed

hashLeaf​

Get a hash of a leaf

Double hash the leaf to prevent second preimage attacks

function hashLeaf(uint256 nodeOperatorId, uint256 shares) public pure returns (bytes32);

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator
sharesuint256Amount of stETH shares

Returns

NameTypeDescription
<none>bytes32Hash of the leaf

_setRebateRecipient​

function _setRebateRecipient(address _rebateRecipient) internal;

_onlyAccounting​

function _onlyAccounting() internal view;

_onlyOracle​

function _onlyOracle() internal view;

_onlyRecoverer​

function _onlyRecoverer() internal view override;