Velocimeter — disclosed vulnerability reports and payouts
Every publicly disclosed and closed bug bounty report we hold for Velocimeter, with our own summary of each finding and a link to the original disclosure.
- Reports indexed
- 16
- Total paid
- $0
- Critical
- 0
- Largest payout
- $0
This page collects the 16 closed, publicly disclosed Velocimeter reports indexed on Coin Buggie. Nothing here is active or unpatched — every entry was published by the programme or the researcher after remediation.
The findings concentrate in Logic error, 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 Velocimeter
Curated highlights
The largest disclosed payouts in this group, with our own summary of each. Every report links back to the original disclosure.
Velocimeter: pause or kill gauge can lead to FLOW token stuck in voter
Velocimeter's V4 Voter contract lets the emergencyCouncil pause or fully kill a gauge at any time, but pauseGauge and killGaugeTotally zero out the gauge's unclaimed FLOW balance in the voter without transferring those tokens back to the minter or forwarding them to any gauge. When Voter.distribute later runs, the wiped claimable amount is never paid out, so the already-minted FLOW stays locked in the voter contract and cannot reach the gauge's liquidity providers. The report's PoC shows that after pausing one of three gauges and distributing, the paused gauge receives zero FLOW while roughly one thousand FLOW remain stranded in the voter, with no recovery in subsequent rounds. This is a permanent loss of protocol emission rewards for the affected gauge's LPs.
Velocimeter: Exercising a large amount of options gives significantly higher discounts than supposed to.
Velocimeter's OptionTokenV4 priced option exercises using getTimeWeightedAveragePrice, which averages the AMM pair's amountOut over four TWAP points rather than reading the true TWAP price. Because amountOut is the marginal swap output, a larger exercise moves the pair's reserves and raises the output-token value, so a bigger position yields a lower effective payment-to-underlying ratio and a deeper discount than the protocol intends. The report's 1e18-reserve example shows 0.1e18 exercising at a 0.9 ratio versus 100e18 at 0.01. The finding was confirmed, fixed upstream, and signed off by the Lead Senior Watson.
Velocimeter: If user merges their `veNFT`, they'll lose part of their rewards
Velocimeter's VotingEscrow lets users merge two veNFTs into one, but the merge function zeroes the `from` lock and burns that token. Because the RewardsDistributor only lets a token claim rewards up to the week before the current `last_token_time`, rewards are always lagging at least one week. Once a token is burned, `claim` can never be called for it (it requires owner/approved), so the current week's rewards are permanently lost each time a user merges without claiming first. Sherlock upheld the finding as High with several duplicates, and the fix recorded the burned token's last owner in a mapping that the RewardsDistributor and Bribe contracts check so rewards can still be routed.
Velocimeter: `ve_supply` is updated incorrectly
Velocimeter's RewardsDistributorV2 records the weekly ve-token supply in ve_supply[t] to compute distribution rewards. In _checkpoint_total_supply, the loop that snapshots each week boundary continues while t <= rounded_timestamp, which means on a timestamp that lands exactly on a week boundary the not-yet-completed current week gets a supply snapshot taken before newly minted veNFTs can be counted. An attacker who mints a veNFT immediately after that checkpoint locks in a balance that is missing from the recorded supply, so the new token captures nearly the entire deposited reward for that period and legitimate earlier lockers end up with nothing to claim. The fix tightens the loop exit from `t > rounded_timestamp` to `t >= rounded_timestamp` so a week's supply is only finalized after the week has actually ended.
Velocimeter: The circulating_supply() of the Minter contract may revert, resulting in the inability of the Minter to periodically emit Flow tokens
Velocimeter's Minter contract has a weekly emission trigger, update_period(), that computes circulating supply inside an emit statement as _flow.totalSupply() minus _ve.totalSupply(). Because the subtraction is unguarded in Solidity, the call reverts whenever ve voting power (locked lpToken value) exceeds the total minted Flow supply, silently halting all weekly Flow emissions to reward distributors. The write-up argues this state is reachable when the flow-weth pool has strong liquidity and Flow trades high, though the judge disputed reachability since ve supply decays with time and lpTokens require previously minted Flow. The protocol fixed it by guarding the subtraction to return zero on underflow and later simplifying circulating_supply() to just return Flow's total supply; the lead senior Watson accepted the fix.
Velocimeter: voters cannot disable max lock
Velocimeter's VotingEscrow.disable_max_lock suffers from an ordering bug when the user disables max lock on the token occupying the last slot of the max_locked_nfts array. The function overwrites that slot with the array's last element before recomputing the mapping entry, so maxLockIdToIndex for the disabled token is refreshed from an already-overwritten value and stays non-zero, leaving the token permanently bookmarked as max-locked. Because the withdrawal path relies on this disabled state, the user's lock end keeps decreasing on every withdraw call and their assets become effectively stuck. The finding was accepted as High severity, fixed by the protocol in a PR, and verified by the Lead Senior Watson.
All reports in this group
- Velocimeter: `DepositWithLock` done via `OptionToken` can be abused to permanently lock a user positionLogic error$0
- Velocimeter: poke() may be dosLogic error$0
- Velocimeter: Voting power does not decay when calculating shares of flow emissions if the user does not vote again.Logic error$0
- Velocimeter: VotingEscrow MAX_DELEGATES value can lead to DOS on certain EVM-compatible chainsLogic error$0
- Velocimeter: Rewards supplied to a gauge, prior to its first depositor will be permanently lost.Logic error$0
- Velocimeter: First liquidity provider of a newly created stable pair can cause DOS and loss of fundsLogic error$0
- Velocimeter: Incorrect calculation of TWAP in OptionTokenV4.getTimeWeightedAveragePrice() function.Logic error$0
- Velocimeter: `update_period(..)` leads to wrong calculation in weekly emissions breaking accounting for the protocolLogic error$0
- Velocimeter: User can make their `veNFT` unpokeable by voting for a to-be-killed gaugeLogic error$0
- Velocimeter: `Voter.replaceFactory()` and `Voter.addFactory()` functions are broken.Logic error$0