Reproduced Exploit
Tectonic TONIC Thin-Oracle Collateral Manipulation — Over-Borrow Against Inflated Spot Mark
1. Tectonic listed TONIC (its own illiquid governance token) as collateral with a 20% collateral factor. 2. The protocol’s internal oracle priced TONIC from a VVS + Crypto.com feed — effectively a spot / thin-market mark with no meaningful on-chain deviation/TWAP guard for this path. 3. Attacker pu…
Loss
~$75M (PeckShield ~$74M; researcher Weilin Li ~$66M then +~$8M → ~$75M). PoC drains 55M USDC + 45M USDT from…
Chain
Ethereum
Category
oracle
Date
Aug 2026
Source
Crypto Training
EVM Playground
Source-level debugger — step opcodes and Solidity in sync
The attack is replayed in an in-browser EVM preloaded with the exact dumped fork state. The execution tree shows every call; step by Solidity line or by opcode across all depths — source, Stack, Memory, Storage, Balances (native / ERC-20 / NFT), Transient storage and Return value stay in sync. Click a tree node, opcode, or source line to jump. No backend, no live RPC.
Source & credit. Crypto Training original detection and analysis (live Twitter/X security-alert intake — not from DeFiHackLabs). Standalone Foundry PoC, offline
anvil_state.json, and full write-up: 2026-08-TectonicTonicOracleManipulation_exp in theevm-hack-registrymirror.
Vulnerability classes: vuln/oracle/spot-price · vuln/oracle/price-manipulation · vuln/oracle/missing-validation · vuln/oracle/single-source
Reproduction: this folder · offline
[PASS]inoutput.txt·_shared/run_poc.sh 2026-08-TectonicTonicOracleManipulation_exp -vvvvv
Key info#
| Loss | ~$75M (PeckShield ~$74M; researcher Weilin Li |
| Chain | Cronos (chainId 25) |
| Protocol | Tectonic (@TectonicFi) — Compound-fork money market |
| Attacker EOA | 0x4266a0E6…3652 |
| Attack contract | 0xd3aaC8a1…f1F3 (deployed in setup tx) |
| Position / borrower | 0x2dc6A36F…b618 |
| Profit sink (Cronos) | 0x7D4E7e5D…F2DC (~$60M trapped after halt) |
| ETH bridge wallet | 0xc404160B…72DD (~$6M → ~2,600 ETH) |
| TectonicSocket | 0xb3831584…eEc0 |
| tTONIC / TONIC | 0xfe6934FD…20Ad / 0xDD73dEa1…c5B2 |
| Borrow markets (PoC) | tUSDC 0xB3bbf1bE…F4c8e · tUSDT 0xA683fdfD…44E5 |
| Oracle | 0xD360D8cA…754A |
| TONIC/USD feed | 0x14f75394…123F (docs: VVS Finance + Crypto.com) |
| Setup tx | 0x0fce5ae8…7d06 @ 90,896,190 |
| Over-borrow tx | 0xddc9dc47…eca20 @ 90,897,110 |
| Fork block | 90,897,109 (one before over-borrow; oracle already pumped, tTONIC collateral posted) |
| Alert | GoPlus · Weilin Li · The Block |
| Bug class | Thin-liq TONIC as Compound-fork collateral (CF 20%) priced by manipulable VVS-sourced internal oracle → over-borrow |
TL;DR#
- Tectonic listed TONIC (its own illiquid governance token) as collateral with a 20% collateral factor.
- The protocol’s internal oracle priced TONIC from a VVS + Crypto.com feed — effectively a spot / thin-market mark with no meaningful on-chain deviation/TWAP guard for this path.
- Attacker pumped TONIC ~100–200× in ~20 minutes, posted huge tTONIC collateral on position
0x2dc6…, then borrowed real USDC/USDT/… against the inflated mark (Mango-style). - Cronos halted block production; only ~$6M reached Ethereum; most funds stayed on Cronos.
- This PoC forks at 90,897,109 (oracle inflated + collateral live) and re-borrows 55M USDC + 45M USDT.
Background#
Tectonic is Cronos’s dominant Compound-fork lending market (pre-incident TVL ~$120M). Like Compound, borrows are gated by account liquidity: collateral value × collateral factor must cover debt, and collateral value comes from oracle.getUnderlyingPrice(tToken).
Tectonic’s docs list TONIC/USD at 0x14f753… with sources VVS Finance and Crypto.com Exchange. That feed is what the socket oracle (0xD360D8…) surfaces into getUnderlyingPrice(tTONIC). Listing a thin DEX-traded governance token as borrowable collateral is the same economic failure mode as Mango Markets (2022) and the contemporaneous Moonwell MAMO drain.
The vulnerable code#
Cronos contracts are not available via Etherscan V2 / Sourcify at build time. Behaviour below is confirmed on a live Cronos archive fork; Solidity under sources/ is RECONSTRUCTED teaching stubs marked as such.
Oracle path (reconstructed):
// sources/TectonicOracle_D360D8/PriceOracle.sol (RECONSTRUCTED)
function getUnderlyingPrice(address tToken) public view returns (uint256) {
int256 answer = AggregatorInterface(feeds[tToken]).latestAnswer();
require(answer > 0, "price <= 0");
uint8 feedDecimals = AggregatorInterface(feeds[tToken]).decimals(); // 12 for TONIC/USD
// No TWAP / deviation / thin-liquidity circuit breaker
return uint256(answer) * (10 ** (18 - feedDecimals));
}
On-fork at 90,897,109:
| Pre-pump (~90,896,189) | PoC fork | |
|---|---|---|
Feed latestAnswer (12 dec) | 10622 | 2076321 |
getUnderlyingPrice(tTONIC) | 1.0622e10 (~$1.06e-8) | 2.076321e12 (~$2.08e-6) |
| Approx. multiple | 1× | ~195× |
Collateral factor (live): markets(tTONIC) = (true, 0.2e18, …) — 20% CF.
Borrow gate (reconstructed Comptroller/Socket): borrowAllowed → getAccountLiquidity, which multiplies tTONIC balances by the oracle mark and CF. Inflated mark → huge liquidity → tUSDC.borrow / tUSDT.borrow succeed.
Root cause#
- Listing risk: Illiquid TONIC accepted as collateral (CF 20%) despite thin VVS liquidity (reports: ~$1.3M liquidity / ~$11k daily volume).
- Oracle risk: Internal TONIC/USD path tracks VVS spot (+ CEX) without an effective on-chain bound that would reject a ~100× move before borrows clear.
- Compound-fork amplification: Once the mark is wrong,
getAccountLiquiditytrusts it; there is no separate “realizable liquidity” check on collateral.
Same family as Mango / Moonwell-MAMO: thin collateral + manipulable mark + over-borrow.
Preconditions#
- TONIC listed with non-trivial CF (20%).
- Ability to move the VVS-influenced TONIC mark (capital + thin pool).
- Capacity to mint/post tTONIC and enter markets on a borrower account.
- Deep enough tUSDC/tUSDT (and other) cash to drain — at fork, ~55.24M USDC and ~45.65M USDT sat in those markets.
Attack walkthrough#
Historical path#
- Setup
0x0fce5ae8…@ 90,896,190 — deploy0xd3aa…, spend ~5M USDC from0x7D4E…, build position; position receives ~3.09e22 raw tTONIC (8 decimals). - Pump window — feed moves
10622→2076321by block 90,897,109. - Drain
0xddc9dc47…@ 90,897,110 — position borrows across markets; Transfer nets show ~55.24M USDC and ~45.65M USDT leaving tTokens alone (plus WCRO/WETH/WBTC/…). - Containment — Cronos validators halt; ~$6M already on Ethereum at
0xc404….
PoC path (test/TectonicTonicOracleManipulation_exp.sol)#
Fork 90,897,109, prank as position 0x2dc6…, call:
tUSDC.borrow(55_000_000e6)tUSDT.borrow(45_000_000e6)
output.txt (offline anvil):
Oracle TONIC underlying price (1e18): 0.000002076321000000
tTONIC collateral factor: 0.200000000000000000
Position tTONIC collateral: 309201610258517.41101656
Account liquidity (USD 1e18): 136835847.149861835932153050
USDC borrowed (profit): 55000000.000000
USDT borrowed (profit): 45000000.000000
[PASS] testExploit()
Diagrams#
Remediation#
- Delist or set CF = 0 for thin governance tokens; Tectonic’s own docs warned about low-liquidity oracle risk.
- Prefer manipulation-resistant oracles (bounded TWAP, multi-venue median with hard deviation caps, circuit breakers on >X% moves).
- Add borrow caps and supply caps tight enough that a full mark attack cannot clear eight-figure cash.
- Pause / guardian path for oracle anomalies (Cronos halt contained bridging but is not a substitute for protocol-level guards).
How to reproduce#
# Offline (preferred)
cd /workspaces/RustroverProjects/audits/evm-hack-registry
anvil --load-state 2026-08-TectonicTonicOracleManipulation_exp/anvil_state.json \
--port 8561 --chain-id 25 &
cd 2026-08-TectonicTonicOracleManipulation_exp
TECTONIC_FORK_URL=http://127.0.0.1:8561 forge test --match-test testExploit -vvvvv
# Or via shared runner once registered
_shared/run_poc.sh 2026-08-TectonicTonicOracleManipulation_exp -vvvvv
# Online archive fork
CRONOS_RPC_URL=https://cronos.drpc.org forge test --match-test testExploit -vvv
Note: Official https://evm.cronos.org returned unhealthy during the halt window; https://cronos.drpc.org and https://cronos-evm-rpc.publicnode.com served archive state for this build.
Reference: https://x.com/GoPlusSecurity/status/2094268398662537542
Sources & further analysis#
Reproductions & code
- Standalone PoC + full trace: 2026-08-TectonicTonicOracleManipulation_exp (evm-hack-registry mirror).
- Attack transaction: view on explorer.
Alerts & third-party analyses
- Original alert / thread: post on X.
- Web3Sec X hacked database: search.
- Rekt leaderboard: search.
- Solodit incident search: search.
These dashboards index community alerts tweets, post-mortems, and independent write-ups. Reach them through the protocol name above to cross-check this reproduction against other analyses.