Flat Money — disclosed vulnerability reports and payouts

Every publicly disclosed and closed bug bounty report we hold for Flat Money, with our own summary of each finding and a link to the original disclosure.

Reports indexed
14
Total paid
$0
Critical
0
Largest payout
$0

This page collects the 14 closed, publicly disclosed Flat Money 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, Oracle manipulation, Integer overflow / underflow, Reentrancy, 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 Flat Money
  • Oracle manipulation findings disclosed against Flat Money
  • Integer overflow / underflow findings disclosed against Flat Money
  • Reentrancy findings disclosed against Flat Money

Curated highlights

The largest disclosed payouts in this group, with our own summary of each. Every report links back to the original disclosure.

mediumLogic errorEVM-Solidity$0

Flat Money: Long traders unable to withdraw their assets

Flat Money's collateral-tracking invariant bricked the entire protocol whenever a long position's unrealized profit exceeded the total LP stable collateral. The vault books the long's gain into marginDepositedTotal without capping it, while the corresponding short-side loss is clamped at zero, so the tracked collateral ends up above the vault's real balance. The _getCollateralNet invariant then reverts in every user-facing function (deposit, withdraw, open/adjust/close position, liquidate), permanently locking long margins and LP collateral. The finding was judged valid and downgraded to Medium because triggering it requires an extreme ETH price move that the protocol team had flagged as an accepted risk.

Flat MoneysherlockFeb 4, 2024Open
highLogic errorEVM-Solidity$0

Flat Money: Trade fees can be avoided in limit orders

In Flat Money's limit-order flow, the leverage-close trade fee owed to UNIT LPs is snapshotted at the moment a limit order is announced, stored in _limitOrderClose, and then reused verbatim when the order executes. Because a trader can grow the position's additionalSize through LeverageModule.executeAdjust after the announcement, the final close settles with a fee computed on the original small size rather than the enlarged position; the embedded Foundry tests demonstrate the reordering yields an extra 2.4 rETH profit (2400 rETH x 0.1%) at LPs' expense. The protocol fixed it by recomputing the fee at execution time, and the judge upheld the finding at High after rejecting two downgrade escalations.

Flat MoneysherlockFeb 4, 2024Open
highOracle manipulationEVM-Solidity$0

Flat Money: Malicious keepers can manipulate the price when executing an order

Flat Money's order execution relies on the keeper pushing the latest Pyth off-chain price on-chain at execution time, enforced only by the updatePythPrice modifier. Because that modifier passes whatever bytes array the keeper supplies to Pyth and never validates it, a keeper can pass an empty priceUpdateData array, causing Pyth's updatePriceFeeds to perform no update while the order still executes against the previously stored on-chain price. Since keepers are permissionless and may themselves be LPs or collude with LPs, a malicious keeper can decide whether to refresh the price—selecting an entry price favorable to their own side of the zero-sum market and inflicting an immediate loss on the opposing traders or LPs. The maxDiffPercent deviation check does not reliably stop this because a selectively stale price can sit within the tolerance band. The finding was upheld as High by the Sherlock lead judge with the severity-restriction escalation rejected.

Flat MoneysherlockFeb 4, 2024Open
mediumLogic errorEVM-Solidity$0

Flat Money: In LeverageModule.executeOpen/executeAdjust, vault.checkSkewMax should be called after updating the global position data

In Flat Money's LeverageModule, the skew guard checkSkewMax is called before updateGlobalPositionData in both executeOpen and executeAdjust, so it evaluates longSkewFraction against a stale stableCollateralTotal that still includes unsettled unrealized PnL. Because updateGlobalPositionData settles profit or loss into stableCollateralTotal, the guard can understate skew when collateral price is rising, allowing new long positions to be opened that exceed the configured 120% skew cap. The finding was admitted as a valid Medium by the Sherlock judging panel and fixed in dhedge/flatcoin-v1#266, which moved the check to run after the position-data update (and ultimately stopped settling collateral inside updateGlobalPositionData), with the Lead Senior Watson signing off on the fix.

Flat MoneysherlockFeb 4, 2024Open
mediumLogic errorEVM-Solidity$0

Flat Money: Losses of some long traders can eat into the margins of others

Flat Money aggregates the PnL of all open long positions into a single shared global margin pool. When one position's settled margin falls below zero (bad debt) before being liquidated, its loss is deducted from that shared pool rather than being charged to LP collateral. As a result, a distressed trader's shortfall can drain the withdrawable margin and profits of other, still-solvent long traders. The finding, reported by xiaoming90, was escalated and ultimately adjudicated as a unique Medium-severity issue after the sponsor confirmed the old margin math had that side effect; it was fixed in PR 266.

Flat MoneysherlockFeb 4, 2024Open
highLogic errorEVM-Solidity$0

Flat Money: Incorrect handling of PnL during liquidation

Flat Money's liquidation flow applies a position's profit/loss twice. `liquidate()` first folds a portion of PnL into `stableCollateralTotal` via `updateStableCollateralTotal`, then calls `updateGlobalPositionData`, which recomputes `profitLossTotal` and re-applies it to both `stableCollateralTotal` and the new `marginDepositedTotal`. This double-count corrupts the protocol's two tracked pools so they no longer reconcile with the vault's real collateral balance. The report demonstrates three concrete scenarios where LPs absorb avoidable losses, the stable collateral total is inflated (allowing users to withdraw value the system does not hold), and tracked balances drift out of sync with actual balances. The remediation excludes `profitLossTotal` from the global position update during liquidation, and the fix was merged in PR 266 with lead-judge signoff.

Flat MoneysherlockFeb 4, 2024Open

All reports in this group

Vulnerability classes disclosed here

Related protocol pages