TORQUE

Evidence

Planted-bug methodology

Tests that pass prove little on their own. To show the suite catches real mistakes, a published harness plants one bug at a time in the contracts, runs the full suite, records whether anything failed, and restores the source.

Result: 24 of 25 planted bugs caught. Re-run on 2026-10-03 on commit 8b698f6; same result as the first run.

How it works

script/planted-bugs.sh in the repo:

  1. Copies src/TorqueMarket.sol and src/TorqueVault.sol aside.
  2. For each mutation, replaces one exact piece of source text (it fails loudly if the text is not found, so a mutation can never silently do nothing).
  3. Runs every unit, adversarial and invariant test, without the fork tests.
  4. Counts failing unit/adversarial tests and failing invariants. If both are zero, the bug survived.
  5. Restores both files and moves to the next mutation.
LOG=research/planted-bugs.log ./script/planted-bugs.sh

The latest log is research/planted-bugs.log.

The 25 mutations

#Bug plantedResult
M1Knock-out ignores a stale feedcaught
M2No utilisation capcaught
M3aVault cap check in _deposit removedsurvived
M3bVault cap removed (both checks)caught
M4Loans marked at face valuecaught
M5Vault shorted on knock-outcaught
M6Open allowed on a stale feedcaught
M7Financing not accruedcaught
M8Knock-out level without the 5% buffercaught
M10Close allowed while underwatercaught
M11Open fill guard removedcaught
M12Open-interest cap removedcaught
M13Opens skip the pool checkcaught
M14Knock-outs skip the pool checkcaught
M15LP flows skip the pool checkcaught
M16Loan mark ignores the pool averagecaught
M17Strict knock-out rule (no recency exemption)caught
M18Agreement band ten times widercaught
M19Tick math sign flippedcaught
M20Unwind without the dead-feed checkcaught
M21LP exits ignore price checks with loans opencaught
M22Dead-feed clock never resets on reportcaught
M23Feed read reverts instead of "no price"caught
M24Open does not clear the dead-feed clockcaught
M25Reentrancy guard removed from open and closecaught

The one survivor

M3a removes one of two identical cap checks: the vault cap is enforced in maxDeposit / maxMint and again in _deposit. With one copy gone, behaviour is unchanged, so no test can fail. M3b removes both, and it is caught. A survivor that changes nothing is the expected outcome for a deliberately redundant check.