When Gamma Equals Delta: How a Skipped Setup Step Cost FoomCash $2.26 Million
FoomCash marketed itself as a "ZKProof-powered private lottery protocol," a system whose withdrawals were supposedly unforgeable thanks to zero-knowledge proofs. The project pitched itself as a successor to the sanctioned Tornado Cash mixer, advertising higher daily transaction volume, more than $8 million in liquidity, and annual yields of 50–80% for liquidity providers. A single missing step in the cryptographic setup made all of that moot: the Groth16 verifier contracts deployed on both Ethereum and Base had set two critical constants — gamma and delta — to the identical elliptic curve point, which collapsed the soundness of the entire proof system. The result was a total loss of $2.26 million, as first reported.
No deposit was required to exploit it, and no valid witness was needed — just repeated calls from a script against a verifier that had never worked correctly. This wasn't a sophisticated hack; it was arithmetic. BlockSec Phalcon's monitoring identified it as essentially a copy of an earlier, smaller incident at Veil Cash, a Base-network privacy protocol hit days before by the same Groth16 misconfiguration. Whoever repeated the technique against FoomCash's larger pool ended up walking away with $320K legitimately — because FoomCash had previously posted a public bounty on Bitcointalk stating a single rule: "the only rule is code." Meanwhile, a separate party emptied the Ethereum side under the banner of a rescue operation, later identified as the security firm Decurity. All of this happened to a team that had reportedly gone quiet since around November 2025.

01Timeline of discovery
CertiK appears to have been first to flag the incident, on February 26, already naming the root cause: "We have seen a ~$1.8M exploit/whitehat rescue on FOOMCASH lottery contract. The root cause may be the delta2==gamma2 setting of the Groth16 verifier. This enables the exploiter to compute 'pC' needed for different 'nullifierHash' while all other inputs are the same, and repeatedly collect ZOOM tokens." BlockSec Phalcon's alert system followed shortly after, tying the FOOMCASH incident on Ethereum and Base to the recent Veil Cash verifier bug and estimating losses in the low seven figures. BeosInAlert added further detail: "An exploit/whitehat rescue has been detected on FOOMCASH and it seems to be another potential victim of a misconfigured Groth16 verifier." The earliest running tally put the loss at $1.6 million. Notably, BlockSec Phalcon's system classified the event as an imitation attack rather than a novel exploit — not a zero-day, not the product of a sophisticated adversary hunting for unknown flaws.
That's because the technique had already been documented in a public write-up on the Veil Cash incident, a smaller Base-based privacy protocol. In that earlier case, roughly 4.5 ETH sat in Veil Cash's legacy pools; an attacker drained 2.9 ETH using the identical Groth16 misconfiguration, Decurity intervened to rescue what remained, and the original attacker later returned the drained funds voluntarily — so all of Veil Cash's funds were ultimately recovered. Someone evidently read that post-mortem, found a much larger target running the same broken setup, and scaled the same method up by orders of magnitude. The blueprint had already been made public; FoomCash apparently never saw it.
The attack hit both chains at once. On Base, a single sequence of whitehat transactions drained nearly the entire lottery balance, capturing a low-six-figure slice of the eventual $2.26M total before any bad actor could act. On Ethereum, a separate whitehat operation emptied the mainnet lottery to zero, beating other potential attackers to the remaining seven-figure balance — a tranche Foom later said was 90% recovered and counted as part of a $1.84M white-hat response. Two separate wallets, the same technique, the same broken verifier, all in a single morning — against a protocol whose social accounts had gone silent since roughly November 2025. By the time researchers had documented how the exploit worked, both chains had already been drained.
02Anatomy of the broken verifier
FoomCash's entire privacy model rested on zero-knowledge proofs, following the standard deposit/proof/redeem structure: a user proves that a withdrawal corresponds to some earlier deposit without revealing which one, severing any link between sender and recipient. This is the same pattern Tornado Cash implemented using Groth16 zk-SNARKs — the mechanism FoomCash advertised as a "lottery/gambling dApp using ZK proofs (Groth16) for withdrawals," per its own proof-of-concept write-up.
A Groth16 verifier is the on-chain contract responsible for confirming a submitted proof is valid, doing so by checking a pairing equation that ties the proof's components (A, B, C) to a fixed verification key. Two elements of that key are essential: gamma (γ) and delta (δ), the G2 curve points anchoring the two right-hand pairing terms, as described in QuillAudits' technical breakdown. Properly configured, gamma and delta must be independently generated, random G2 elements produced during a trusted setup ceremony — that independence is what prevents algebraic shortcuts from collapsing the equation, as demonstrated when the two values are equal in both QuillAudits' analysis and Foom's own proof-of-concept.
On FoomCash's live contracts, gamma and delta were not independent at all — both were set to the BN254 G2 generator, identically, on both Ethereum and Base, from the moment of deployment. Foom's own technical post-mortem described the flaw plainly as "delta == gamma == G2 generator." With gamma equal to delta, the verifier's underlying security check no longer functions. Instead of confirming "does this proof correspond to a real deposit," the equation effectively reduced to asking "does 1 equal 1" — which is always true.
The proof-of-concept published by researcher DK27ss explains the exact exploitation: an attacker sets C to the negative of vk_x (making the right-hand side of the pairing equation cancel to 1), while using the publicly known constants A = alpha and B = beta (making the left-hand side cancel to 1 as well). "The verifier accepts the proof without needing a valid witness," the write-up states. From that point, forging a valid-looking proof is purely mechanical: an exploit contract reads alpha, beta, and the IC points straight from the on-chain verification key, computes vk_x from arbitrary chosen public inputs — root, nullifier, and recipient — sets A = alpha, B = beta, and C = -vk_x, then calls collect(), increments the nullifier, and loops, exactly matching the PoC's forgeAndCollect routine.
Run at scale, that loop was devastating: 10 iterations on Base drained 99.97% of the FOOM balance there, and 30 iterations on Ethereum drained 99.99% — figures that match the observed before-and-after balances on both chains. QuillAudits confirmed the vulnerability remained live: anyone could run a published Foundry cast call against the deployed Ethereum verifier contract with a fabricated proof built only from public inputs, and it would return true instead of reverting.
Both Foom's own post-exploit writeup and an independent analysis by ZKSecurity agree on the root cause: during the Phase 2 trusted setup performed with snarkjs, the command responsible for randomizing gamma and delta away from their default G2 generator values was simply never executed. This wasn't a case of weak or predictable randomness — there was no randomness introduced at all. The verifier shipped with snarkjs' untouched placeholder defaults.
03Who took what
Two chains, two separate actors, and one broken verifier doing all the work. On Base, a single transaction moved $320K worth of FOOM tokens, attributed to a whitehat operating under the handle duha. On Ethereum, $1.84M was withdrawn by the address whitehat-rescue.eth, tied to the security firm Decurity, which independently discovered the gamma-equals-delta flaw and carried out its own rescue.
The FOOM extracted on Base didn't remain there — it was bridged to Ethereum through FoomCash's own official bridge contract at 0x2f534ce6843e7a773fd9f2e45d04e8608b9de3f8. QuillAudits' initial analysis, published February 27 before the whitehat resolution had been confirmed, noted that the bridged tokens were converted into WETH, while the Ethereum-side FOOM was swapped for USDT at reportedly discounted rates, with the resulting funds spread across several identified externally-owned accounts.
The picture shifted on March 1, when it emerged that Decurity had returned $1.84M to the protocol as part of a rescue operation. The return happened the same day the funds were taken — on-chain records place the return transaction at 10:11 AM UTC on February 26, within hours of the initial drain. The protocol offered a $100K fee for the recovery; Decurity reportedly made no demands of its own.
Key addresses and transactions:
- ETH lottery contract: 0x239af915abcd0a5dcb8566e863088423831951f8
- Base lottery contract: 0xdb203504ba1fea79164af3ceffba88c59ee8aafd
- ETH verifier (misconfigured): 0xc043865fb4D542E2bc5ed5Ed9A2F0939965671A6
- Base verifier (identically misconfigured): 0x02c30D32A92a3C338bc43b78933D293dED4f68C6
- Primary ETH attack transaction: 0xce20448233f5ea6b6d7209cc40b4dc27b65e07728f2cbbfeb29fc0814e275e48
- Secondary transaction (Base): 0xa88317a105155b464118431ce1073d272d8b43e87aba528a24b62075e48d929d
- Decurity's returned-funds transaction: 0xfed2dc60634b321fab073312168b327a47fdd76d2a39489249e4ef986671e83f
- Involved EOAs: 0x46c403e3DcAF219D9D4De167cCc4e0dd8E81Eb72 (whitehat-rescue.eth), 0x73f55A95D6959D95B3f3f11dDd268ec502dAB1Ea, 0xa30841846259c02eb540059100b57d87c2384358
In total, 24,283,773,519,600 FOOM tokens moved out of the two contracts.
04The bounty that backfired
FoomCash's social media presence had gone dark since roughly November 2025 — no updates, no posts, nothing suggesting active stewardship of a protocol holding millions in user deposits. Three months of silence preceded the exploit, and silence continued immediately afterward.
But there was a wrinkle: before the attack, the team had published a public bounty challenge on Bitcointalk. The prize was roughly $500K in FOOM tokens sitting on Base, and the terms were stated in full as: "The only rule is code. If your code can take the funds, you've won." There was no restitution clause, no disclosure requirement, no deadline, and no provision for partial return — an unconditional, on-chain-verifiable dare.
duha accepted those terms, using the verifier flaw to drain the Base lottery contract — within scope, on the specified network, satisfying the one stated rule. The FoomCash team then reversed course and asked for 90% of the funds back. beacon302, speaking publicly on duha_real's behalf, pushed back: "Foom team is not respecting their own contract. duha_real is legally within his rights to keep all of the Base network funds. This is a public unilateral commitment. Terms are clear and verifiable on-chain. When you launch a bounty challenge with no restitution conditions, you accept consequences."
What followed became one of the more unusual public disputes in the space. On February 26, duha — using the handle Hao Pham — entered the EthSecurity Telegram group to publicly defend the position, then requested that SEAL step in as a mediator: the person who had just drained a protocol was now asking for formal arbitration to protect the right to keep the funds. Security researcher Elliot summed up the reaction: "You can't even make the eth security stuff up it's so absurd."
SEAL's Safe Harbor framework exists specifically to draw a clear line between whitehat rescues and exploits — but FoomCash had never adopted it. There was no pre-authorized rescue scope, no legal protection structure, and no designated recovery address; only a Bitcointalk forum post and a broken verifier contract.

beacon302 announced a resolution at approximately $330K on February 26; FoomCash's own statement on March 1 put the number at $320K, and the $10K gap between the two figures was never explained publicly. duha_real retained the Base bounty in full. The Ethereum-side situation was addressed in that same March 1 statement, which confirmed that Decurity — the firm operating the whitehat-rescue.eth address — had returned $1.84M, or 90% of the Ethereum funds, and had been paid a $100K fee for the recovery.
Adding it up: total bounty payouts and recovery costs came to $420K, total funds recovered were $1.84M, leaving a net loss of roughly $420K against the original $2.26M drained. One party kept $320K–$330K by winning a public dare; the other received a $100K fee for giving back what had been taken.
05Two accounts, one blockchain
The transaction history tells one version of events. FoomCash's public statement told a different one. The team's March 1 post did not describe a protocol drained by a bounty hunter and subsequently saved by a security firm that returned the funds within hours in exchange for a fee the protocol itself offered. Instead, it characterized the episode as an "elite white-hat response," describing duha as someone who "identified the vulnerability and moved to secure the funds on Base before malicious actors could strike," and labeling Decurity's actions on Ethereum an "analogous rescue" performed to "front-run malicious actors." The post further recast duha as the "winner of our Bitcointalk hacking contest held a year ago," who supposedly noticed the flaw and moved to protect the funds — omitting any mention of the 90% restitution demand, the ensuing public dispute, the EthSecurity Telegram standoff, the beacon302 threads, or the days of public pressure that preceded the resolution.
duha's own response played along: "By honoring their bug bounty policy, foomclub has proven that they take protocol security seriously and value the researchers helping them." Coming from someone who had just spent days publicly defending a right to keep funds a team wanted returned, it read as a notably gracious exit — one that didn't match the record either the blockchain or Twitter had already established.
06Aftermath
Someone found a public post-mortem describing an exploit on an obscure protocol, identified a much larger target running the identical broken verifier, and drained $2.26 million from contracts a team had stopped monitoring three months earlier. There was no public audit, no active monitoring, and no pause function available to stop it. The cryptographic guarantee marketed to users had been void from the moment of deployment — not because a value was set incorrectly, but because the CLI step that would have set any value at all was never run. FoomCash was the second protocol hit by this exact flaw within the same week, and researchers do not expect it to be the last.
In the aftermath, ZKSecurity and Dedaub scanned known EVM chains looking for other live contracts carrying the same defect. None of the Groth16 verifiers found with delta equal to gamma held meaningful recent activity or locked value — but a GitHub search still turned up repositories reproducing the same pattern, including a Tornado Cash fork with 248 stars. The immediately visible exposure may be limited, but how many similar deployments remain unexamined is harder to say.
When a trusted setup ships with its defaults untouched, whatever certainty it claimed to offer was never more than a placeholder — and a protocol capable of rewriting a public dispute into a coordinated rescue narrative has produced its own kind of zero-knowledge proof: one that demonstrates nothing about what actually happened, yet gets treated as valid all the same.
Get new scam files the moment we publish them — usually 2–3 emails a week.