PirexEthValidators.sol
General Overview
The PirexEthValidators.sol
contract is a central component in managing Ethereum validators for the Beacon Chain deposit contract. It facilitates a wide range of functions including setting contract addresses, managing validator queues, initiating deposits, and handling rewards and slashing operations. The contract also allows for validator management through various queues with capabilities to add, swap, remove, or clear validators.
Additionally, it addresses the redemption and rewarding of validators with upxEth tokens. The roles defined within the contract, such as GOVERNANCE_ROLE
, KEEPER_ROLE
, and DEFAULT_ADMIN_ROLE
, are important for these activities, ensuring a seamless and secure operation of validators within the protocol.
GOVERNANCE_ROLE
- manages the validator queue, sets fee parameters, and controls the pausing of deposits to the Beacon Chain deposit contract.KEEPER_ROLE
- responsible for harvesting rewards, updating the status of validators when they are slashed, and topping up the validator's stake if the active balance falls below the effective balance.DEFAULT_ADMIN_ROLE
- sets external contract addresses.
Technical Overview
Inherits: ReentrancyGuard, AccessControlDefaultAdminRules, IPirexEth
Author: redactedcartel.finance
State Variables
DENOMINATOR
uint256 public constant DENOMINATOR = 1_000_000;
KEEPER_ROLE
bytes32 public constant KEEPER_ROLE = keccak256("KEEPER_ROLE");
GOVERNANCE_ROLE
bytes32 public constant GOVERNANCE_ROLE = keccak256("GOVERNANCE_ROLE");
_NOT_PAUSED
uint256 internal constant _NOT_PAUSED = 1;
_PAUSED
uint256 internal constant _PAUSED = 2;
beaconChainDepositContract
address public immutable beaconChainDepositContract;
preDepositAmount
uint256 public immutable preDepositAmount;
DEPOSIT_SIZE
uint256 public immutable DEPOSIT_SIZE;
withdrawalCredentials
bytes public withdrawalCredentials;
buffer
uint256 public buffer;
maxBufferSize
uint256 public maxBufferSize;
maxBufferSizePct
uint256 public maxBufferSizePct;
maxProcessedValidatorCount
uint256 public maxProcessedValidatorCount = 20;
upxEth
ERC1155Solmate public upxEth;
pxEth
PxEth public pxEth;
autoPxEth
AutoPxEth public autoPxEth;
oracleAdapter
IOracleAdapter public oracleAdapter;
rewardRecipient
address public rewardRecipient;
depositEtherPaused
uint256 public depositEtherPaused;
pendingDeposit
uint256 public pendingDeposit;
_initializedValidators
DataTypes.ValidatorDeque internal _initializedValidators;
_stakingValidators
DataTypes.ValidatorDeque internal _stakingValidators;
pendingWithdrawal
uint256 public pendingWithdrawal;
outstandingRedemptions
uint256 public outstandingRedemptions;
batchId
uint256 public batchId;
endBlock
uint256 public endBlock;
status
mapping(bytes => DataTypes.ValidatorStatus) public status;
batchIdToValidator
mapping(uint256 => bytes) public batchIdToValidator;
burnerAccounts
mapping(address => bool) public burnerAccounts;
Functions
onlyRewardRecipient
modifier onlyRewardRecipient();
onlyWhenDepositEtherPaused
modifier onlyWhenDepositEtherPaused();
constructor
constructor(
address _pxEth,
address _admin,
address _beaconChainDepositContract,
address _upxEth,
uint256 _depositSize,
uint256 _preDepositAmount,
uint48 _initialDelay
) AccessControlDefaultAdminRules(_initialDelay, _admin);
Parameters
Name | Type | Description |
---|---|---|
_pxEth | address | PxETH contract address |
_admin | address | Admin address |
_beaconChainDepositContract | address | The address of the deposit precompile |
_upxEth | address | UpxETH address |
_depositSize | uint256 | Amount of ETH to stake |
_preDepositAmount | uint256 | Amount of ETH for pre-deposit |
_initialDelay | uint48 | Delay required to schedule the acceptance of a access control transfer started |
getInitializedValidatorCount
Get the number of initialized validators
function getInitializedValidatorCount() external view returns (uint256);
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | Number of initialised validators |
getStakingValidatorCount
Get the number of staking validators
function getStakingValidatorCount() public view returns (uint256);
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | Number of staking validators |
getInitializedValidatorAt
Get the initialized validator info at the specified index
function getInitializedValidatorAt(uint256 _i)
external
view
returns (bytes memory, bytes memory, bytes memory, bytes32, address);
Parameters
Name | Type | Description |
---|---|---|
_i | uint256 | Index |
Returns
Name | Type | Description |
---|---|---|
<none> | bytes | Public key |
<none> | bytes | Withdrawal credentials |
<none> | bytes | Signature |
<none> | bytes32 | Deposit data root hash |
<none> | address | pxETH receiver |
getStakingValidatorAt
Get the staking validator info at the specified index
function getStakingValidatorAt(uint256 _i)
external
view
returns (bytes memory, bytes memory, bytes memory, bytes32, address);
Parameters
Name | Type | Description |
---|---|---|
_i | uint256 | Index |
Returns
Name | Type | Description |
---|---|---|
<none> | bytes | Public key |
<none> | bytes | Withdrawal credentials |
<none> | bytes | Signature |
<none> | bytes32 | Deposit data root hash |
<none> | address | pxETH receiver |
setContract
Set a contract address
function setContract(DataTypes.Contract c, address contractAddress) external onlyRole(GOVERNANCE_ROLE);
Parameters
Name | Type | Description |
---|---|---|
c | DataTypes.Contract | Contract |
contractAddress | address | Contract address |
setMaxBufferSizePct
Set the percentage that will be applied to total supply of pxEth to determine maxBufferSize
function setMaxBufferSizePct(uint256 _pct) external onlyRole(GOVERNANCE_ROLE);
Parameters
Name | Type | Description |
---|---|---|
_pct | uint256 | Max buffer size percentage |
setMaxProcessedValidatorCount
Set maximum count of processed validator in a _deposit call
function setMaxProcessedValidatorCount(uint256 _count) external onlyRole(GOVERNANCE_ROLE);
Parameters
Name | Type | Description |
---|---|---|
_count | uint256 | Max processed count |
togglePauseDepositEther
Toggle allowing depositing ETH to validators
function togglePauseDepositEther() external onlyRole(GOVERNANCE_ROLE);
toggleBurnerAccounts
Approve/revoke addresses as burner accounts
function toggleBurnerAccounts(address[] calldata _accounts, bool _state) external onlyRole(GOVERNANCE_ROLE);
Parameters
Name | Type | Description |
---|---|---|
_accounts | address[] | Addresses |
_state | bool | Burner acount state |
dissolveValidator
Update validator to Dissolve once Oracle updates on ETH being released
function dissolveValidator(bytes calldata _pubKey) external payable override onlyRewardRecipient;
Parameters
Name | Type | Description |
---|---|---|
_pubKey | bytes | Public key of the validator |
slashValidator
Update validator state to be slashed
function slashValidator(
bytes calldata _pubKey,
uint256 _removeIndex,
uint256 _amount,
bool _unordered,
bool _useBuffer,
DataTypes.BurnerAccount[] calldata _burnerAccounts
) external payable override onlyRewardRecipient;
Parameters
Name | Type | Description |
---|---|---|
_pubKey | bytes | Public key of the validator |
_removeIndex | uint256 | Index of validator to be slashed |
_amount | uint256 | ETH amount released from Beacon chain |
_unordered | bool | Whether remove from staking validator queue in order or not |
_useBuffer | bool | whether to use buffer to compensate the loss |
_burnerAccounts | DataTypes.BurnerAccount[] | Burner accounts |
addInitializedValidators
Add multiple synced validators in the queue to be ready for staking
function addInitializedValidators(DataTypes.Validator[] memory _validators)
external
onlyWhenDepositEtherPaused
onlyRole(GOVERNANCE_ROLE);
Parameters
Name | Type | Description |
---|---|---|
_validators | DataTypes.Validator[] | Validators details |
swapInitializedValidator
Swap initialized validators specified by the indexes
function swapInitializedValidator(uint256 _fromIndex, uint256 _toIndex)
external
onlyWhenDepositEtherPaused
onlyRole(GOVERNANCE_ROLE);
Parameters
Name | Type | Description |
---|---|---|
_fromIndex | uint256 | From index |
_toIndex | uint256 | To index |
popInitializedValidator
Pop initialized validators
function popInitializedValidator(uint256 _times) external onlyWhenDepositEtherPaused onlyRole(GOVERNANCE_ROLE);
Parameters
Name | Type | Description |
---|---|---|
_times | uint256 | Count of pop operations |
removeInitializedValidator
Remove initialized validators
function removeInitializedValidator(bytes calldata _pubKey, uint256 _removeIndex, bool _unordered)
external
onlyWhenDepositEtherPaused
onlyRole(GOVERNANCE_ROLE);
Parameters
Name | Type | Description |
---|---|---|
_pubKey | bytes | |
_removeIndex | uint256 | Remove index |
_unordered | bool | Whether unordered or ordered |
clearInitializedValidator
Clear initialized validators
function clearInitializedValidator() external onlyWhenDepositEtherPaused onlyRole(GOVERNANCE_ROLE);
depositPrivileged
Trigger deposit to the ETH 2.0 deposit contract when allowed
function depositPrivileged() external nonReentrant onlyRole(KEEPER_ROLE);
topUpStake
Topup ETH to the validator if current balance drops below effective balance
function topUpStake(
bytes calldata _pubKey,
bytes calldata _signature,
bytes32 _depositDataRoot,
uint256 _topUpAmount,
bool _useBuffer,
DataTypes.BurnerAccount[] calldata _burnerAccounts
) external payable nonReentrant onlyRole(KEEPER_ROLE);
Parameters
Name | Type | Description |
---|---|---|
_pubKey | bytes | Validator public key |
_signature | bytes | A BLS12-381 signature |
_depositDataRoot | bytes32 | The SHA-256 hash of the SSZ-encoded DepositData object. |
_topUpAmount | uint256 | Top-up amount |
_useBuffer | bool | Whether to use buffer |
_burnerAccounts | DataTypes.BurnerAccount[] | Burner accounts |
harvest
Harvest and mint staking rewards when available
function harvest(uint256 _endBlock) external payable override onlyRewardRecipient;
Parameters
Name | Type | Description |
---|---|---|
_endBlock | uint256 | Block until which ETH rewards is computed |
_mintPxEth
Internal method for minting pxETH
function _mintPxEth(address _account, uint256 _amount) internal;
Parameters
Name | Type | Description |
---|---|---|
_account | address | Account |
_amount | uint256 | Amount |
_burnPxEth
Internal method for burning pxETH
function _burnPxEth(address _account, uint256 _amount) internal;
Parameters
Name | Type | Description |
---|---|---|
_account | address | Account |
_amount | uint256 | Amount |
_deposit
Spin up validator if sufficient ETH is available
function _deposit() internal;
_addPendingDeposit
Add pending deposit and spin up validator if required ETH available
function _addPendingDeposit(uint256 _amount) internal virtual;
Parameters
Name | Type | Description |
---|---|---|
_amount | uint256 | ETH asset amount |
_initiateRedemption
Internal handler for validator related logic on redemption
function _initiateRedemption(uint256 _pxEthAmount, address _receiver, bool _shouldTriggerValidatorExit) internal;
Parameters
Name | Type | Description |
---|---|---|
_pxEthAmount | uint256 | Amount of pxETH |
_receiver | address | Receiver for upxETH |
_shouldTriggerValidatorExit | bool | Whether initiate partial redemption with validator exit or not |
_updateBuffer
function _updateBuffer(uint256 _amount, DataTypes.BurnerAccount[] calldata _burnerAccounts) private;
Events
ValidatorDeposit
event ValidatorDeposit(bytes pubKey);
SetContract
event SetContract(DataTypes.Contract indexed c, address contractAddress);
DepositEtherPaused
event DepositEtherPaused(uint256 newStatus);
Harvest
event Harvest(uint256 amount, uint256 endBlock);
SetMaxBufferSizePct
event SetMaxBufferSizePct(uint256 pct);
ApproveBurnerAccount
event ApproveBurnerAccount(address indexed account);
RevokeBurnerAccount
event RevokeBurnerAccount(address indexed account);
DissolveValidator
event DissolveValidator(bytes pubKey);
SlashValidator
event SlashValidator(bytes pubKey, bool useBuffer, uint256 releasedAmount, uint256 penalty);
TopUp
event TopUp(bytes pubKey, bool useBuffer, uint256 topUpAmount);
SetMaxProcessedValidatorCount
event SetMaxProcessedValidatorCount(uint256 count);
UpdateMaxBufferSize
event UpdateMaxBufferSize(uint256 maxBufferSize);
SetWithdrawCredentials
event SetWithdrawCredentials(bytes withdrawalCredentials);