Cap — disclosed vulnerability reports and payouts
Every publicly disclosed and closed bug bounty report we hold for Cap, with our own summary of each finding and a link to the original disclosure.
- Reports indexed
- 7
- Total paid
- $0
- Critical
- 0
- Largest payout
- $0
This page collects the 7 closed, publicly disclosed Cap reports indexed on CoinBuggie. Nothing here is active or unpatched — every entry was published by the programme or the researcher after remediation.
The findings concentrate in Logic error, Oracle manipulation, across EVM-Solidity. Reading a single protocol end to end is the fastest way to see which assumptions its codebase repeatedly gets wrong, which is usually a better predictor of where the next finding lives than the category alone.
Use the vulnerability class links below to compare these findings against the same bug class in other protocols.
What reviewers look for
- Logic error findings disclosed against Cap
- Oracle manipulation findings disclosed against Cap
Curated highlights
The largest disclosed payouts in this group, with our own summary of each. Every report links back to the original disclosure.
Cap: Lender DoS if all asset is borrowed or realized
Cap's BorrowLogic.realizeRestakerInterest() fails to guard against a zero realizedInterest before borrowing from the vault and distributing rewards to restakers. When the entire asset supply is borrowed (or interest is already realized), the realized amount is 0, so the delegation holds no rewards and Symbiotic's DefaultStakerRewards reverts with InsufficientReward. Because interest realization is executed as a precursor step of borrow, repay and liquidation flows, the revert bricks these time-sensitive operations, letting an agent deliberately DoS another agent's repay or liquidation. The verified fix wraps the borrow and distributeRewards calls in an if (realizedInterest > 0) guard.
Cap: Cannot repay or liquidate on paused asset
Cap's lending protocol intends to allow repayment and liquidation on paused assets while blocking minting and borrowing, so that positions on paused assets can still be settled. However, the repay path calls Lender.realizeRestakerInterest, which unconditionally invokes Vault.borrow even when the realized interest on a paused asset is zero. Because the paused asset makes that borrow revert with AssetPaused, repayment always fails and liquidations are blocked as a consequence, trapping agents' debt. The proposed fix guards the borrow-and-reward calls behind a realizedInterest > 0 check so zero-interest settlement skips the prohibited borrow.
Cap: Utilization rate multiplier will not shift if oracle is consulted frequently
Cap's VaultAdapter computes a utilization-rate multiplier that glides toward a target over time. The time-based shift term `(_elapsed * $.rate / 1e27)` is truncated before being combined with the slope factor, so whenever a caller queries the utilization oracle before enough time has elapsed for that quotient to reach one, the term rounds to zero and the multiplier stays frozen. An attacker who calls the oracle at short, sub-threshold intervals (e.g., every 23 hours against a 24-hour rate cycle) can pin the multiplier, keeping the DebtToken's borrow interest from ramping up during high utilization or from declining during low utilization. Sherlock accepted the issue and the protocol fixed it by deferring the division until after multiplying by elapsed time and rate, preserving arithmetic precision.
Cap: Restaker rewards on zero coverage agent will be stolen by subsequent restaker interest realization
Cap's lending protocol routes realized restaker interest from its Lender/BorrowLogic into a Delegation contract that is meant to forward the value to network middleware and restakers. Delegation.sol's distributeRewards() early-returns when the agent's total coverage is zero, leaving the received interest sitting idle in the Delegation contract instead of being distributed. Because a later realizeRestakerInterest() call reads the contract's full token balance, the stuck amount is swept to the network of whichever agent is processed subsequently, so those restakers receive rewards that belonged to the original restakers. Since realizeRestakerInterest() is public, any party can trigger this misallocation once a zero-coverage deposit has had its interest realized.
Cap: VaultAdapter::multiplier not initialized can lead first borrows to have `utilizationRate` = 0
Cap's DebtToken computes its interest rate as a base rate plus a utilization-dependent component, where the utilization component scales with a `multiplier` stored in the VaultAdapter oracle library. Because that storage value defaults to zero, the first borrower whose loan pushes utilization above the kink threshold triggers `_applySlopes`, which multiplies the still-zero multiplier by a positive growth factor — leaving it permanently at zero. As long as utilization stays above kink, every subsequent borrower is therefore charged a zero utilization-based rate, so the protocol only earns the base interest and forgoes the premium it is owed at high utilization. The fix is to initialize the multiplier to its neutral value instead of relying on the zero default.
Cap: Attacker/partial liquidator can extend Liquidation action by resetting $.liquidationStart[_agent] to 0.
Cap's lending pool closes a liquidation by resetting `liquidationStart[agent] = 0` based on a health factor recomputed immediately after debt repayment but before the liquidated value is slashed from the position's delegation. Because debt is burned before the delegation reduction is applied, the recomputed health is overstated, so a partial repayment of a few wei can make an unhealthy position appear healthy and prematurely close its liquidation. A genuine liquidator that follows then cannot liquidate promptly because a fresh grace period applies, repeatedly extending the window on an undercollateralized position. The finding was confirmed by the protocol team and fixed by moving the health check and close after the delegation slash.