26Q2 - Security Upgrades#385
Conversation
…drawRequestNFT contracts
…thdraw functions; enforce invalidation rules for finalized requests
…nd permissionless claims while paused
…s-execute-task yash/feat/permissionless-execute-task
yash/fix/syko-review
| if (updatedAt + STALE_PRICE_WINDOW >= block.timestamp) { | ||
| uint256 pricefeedValue = (uint256(answer) * _amount) / 1e18; | ||
| uint256 deviation = pricefeedValue > _marketValue ? pricefeedValue - _marketValue : _marketValue - pricefeedValue; | ||
| if (deviation * BASIS_POINT_SCALE / _marketValue > MAX_PRICE_DEVIATION_IN_BPS) revert InvalidStEthPrice(); |
There was a problem hiding this comment.
Liquifier price deviation check divides by zero when market value is zero
Low Severity
In quoteByMarketValue, if the Curve pool's get_dy returns zero for a non-zero _amount (e.g., during extreme pool imbalance), _marketValue would be zero. The subsequent deviation * BASIS_POINT_SCALE / _marketValue division would then revert with an unhelpful panic instead of the expected InvalidStEthPrice error, making debugging harder and masking the root cause.
Reviewed by Cursor Bugbot for commit 1e11e8e. Configure here.
…nto yash/feat/blacklist-users
…-task yash/feat/check-execute-task
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
There are 6 total unresolved issues (including 4 from previous reviews).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d442527. Configure here.
| RoleRegistry public roleRegistry; | ||
|
|
||
| uint256 public maxFinalizedWithdrawalAmountPerDay; | ||
| uint256 public maxNumValidatorsToApprovePerDay; |
There was a problem hiding this comment.
Uninitialized rate limits block oracle report execution
High Severity
maxFinalizedWithdrawalAmountPerDay and maxNumValidatorsToApprovePerDay are new storage variables that default to 0 and have no initialization in the constructor, initialize, or any initializeOnUpgrade function. The _validateReport function checks numValidatorsToApprovePerDay > maxNumValidatorsToApprovePerDay and finalizedWithdrawalAmountPerDay > maxFinalizedWithdrawalAmountPerDay, so any oracle report containing non-zero validator approvals or finalized withdrawals will be rejected until an admin manually sets these values.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit d442527. Configure here.
| if (!roleRegistry.hasRole(ETHERFI_ORACLE_EXECUTOR_ADMIN_ROLE, msg.sender)) revert IncorrectRole(); | ||
| if (_maxNumValidatorsToApprovePerDay > MAX_NUM_VALIDATORS_TO_APPROVE_PER_DAY) revert InvalidMaxNumValidatorsToApprovePerDay(); | ||
| maxNumValidatorsToApprovePerDay = _maxNumValidatorsToApprovePerDay; | ||
| } |
There was a problem hiding this comment.
Validator approval rate limit can be set to zero
Medium Severity
updateMaxNumValidatorsToApprovePerDay only checks > MAX_NUM_VALIDATORS_TO_APPROVE_PER_DAY but lacks a == 0 lower bound check, unlike updateMaxFinalizedWithdrawalAmountPerDay which explicitly rejects zero. Setting this to 0 permanently blocks all validator approvals through oracle reports, since any non-zero count will fail _validateReport.
Reviewed by Cursor Bugbot for commit d442527. Configure here.
…withdrawals T2-2: Stale Rate Redemption Fallback
…nto yash/feat/blacklist-users
yash/feat/blacklist-users


Note
High Risk
High risk because it changes authorization, pausing, and withdrawal/escrow accounting across core contracts (
LiquidityPool,PriorityWithdrawalQueue,RedemptionManager, tokens), which can impact fund flows and upgrade safety if misconfigured.Overview
Security hardening across core contracts. Replaces multiple ad-hoc
admins/pausersmappings withRoleRegistry-based roles and updates scripts/tests accordingly, including new role checks for pausing/unpausing.Adds new enforcement controls. Introduces pervasive
IBlacklisterchecks (deposits, bids, redemptions, token transfers, membership actions) and adds timed pause support viaPausableUntil(newPAUSE_UNTIL_ROLE/UNPAUSE_UNTIL_ROLE) wired intoLiquidityPool,EtherFiRateLimiter,EtherFiNodesManager,PriorityWithdrawalQueue, and distributors.Refactors withdrawal/escrow mechanics.
LiquidityPoolnow supports an escrow migration (initializeOnUpgradeV2) that moves previously “locked” ETH out of LP intoWithdrawRequestNFT/PriorityWithdrawalQueue, updates LPwithdrawto treat NFT/queue withdrawals as paid from segregated balances, and adds new LP<->queue flows (transferLockedEthForPriority,returnLockedEth) withPriorityWithdrawalQueueupdated to escrow ETH on fulfill/claim/cancel and enforce a newMAX_AMOUNT.Additional guardrails. Adds a namespaced reentrancy guard (
ReentrancyGuardNamespaced) to avoid proxy storage layout issues, enforces a minimum share value check inLiquidityPool, adds stETH market-value validation using a Chainlink feed + deviation/staleness bounds inLiquifier, and tightensEtherFiAdminreport validation plus a stale-oracle withdrawal finalization path.Minor: CI now passes
OP_RPC_URL, andfoundry.lockis ignored.Reviewed by Cursor Bugbot for commit 4d3febc. Bugbot is set up for automated code reviews on this repo. Configure here.