# The first disputer might lose funds although his dispute is valid

disputeTree() allows overwriting an active disputer, so a frontrunner's dispute replaces the honest disputer and resolveDispute(true) refunds the wrong party.

- Payout: Contest reward
- Severity: high
- Program: Angle Protocol
- Credited: auditor0517
- Disclosed: 2023-08-09
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-06-angle-findings/issues/23
- Library page: https://bugbountylibrary.com/r/c4%3A2023-06-angle%3AH-02
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:business-logic vuln:race-condition

**Target:** Merkl Distributor contract disputeTree/resolveDispute
**Root cause:** disputeTree() lacks a check that disputer == address(0), so a second caller overwrites the stored disputer and disputeAmount accounting; resolveDispute refunds only the last disputer.
**Steps:**
1. Honest user calls `disputeTree(reason)` transferring `disputeAmount` of disputeToken to the contract; disputer = honest.
2. Governor prepares `resolveDispute(true)`.
3. Attacker frontruns with `disputeTree(reason)` transferring disputeAmount; disputer = attacker.
4. `resolveDispute(true)` executes: `safeTransfer(disputer, disputeAmount)` refunds attacker, `_revokeTree()`; honest disputer's funds remain stuck.
**How found:** Code review of disputeTree/resolveDispute: noticed disputeTree has no guard against an existing disputer while resolveDispute refunds only the single stored disputer address.
**Exploitation:** Attacker monitors mempool for resolveDispute(true), frontruns with disputeTree() paying disputeAmount, then receives the refund meant for the honest disputer while the honest disputer loses their deposit; requires governance to manually recover via recoverERC20.
**Insight:** When a contract stores a single 'current actor' (disputer, challenger, claimant) and refunds that address, check whether the setter can be re-invoked to overwrite it before resolution — frontrunning the resolve call redirects the refund.
