DEV Community

Cover image for Solv Protocol Hack: $2.5M Double Mint Exploit
QuillAudits
QuillAudits

Posted on • Originally published at quillaudits.com

Solv Protocol Hack: $2.5M Double Mint Exploit

The Solv Protocol exploit resulted in approximately $2.5M in losses after an attacker exploited a logic flaw in the BitcoinReserveOffering contract. The vulnerability allowed the attacker to mint BRO tokens twice during a single mint flow, leading to massive token inflation.

The issue stemmed from an interaction between the NFT transfer process and the onERC721Received callback. By triggering token minting inside the callback and then receiving another mint when execution returned to the main mint() function, the attacker was able to create unbacked BRO tokens.

How the Exploit Happened?

The attacker began with 135 BRO tokens, which were burned through the reserve contract. In return, the protocol issued a small amount of GOEFS tokens based on the current exchange rate.

Using these tokens, the attacker initiated a mint transaction, sending GOEFS tokens along with a specific NFT. When the NFT was transferred, the contract triggered the onERC721Received callback, which internally executed the _mint function and issued BRO tokens to the attacker.

However, after the callback finished, the contract returned to the original mint() function and minted tokens again for the same action. This unintended behavior resulted in double minting.

Token Inflation in a Single Transaction

The attacker repeatedly triggered this mint flow 22 times within a single transaction. Because the entire exploit occurred in one transaction, the exchange rate remained constant, allowing the attacker to repeatedly double the minted tokens.

Through this process, the attacker inflated their holdings from 135 BRO tokens to approximately 567 million BRO tokens.

Converting the Exploit Into Profit

Once the tokens were minted, the attacker converted part of the inflated supply into real assets. Around 165M BRO tokens were swapped through the BRO–SolvBTC exchange, and then routed through Uniswap V3, eventually converting the assets into 1211 ETH.

The remaining tokens remained in the attacker's wallet.Following the swaps, the extracted ETH was transferred to multiple attacker-controlled wallets and eventually deposited into RailGun, a privacy protocol used to obscure transaction trails.

Want to see the full technical breakdown, attack flow diagrams and on-chain analysis?
Read our detailed blog: Solv Protocol Exploit (Explained in Depth)

Root Cause

The exploit was caused by a logic flaw in the minting flow.
During NFT transfers, the contract triggered a callback (onERC721Received) that already executed a mint. When execution returned to the mint() function, the contract minted tokens again without validating whether minting had already occurred.

This lack of validation allowed the attacker to repeatedly mint tokens and inflate supply within a single transaction.

Why This Matters?

The Solv Protocol exploit highlights how small logic flaws in smart contract flows can lead to catastrophic token inflation. Improper handling of external calls, callbacks, and state updates can introduce subtle vulnerabilities that attackers can exploit at scale.

Top comments (1)

Collapse
 
doomhammerhell profile image
Mayckon Giovani

Incidents like the Solv exploit are a good reminder that most catastrophic failures in smart contracts are not caused by exotic cryptography failures or complex financial primitives, but by extremely mundane control-flow mistakes. What stands out here is not the creativity of the attacker, but the architectural fragility of the minting pipeline itself. When a contract mixes asset transfers, callbacks, and token issuance inside the same execution path, it is effectively delegating part of its control flow to external code. The moment an ERC721.safeTransfer triggers onERC721Received, the contract is no longer executing in a closed system. If mint logic can be reached both inside the callback and again after returning to the original mint() flow, you have implicitly created a reentrant mint surface, even if the contract does not look like a classic reentrancy bug.

From a systems engineering perspective, the deeper problem is that token supply invariants were not treated as first-class protocol constraints. In any mint or burn pipeline, there should be a strict invariant: every unit of issued supply must correspond to a verifiable state transition that can only occur once. The moment the mint path can be reached through multiple execution branches without a state guard, the invariant is broken. In this case the invariant should have been something like “one reserve redemption → one mint event”, enforced before any external call occurs. Instead, the contract allowed external callbacks to re-enter a mint path before the original state transition was finalized.

Another interesting detail is that the attacker executed the entire inflation loop within a single transaction. This is a classic DeFi exploit pattern because it prevents price or exchange rate updates from reacting to the manipulation. By keeping the exchange rate constant across the 22 iterations, the attacker effectively turned the minting logic into a deterministic inflation amplifier. Once the supply exploded, the rest was simply a liquidity extraction step through the BRO–SolvBTC pair and Uniswap routing.

What this incident really highlights is the importance of invariant-driven design in smart contracts. The correct approach is not just adding reentrancy guards or checks after the fact, but structuring the contract so that mint authority cannot be reached through callbacks at all. External calls should happen only after the state transition that enforces the invariant is finalized, or the mint logic must be isolated into an internal path that cannot be triggered indirectly. In other words, supply-critical operations should be architecturally unreachable from external callback contexts.

The industry often frames these exploits as “logic bugs”, but that description undersells the issue. These are architectural failures in control-flow design. As long as protocols continue composing token logic with external callbacks without formalizing their state invariants, these kinds of exploits will keep appearing.