Decentralized ETH liquid staking protocol with 4 ETH bond for anyone to be a node operator.
Platform: Code4rena
Start Date: 02/06/2023
End Date: 09/06/2023
Period: 7 days
Status: Completed
Pot Size: $100,000 USDC
Participants: 75
Reporter: thebrittfactor
Judge: Picodes
Id: 249
League: ETH
rvierdiiev | 1/75 | $12,289.77 | 4 | 0 | 0 | 3 | 2 | - | 0 | 0 |
dwward3n | 2/75 | $8,210.54 | 3 | 1 | 0 | 2 | 1 | 0 | 0 | 0 |
bin2chen | 3/75 | $6,286.75 | 7 | 1 | 0 | 5 | 0 | Grade B | 0 | 0 |
etherhood | 4/75 | $6,173.12 | 3 | 0 | 0 | 2 | 1 | 0 | Grade B | 0 |
JGcarv | 5/75 | $6,138.27 | 2 | 0 | 0 | 1 | 1 | - | 0 | 0 |
0xWaitress | 6/75 | $3,465.78 | 4 | 0 | 0 | 2 | 0 | Grade A | Grade B | 0 |
DadeKuma | 7/75 | $3,059.30 | 3 | 0 | 0 | 2 | 0 | Grade A | 0 | 0 |
Co0nan | 8/75 | $2,772.43 | 2 | 0 | 0 | 1 | 0 | - | 0 | 0 |
broccolirob | 9/75 | $2,676.76 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
sces60107 | 10/75 | $2,328.85 | 2 | 0 | 0 | 1 | 0 | - | 0 | 0 |
Auditor per page
Automated findings output for the audit can be found here.
Note for C4 wardens: Anything included in the automated findings output is considered a publicly known issue and is ineligible for awards.
Below are known issues of Slither; we encourage reporting any bugs around them and not just the errors:
ETHx is a multi pool architecture for node operations, designed for decentralization, scalability, and resilience. This design is integral to our ability to democratize node operations and adapt to increasing demand. Our structure includes a permissionless pool, where anyone can participate and operate nodes, thereby fostering widespread participation. Alongside this, we also feature a permissioned pool. This is a select group of validators known for their consistent high performance.
vaultProxy, vaultFactory, PoolSelector, staderOracle contracts
Contract | SLOC | Purpose | Libraries used |
---|---|---|---|
contracts/Auction.sol | 116 | create auction lot for SD token, manage bid and transfer highest bid ETH to StaderStakePoolManager contract | @openzeppelin/* |
contracts/ETHx.sol | 50 | The ERC20 contract for the ETHx token | @openzeppelin/* |
contracts/NodeELRewardVault.sol | 32 | Distribution logic for Execution layer reward for operators opted out of socializing pool | |
contracts/OperatorRewardsCollector.sol | 39 | stores operator rewards/settled amount for operator to claim | @openzeppelin/* |
contracts/Penalty.sol | 106 | store validator level penalty data, update penalty based on MEV Theft/missed attestation data | @openzeppelin/* |
contracts/PermissionedNodeRegistry.sol | 524 | Handles Permissioned Operator onboarding, adding validator keys, validator selection within operators to depsoit on beacon chain and maintains validator and operator registry | @openzeppelin/* |
contracts/PermissionedPool.sol | 252 | Interact with Ethereum Deposit Contract to do PRE_DEPOSIT and Full Deposit | @openzeppelin/* |
contracts/PermissionlessNodeRegistry.sol | 502 | Handle Permissionless Operators onboarding, adding validator keys with a collateral of 4ETH per validator and maintains validator and operator registry | @openzeppelin/* |
contracts/PermissionlessPool.sol | 216 | Interact with Ethereum deposit contract to do PRE_DEPOSIT and Full Deposit | @openzeppelin/* |
contracts/PoolSelector.sol | 108 | stores pool target weight, computes validator number to register on beacon chain based on pooled ETH and pool target and handle excess ETH allocation to pools if pool does not have capacity in a round robin way | @openzeppelin/* |
contracts/PoolUtils.sol | 232 | provides data across all pools like total queued validator count, total active validator count along with performing checks like unique pubkey, uinque operator address across all pools | @openzeppelin/* |
contracts/SDCollateral.sol | 172 | handles SD token deposit for collateral, check for SD collateral based on pool, withdraw of excess SD token | @openzeppelin/* |
contracts/SocializingPool.sol | 180 | Handle Execution Layer reward distribution for permissioned pool and permissionless operator which opted-in for socializing pool, reward data is pushed in form of merkle tree by staderOracle | @openzeppelin/* |
contracts/StaderConfig.sol | 374 | store the address of all other contracts and allow to update them via admin | @openzeppelin/* |
contracts/StaderInsuranceFund.sol | 52 | Reimburse 1ETH ETH lost in case a permissioned NO submit invalid signature key | @openzeppelin/* |
contracts/StaderOracle.sol | 589 | Submit Exchange Rate, SD Price, Withdrawn validator, Missed attestation penalty, socializing pool reward merkles along with Validator status data via trusted node | @openzeppelin/* @chainlink/* |
contracts/StaderStakePoolsManager.sol | 213 | handle user staking ETH, minting ETHx, receiving user share of rewards from validators across all pools and validatorBatch Deposit based on the pooled ETH amount | @openzeppelin/* |
contracts/UserWithdrawalManager.sol | 176 | handle user unstake and claiming for requests along with buring ETHx for withdraw request | @openzeppelin/* |
contracts/ValidatorWithdrawalVault.sol | 125 | handle consensus layer reward distribution and settlement in case validator is withdrawn | @openzeppelin/* |
contracts/VaultProxy.sol | 56 | router contract for all ValidatorWithdrawalVault and NodeELRewardVault contracts, delegate calls to specific vault via fallback | |
contracts/factory/VaultFactory.sol | 77 | Deploys vaultProxy implementation via clones | @openzeppelin/* |
contracts/library/UtilLib.sol | 143 | Perform check on msg.sender, check for roles and get operator data given validatorID | |
contracts/library/ValidatorStatus.sol | 9 | List of stader defined validator status |
- If you have a public code repo, please share it here: - How many contracts are in scope?: 23 - Total SLoC for these contracts?: 4348 - How many external imports are there?: 0 - How many separate interfaces and struct definitions are there for the contracts within scope?: 23 interfaces, 13 structs - Does most of your code generally use composition or inheritance?: Composition - How many external calls?: 0 - What is the overall line coverage percentage provided by your tests?: 85 - Is this an upgrade of an existing system? No - Is there a need to understand a separate part of the codebase / get context in order to audit this part of the protocol?: Yes - Please describe required context: https://miro.com/app/board/uXjVMDv5XKo=/ - Does it use an oracle?: Yes - Custom oracle that is reflected in StaderOracle.sol - Does the token conform to the ERC20 standard?: - Are there any novel or unique curve logic or mathematical models?: Yes - Any validator in permissionless pool can run a node with 4 ETH + 0.4 ETH worth of SD token. Rewards are split proportionately. - Does it use a timelock function?: No - Is it an NFT?: No - Does it have an AMM?: No - Is it a fork of a popular project?: No - Does it use rollups?: No - Is it multi-chain?: No - Does it use a side-chain?: No
Installing foundry:
curl -L https://foundry.paradigm.xyz | bash
brew install libusb
foundryup
Using the test suite:
# to install hardhat-foundry plugin npm install # to install submodule dependencies forge install # to build all contracts forge build forge test forge test --gas-report forge coverage
Note: a slither.config.json
file is present and exclude findings and files that do not align with our areas of interest