Moolam attack: receiver-replay-and-wrong-chain REFUSED run 2026-09-28T07:54:34.113Z command npm run prove:receivers network Monad mainnet, chain 143 registry 0xa19188801E5DC93CD925884d73e4DaFc2bcb80C0 covered by Foundry tests, not by a mainnet transaction: only the CRE wallet's key can reach the check receiver 0x4aD66c77f961884E9e866EEEc3EafF1EdB5BAa95, the public SimulationReceiver forwarder on chain 0x9eF6468C5f37b976E57d52054c693269479A784d, Chainlink's MockKeystoneForwarder sending wallet 0xC79620AF233a4434b03f6B57239F8A9E71B3C178, fixed in the constructor with no setter last report seen 1790524180 for passport 0x3d41c6960a1486e29a85febcdfe282fafcbe33b558fd47578f99cb2f55f70c91 onReport refuses anything that is not the forwarder before it decodes a byte, which is the attack in report-from-fake-forwarder.txt and it is executed live. The mock forwarder itself checks no signature and anyone may call it, so the door that matters here is the next one: _processReport refuses first any transaction the sending wallet did not sign. The replay and wrong chain checks sit behind it, so reaching them on mainnet would mean holding the CRE wallet's key. An outsider cannot, and that is the point. The holder of that key can write any verdict through this receiver, and the threat model names that as a non-goal. packages/contracts/test/SimulationReceiver.t.sol, run with npm test in packages/contracts: test_theFloorIsStrictlyMonotonic StaleReport test_aReportBuiltForAnotherChainIsRefused WrongChain test_aReportFromAnyOtherOriginIsRefused WrongSendingWallet The first two act as the sending wallet and expect the named error on the same report sent twice, on an older one, and on one built for another chain. The third sends as a stranger and expects nothing written. packages/contracts/test/fork/SimulationReceiver.fork.t.sol replays real mainnet report calldata through the real mock from a stranger and from the policy owner, and nothing is written either time.