Root Cause
MAYAChain's trade account system contained a cluster of six interrelated bugs in its outbound transaction handling and liquidity-pool mathematics. The root failure was in the slash subsidy mechanism — a compensation feature designed to reimburse liquidity providers when a validator steals assets. A crafted transaction could falsely trigger this mechanism, which had no upper bound on the CACAO it would credit.
The attack exploited:
- False positive in the theft detection logic (legitimate outbound incorrectly classified as stolen)
- Uncapped slash subsidy calculation interacting with pool accounting
- Pool balance bookkeeping error that recorded phantom CACAO without requiring actual reserves
- Trade account credit/debit asymmetry that allowed asset withdrawal against inflated balances
- Asgard vault module permitting withdrawal against unchecked pool state
- Pool-ownership dilution via minimal deposit giving attacker >99% share
// Pseudocode illustrating the uncapped slash subsidy flaw (MAYAChain Go codebase)
func handleOutboundTx(ctx Context, tx ObservedTx) {
if isStolenByValidator(tx) { // Bug #1: false positive classification
slashAmt := calcSlashAmount(tx.Amount) // Bug #2: no ceiling on slashAmt
pool := getPool(tx.Asset)
pool.BalanceCacao += slashAmt // Bug #3: credited without reserve check
setPool(ctx, pool) // phantom balance now persists
// reserve.BalanceCacao unchanged — divergence created
}
}
// Attacker then:
// addLiquidity(tiny CACAO) → gets >99% LP share of inflated pool
// withdraw(99%) → receives 48.87M phantom CACAO from Asgard vault
Attack Steps
| Step | Action | Detail |
|---|---|---|
| 1 | Craft exploit tx | Single transaction containing 23 messages targeting trade account handlers |
| 2 | Trigger false theft detection | Bug #1: system classifies legitimate outbound transfer as validator theft |
| 3 | Activate uncapped subsidy | Bug #2: slash subsidy calculates 49.45M CACAO credit — far exceeding reserves |
| 4 | Phantom balance recorded | Bug #3: ARB.LINK pool balance inflated to 49.45M CACAO; reserves unchanged |
| 5 | Become majority LP | Deposit tiny CACAO → acquire >99% ownership of inflated pool |
| 6 | Withdraw from Asgard | Withdraw 48.87M CACAO from Asgard vault module; hard assets (BTC, ETH, etc.) also swept |
| 7 | Sell CACAO | Massive sell pressure causes CACAO price to collapse 88% (≈$0.115 → $0.013) |
Impact
- Hard asset loss: ~$1.36M in cross-chain assets (BTC, ETH, stables)
- CACAO market impact: Price fell from ~$0.115 to ~$0.013 — an 88% single-day collapse; total pool value impact ~$11M
- Protocol: MAYAChain (THORChain fork), specifically trade account module and Asgard vault
- Chain: MAYAChain L1 (Cosmos-SDK / EVM cross-chain)
- Date: August 18, 2026 (~17:30 UTC)
- Response: Network halted; team confirmed "sophisticated 6-bug exploit"; recovery plan mirrors THORChain's 2021 playbook (validator slashing, LP reimbursement fund).
Lessons for Auditors
- Cap all subsidy/compensation mechanisms: Any auto-compensation feature (slash rebate, insurance payout, slippage cover) must have an explicit ceiling tied to actual reserve balances — never credit more than the reserve can cover.
- Verify reserve solvency before pool writes: Pool balance writes should be followed by an invariant check:
pool.BalanceCacao <= reserve.BalanceCacao. Failing this check should revert the entire transaction. - Fuzz with chained message transactions: Multi-message transactions (especially 10+ messages) should be fuzz-tested for unexpected state accumulation between messages. Each message handler must validate state on entry, not assume prior handlers left it valid.
- Theft detection false-positive rate: Any mechanism that triggers financial compensation on detection of bad behavior must be extremely precise — false positives are attackable. Require multi-validator consensus before triggering a slash subsidy.
- THORChain / MAYAChain fork audits: Forks of THORChain carry the same systemic risks in pool math and the Asgard module; all invariants from prior THORChain audit findings should be re-verified after every protocol modification.