Mure's $11.7K Loss and How Olympix Would Have Prevented It
At 04:04:47 UTC on May 21, 2026, a Gnosis Safe on Ethereum lost 4,848,683.80 QUEST tokens in a transaction it never signed. The Safe had approved Mure's distribution contract to move its QUEST, which is exactly what a distribution contract needs to pay out claims. The attacker used that approval to have MureDistribution pull the whole balance to a contract they controlled, swapped it on Uniswap into 11,702.88 USDC and then into 5.45 WETH, and unwrapped it into ETH, all inside the same transaction.
MureDistribution checked a signature on every claim, and the check itself ran correctly. What failed was the lookup that decided whose signature counted, because the contract asked the caller to supply it.
What MureDistribution Was Supposed to Do
Mure describes itself as a suite of smart contracts for fundraising, payments and distribution, with distribution covering airdrops and claims. MureDistribution is the piece that pays out. A project that wants to distribute tokens approves the contract to spend from a holding address, which the code calls the repository, and recipients submit a signed distribution record to claim their share.
That record carries the details of the payout: which token, which repository it comes from, how much, the pool it belongs to, and a source contract that describes the pool. The signature on the record is what's meant to stop anyone from writing their own payout. If the pool's authorized signer didn't sign the record, the claim should fail.
A Signer Chosen by the Claimant
The implementation behind the MureDistribution proxy at the time of the exploit, set in March 2024 and published as verified source, handled claims in an internal function called _distribute. These are its opening lines, copied from the verified source:
The signer that _verifySignature checks against comes from poolState.signer, and poolState comes from calling distribution.source, an address taken straight from the record the claimant submits. The only gate on that address, in the distributable modifier, is an ERC-165 check that the source says it supports the PoolMetadata interface. Any contract can say that.
Contract signers exist for good reasons. Smart wallets and multisigs can't produce an ordinary ECDSA signature, so the ERC-1271 standard lets a contract confirm a signature on its own terms, and SignatureChecker supports both kinds so that a pool run from a Safe can still authorize claims. That flexibility is safe only when the contract being asked is one the protocol chose. In MureDistribution, the claimant chose it.
Once the signer is whatever the source reports, the signature check stops meaning anything. _verifySignature uses OpenZeppelin's SignatureChecker, which accepts a contract as a signer and asks that contract whether the signature is valid. According to Defimon, the attacker passed in a contract they controlled as the signer source, the check called it, and it answered yes. From there _transferAssets called transferFrom on the token, moving the requested amount out of the repository named in the record to the recipient, and the repository could be any address that had approved the contract.
One Transaction, One Approval
The attacker's wallet sent a single contract-creation transaction, and the attack ran during deployment. Inside it, 4,848,683.80 QUEST moved from the Safe to an attacker-controlled contract through MureDistribution, which had the Safe's approval. The QUEST went through the Uniswap V3 router into 11,702.88 USDC, the USDC went into 5.45 WETH, and the WETH was unwrapped into ETH.
Defimon describes the exposure as covering any address that had pre-approved the MureDistribution proxy, so the risk reached every holder with an outstanding approval to it. In this transaction, the one repository drained was the Safe, and the on-chain swap values its loss at 11,702.88 USDC.
Five days later, on May 26, the proxy was upgraded to a new implementation. The new code verifies signatures against a signer held in the contract's own storage, set through a reinitialize function, so a claimant can no longer supply it. As of November 6, 2026, Mure hadn't published a post-mortem.
The Trust Boundary in One Line
Every signature scheme depends on two things, a correct cryptographic check and a trustworthy answer to the question of whose key counts. MureDistribution got the first right and handed the second to the person making the claim. The ERC-165 check made the source look validated, but it only confirmed that the contract could answer the question, never that its answer came from Mure.
The same shape shows up whenever a contract reads its own authorization rules from an address the caller provides, whether that's a signer, an oracle, a fee recipient or a registry. The fix in the upgraded implementation is the general one, keeping the authority inside the contract, where only an administrator can change it.
How Olympix Would Have Caught the Borrowed Signer
Olympix models a contract as states, transitions and entry points, and it starts by asking which entry points can move value. In MureDistribution, that's the claim path, which ends in a transferFrom against an arbitrary repository. Olympix's static analysis would have surfaced the signal sitting right above that transfer: the address whose signature authorizes the payout is read from an external call to a contract the caller supplies, guarded only by an interface check.
That signal points to the invariant the contract exists to enforce. Tokens should leave a repository only when the pool's real authorized signer has signed the record. BugPoCer would have run Counterexample-Guided Invariant Refutation against that rule, working outward from the distribution contract and searching for a sequence of calls that moves an approved holder's tokens without a signature from Mure's signer.
The sequence it would have found is short. A caller deploys a contract that reports support for PoolMetadata and names itself as the pool's signer, submits a record that points at that contract and at a repository holding an approval, and receives the repository's tokens. BugPoCer would have returned that as a counterexample with the minimal conditions, an approval to MureDistribution and a self-reporting source, plus a generated Forge test that replays it. That test would have been the May 21 drain, produced in development, before any repository approved the contract.
What Builders Can Take From Mure
A signature check is only as strong as the lookup that tells it whose signature to trust. When that lookup takes an address from the caller, the caller gets to pick the answer, and an interface check doesn't change that. Treat every address in user-supplied data as untrusted until the contract has matched it against something it already holds. For a distribution contract, that means the pool's signer, the list of valid sources and the repositories that can pay out all live in storage the contract controls, and a claim record only ever references them.
To see how Olympix maps the authorization paths in your own contracts and returns a runnable counterexample for each one that breaks, book a technical walkthrough.
On-Chain References
Exploit tx (May 21, 2026, 04:04:47 UTC, block 25141107): 0xb830...b798
Attacker EOA: 0x0809...2156
Contract created by the exploit tx: 0x2B89...7F63
Contract that received the QUEST: 0x26e5...D467
Victim Safe (repository that had approved the proxy): 0x29b0...cAc7
MureDistribution proxy: 0x3650...4D8a
Implementation at the time of the exploit: 0xEc9C...4137
Upgrade tx (May 26, 2026): 0x81e1...413f
Implementation after the upgrade: 0xc35c...7cd8
More post-mortems
See every post-mortem →See what Olympix finds on your own code
Send us a repo that's already been audited, and we'll run Olympix at the same commit and show you what comes back.




