Case study · Solana smart contract
A slashing check that only looked at half the collateral
- Project
- Paraloom, a privacy-focused Solana L2
- Component
slash_validatorin the Anchor program- Severity
- Medium, under the project's own bounty scale
- Report
- Issue #1406 · PR #1407
Background
Paraloom validators must lock two kinds of collateral to join: SOL and a protocol token. Registration enforces a minimum for both. Validators then co-sign settlements, and the network needs a supermajority of them to approve.
The bug
When the admin slashes a validator, both balances are reduced by the same percentage. The code then decides whether to deactivate the validator, and that check compared only the SOL balance to its minimum.
- if validator_account.stake_amount < registry.minimum_stake { + if validator_account.stake_amount < registry.minimum_stake + || validator_account.token_stake_amount < registry.min_token_stake + { validator_account.is_active = false; // residual SOL and token are moved to unbonding }
So a validator with extra SOL could be slashed until its token collateral was below the required minimum, and still stay active. It kept counting toward the quorum and kept co-signing, even though it would not have been allowed to register in that state.
Why it matters
The token half exists to make misbehaviour costly. A validator that has been slashed below the token floor but stays active is exactly the case the rule was meant to remove. This is an accounting and invariant failure rather than a direct theft path, which is why I rated it Medium.
The fix and the test
The patch adds the second condition, so dropping below either floor deactivates the validator and moves both residual balances into unbonding. I added an integration test that registers a validator with surplus SOL and the minimum token stake, applies a 25% slash, and asserts that the validator is inactive, the active count and total stake are decremented, and the residual SOL and tokens are in unbonding. I also adjusted one existing test so it still leaves both balances above their floors.
Status: submitted and awaiting maintainer review. I wrote the test against the project's existing test helpers, but I have not run the suite locally, and the project's CI has not yet been approved to run on my pull request.