Try tobreak it.
35 real attacks on Adag's live contracts, AdagBills and the loan guard, simulated on Arc mainnet's current state: the real loan, the real bills, the real bitcoin price. Nothing is signed and nothing is sent.
About a minute. Each simulation waits its turn so Arc's public node is never flooded.
35
Attacks armed
01 · Paying bills
Against the current AdagBills and the demo wallet's real Morpho loan.
- A1
A stranger with money pays an already-paid bill a second time.
What should stop it · A bill can be paid once. Only an open bill can be paid.
Armed - A2a
Close the loan outside Adag, then re-borrow the same debt against a quarter of the bitcoin.
What should stop it · Morpho's own 86% line stops it before Adag is reached.
Armed - A2b
Close the loan, then re-borrow the same debt against bitcoin worth 60%, which Morpho allows, and pay a bill.
What should stop it · Adag sees the pledge shrank since its last check, so the 40% check runs.
Armed - A3
Borrow up to half the bitcoin's value and pay a new bill in the same signature.
What should stop it · Adag sees new debt, so the 40% check runs.
Armed - A4
Pay a bill from cash, then borrow up to 60% after Adag's step in the same batch. Next block, pay another bill.
What should stop it · Allowed by design, caught on the next payment.
Armed - A5
A supplier pays its own bill.
What should stop it · The payer can never be the payee.
Armed - A6.1
A stranger writes a bill payable in cirBTC.
What should stop it · Bills are in USDC or EURC only.
Armed - A6.2
A stranger writes a bill payable in WETH.
What should stop it · Bills are in USDC or EURC only.
Armed - A6.3
A stranger writes a bill payable in a made-up token.
What should stop it · Bills are in USDC or EURC only.
Armed - A6.4
A stranger writes a bill for zero.
What should stop it · A bill must be for more than zero.
Armed - A6.5
A stranger writes a bill with a 141-byte invoice reference.
What should stop it · References are 140 bytes at most.
Armed - A7a
A stranger cancels a supplier's open bill.
What should stop it · Only the supplier who wrote a bill can cancel it.
Armed - A7b
The supplier cancels a bill after it was paid.
What should stop it · Only an open bill can be cancelled.
Armed - A8
Pay a bill without approving Adag to move the USDC.
What should stop it · The token refuses, and the whole batch undoes itself.
Armed - A9aSimulated price drop · a mock oracle, 25% lower
Bitcoin drops 25%. Pay a new bill from cash, with no new borrowing.
What should stop it · Allowed on purpose: no new debt, so nothing to check. A price drop never blocks a cash payment.
Armed - A9bSimulated price drop · a mock oracle, 25% lower
Bitcoin drops 25%. Borrow one cent more and pay the same bill.
What should stop it · New debt, so the 40% check runs.
Armed
02 · Recording an existing loan
Recording (enrol) saves a loan the payer already had, so that payer's next payments are checked against it.
- E1
Record the loan with enrol and pay a bill from cash in the same batch.
What should stop it · A payer who enrolled in this block is refused, so a loan cannot be recorded and spent at once.
Armed - E2
Borrow up to 60%, record that debt with enrol, and pay a bill, all in one batch.
What should stop it · The same-block refusal: new debt cannot be enrolled and spent at once.
Armed - E3
A stranger calls enrol, hoping to overwrite the demo payer's recorded loan, then the payer pays.
What should stop it · enrol takes no arguments and only ever writes the caller's own record.
Armed - E4
Enrol in one block; in the next, close the loan outside Adag, re-borrow it against bitcoin worth 60%, and pay.
What should stop it · The pledge fell below the enrolled one, so the 40% check runs.
Armed - E5
Borrow up to 60% outside Adag and enrol it; in the next block, pay a bill from cash.
What should stop it · Allowed by design: enrol accepts the loan as it stands, and only the payer's own position carries the risk.
Armed
03 · The loan guard
Against the live AdagGuard. Every loan guard row starts from a simulated premise: the demo payer borrows on Morpho until the loan sits at 38.00%, above the 35% trigger. Nothing of AdagGuard, Morpho or the oracle is overwritten.
- G6
Call protect three times at the same price: twice in one block, once in the next.
What should stop it · Each protect repays only what brings the loan back to the target, so a repeat finds nothing to do.
Armed - G1
Pull more than the payer approved: the loan needs more than the 0.10 USDC approval, and protect runs twice.
What should stop it · The approval is the lifetime ceiling, and protect caps at it.
Armed - G2a
Protect the payer's loan through the other real USDC/cirBTC market on Morpho.
What should stop it · AdagGuard accepts only its two fixed market ids, checked against Morpho.
Armed - G2b
Set a rule and call protect with a market id one hex digit away from Adag's.
What should stop it · A near miss is a different id, and it is refused.
Armed - G2c
Protect the payer in the EURC market, where they have no loan and no rule.
What should stop it · Each market repays only its own loan, and only for a real, triggered rule.
Armed - G3
A stranger calls protect while the loan sits under the payer's 50% trigger.
What should stop it · Protect acts only at or above the trigger; otherwise nothing moves and nothing is emitted.
Armed - G4
The payer's rule expires 60 seconds after it is set; a stranger calls protect at that second.
What should stop it · An expired rule is inert.
Armed - G5a
A stranger clears the payer's rule.
What should stop it · Rules are keyed by the sender; nobody can name another wallet.
Armed - G5b
A stranger sets a rule (80% / 1%) hoping it lands on the payer.
What should stop it · setRule writes only the sender's own rule.
Armed - G7
The payer's wallet holds only 0.05 USDC when the loan needs more.
What should stop it · Protect never pulls more than the wallet holds, and does not revert.
Armed - G8Simulated price crash · a mock oracle at zero
Bitcoin crashes to zero. Protect with a 2 USDC approval against the whole loan.
What should stop it · The repay is capped at the debt rounded down, so Morpho's share maths cannot underflow.
Armed - G9aSimulated price crash · a mock oracle at zero
Bitcoin crashes to zero. Protect a payer who approved 1 USDC but has no rule.
What should stop it · No rule, no action, even at a zero price.
Armed - G9b
Protect a wallet with no loan and no rule.
What should stop it · Nothing to repay, nothing moves.
Armed - G10
Call the admin functions a drain would need: transferOwnership, withdraw, rescue, pause and upgradeToAndCall.
What should stop it · No owner, pause, rescue or upgrade exists; only setRule, clearRule and protect change state.
Armed