Conversation
tsudmi
approved these changes
Sep 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The operator has been sending
withdrawValidatorstransactions for dust amounts (61 gwei, 62 gwei, 3954 gwei) roughly every 12 hours on the Serenita vault, each costing more in gas than it withdraws.Root cause: the vault exit queue is share-denominated, so queued positions keep accruing rewards at every oracle update. The operator requested exactly the
getExitQueueMissingAssetsshortfall, floored to 1 gwei and truncated down. An EL-triggered partial withdrawal only lands afterMIN_VALIDATOR_WITHDRAWABILITY_DELAY(256 epochs, ~27h on mainnet) plus its wait in the pending-partials sweep plus the next harvest, so every reward update during that window produced a fresh shortfall of ~12h of rewards on the remaining queue, and the operator immediately chased it with another transaction.Changes:
get_queued_assetsnow returnsExitQueueAssets(missing, total).missingis the net shortfall as before.totalis the same checker call with in-flight withdrawals and redemptions set to zero, i.e. the whole remaining queue that keeps accruing rewards.calculate_withdrawal_bufferpads the request with the rewards expected to accrue ontotalover the full latency window: the larger of the withdrawability delay and the pending-partials sweep wait (from the queue length the operator already fetches, the sweep drains concurrently with the delay), plus the keeperrewardsDelay, using the osToken controlleravgRewardPerSecondas the rate and a 2x safety factor. Excess lands as withdrawable assets and is re-staked by the normal funding path.MIN_WITHDRAWAL_AMOUNT_GWEIbecomes an env setting (default 1 gwei, so any positive shortfall is served and a small exit is paid once rather than left in the queue). A startup check caps it at 0.01 ETH, mirroring the oracle'sMISSING_ASSETS_THRESHOLD: above that the operator would skip shortfalls the oracle already treats as exit-worthy and covers with a full validator exit.NetworkConfiggainsMIN_VALIDATOR_WITHDRAWABILITY_DELAY_EPOCHS(256 on all networks) andMAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP(8 on mainnet and hoodi, 6 on gnosis), verified against live consensus node specs.KeeperContract.rewards_delayandOsTokenVaultControllerContract.avg_reward_per_second;get_withdrawals_countis fetched once per run and reused.totalis skipped when there is no shortfall. In the full-exit path the partial top-up is skipped once a full exit covers the shortfall, so the buffer alone never produces a partial request.For a 120 ETH queue at the current ~2% protocol rate the buffer is about 0.022 ETH; for a 164 gwei remainder it is zero.