Tapioca — disclosed vulnerability reports and payouts
Every publicly disclosed and closed bug bounty report we hold for Tapioca, 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 Tapioca 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 Access control, Logic error, Integer overflow / underflow, Governance attack, Bridge exploit, 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
- Access control findings disclosed against Tapioca
- Logic error findings disclosed against Tapioca
- Integer overflow / underflow findings disclosed against Tapioca
- Governance attack findings disclosed against Tapioca
- Bridge exploit findings disclosed against Tapioca
Curated highlights
The largest disclosed payouts in this group, with our own summary of each. Every report links back to the original disclosure.
Tapioca: Unprotected `executeModule` function allows to steal the tokens
Tapioca's USDO token exposes a public executeModule function whose module selector and encoded parameters are entirely caller-controlled with no ownership or authorization check. Because the function forwards arbitrary module calls (here UsdoMarketReceiver.removeAssetReceiver, which drives magnetar's exitPositionAndRemoveCollateral path), any address can instruct the protocol to remove another user's deposited assets from a Singularity market and withdraw them to an attacker-chosen recipient. The report demonstrates the full attack end-to-end with a struct and PoC, showing a victim's market assets drained and credited to the attacker. The protocol acknowledged the issue and proposed validating that the caller equals the user whose operations are being executed.
Tapioca: Unupdated totalBorrow After BigBang Liquidation
During BigBang liquidation the helper _updateBorrowAndCollateralShare() decrements the user's borrow and collateral shares and the caller drops totalCollateralShare, but the global totalBorrow accumulator is never reduced. As a result the market's global debt figure stays artificially high after liquidation, inflating interest accrual and corrupting every subsequent debt and interest computation market-wide. The same accounting gap exists in the Singularity (SGL) liquidation path. The protocol acknowledged and fixed it by subtracting the repaid elastic and base amounts from totalBorrow in PR 354.
Tapioca: Underflow Vulnerability in `Market::_allowedBorrow` Function: Oversight with Pearlmit Allowance Handling
Tapioca's Market contract lets a granter authorize a spender to borrow on their behalf via either the internal `allowanceBorrow` mapping (set through `approveBorrow`) or an external approval granted through the Pearlmit contract. The `_allowedBorrow` guard treats both allowance sources as valid, but the allowance-decrement logic unconditionally subtracts the borrowed share from the internal market mapping regardless of which source authorized the call. A spender operating solely under a Pearlmit grant therefore has an internal allowance of zero, and the `0 - share` subtraction underflows and reverts the whole transaction. This permanently disables the Pearlmit-based borrowing path, so authorized spenders can never actually borrow on behalf of the granter even though the protocol advertises that permission as supported. The subset of users relying on Pearlmit approvals for borrowing is economically locked out of the intended functionality.
Tapioca: BBCommon::_accrue wrong value is used to prevent overflow
Tapioca's BigBang market uses a shared accrual routine, _accrue, whose overflow guard clamps the accumulated interest to `type(uint128).max - totalBorrowCap`. That bound is only safe while the outstanding elastic debt remains below the cap, so a single prior accrual that pushes `totalBorrow.elastic` above the cap leaves the clamp ineffective; the next call to _accrue overflows and reverts. Because many market entrypoints invoke _accrue before executing their logic, the revert effectively freezes the market's core functions, a denial-of-service on legitimate borrowers. The finding was confirmed and fixed by clamping to `type(uint128).max - totalBorrow.elastic` in Tapioca-bar PR 351.
Tapioca: mTOFTReceiver MSG_XCHAIN_LEND_XCHAIN_LOCK unable to execute
Tapioca's mTOFTReceiver dispatches incoming LayerZero compose messages through a chain of handlers; each handler is expected to return true when it recognizes and processes a message type. The MSG_XCHAIN_LEND_XCHAIN_LOCK branch in _toftCustomComposeReceiver executes the intended module call (TOFTOptionsReceiverModule.mintLendXChainSGLXChainLockAndParticipateReceiver) but never returns true, falling through to the else branch that returns false. Because _lzCompose treats a false return as an unrecognized type, it reverts with InvalidMsgType, so every cross-chain lend-and-lock operation is permanently blocked even though its innermost logic runs. This is a pure availability flaw that breaks an entire cross-chain feature rather than draining funds.
Tapioca: Withdrawing to other chain when exercising options won’t work as expected, leading to DoS
Tapioca's DAO Share Options (DSO) module, UsdoOptionReceiverModule, lets users exercise locked USDO options into TAP tokens and optionally bridge them to another chain via LayerZero. When a user sets withdrawOnOtherChain to true, the module calls its own internal _sendPacket() helper, which operates on the USDO OFT — debiting and burning USDO from the msg.sender instead of bridging the freshly exercised tapOft tokens. Because the burning target is the wrong token, the transaction either burns USDO from the user and strands the TAP tokens in the USDO contract, or, more commonly, reverts with 'ERC20: burn amount exceeds balance', permanently DoS-ing the cross-chain option-exercise feature. The fix is to call the tapOft contract's own sendPacket() so the bridged asset is actually TAP rather than USDO.