# Wrong implementation of withdrawAdminFees() can cause the adminFees to be charged multiple times and therefore cause users' fund loss

Connext SwapUtils.withdrawAdminFees never zeroes adminFees after transfer, letting the admin repeatedly withdraw the same fees and drain LP funds.

- Payout: Audit contest
- Severity: high
- Program: Connext
- Found by: WatchPug
- Disclosed: 2022-10-17
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-06-connext-findings/issues/202
- Library page: https://bugbountylibrary.com/r/c4%3A2022-06-connext%3AH-02
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:fee-bypass

**Target:** Solidity AMM swap library (SwapUtils) admin fee withdrawal
**Root cause:** withdrawAdminFees transfers self.adminFees[i] but never resets the accumulator to zero, so the recorded fee balance persists and can be withdrawn again on each call.
**Steps:**
1. Read SwapUtils.sol withdrawAdminFees loop: balance = self.adminFees[i]; if balance != 0 token.safeTransfer(to, balance).
2. Note no assignment self.adminFees[i] = 0 after transfer.
3. Call withdrawAdminFees repeatedly (admin or via any path invoking it); each call re-transfers the same accumulated fee amount.
4. Fix: set self.adminFees[i] = 0 before safeTransfer.
**How found:** Code reading of the fee-withdrawal function revealed the accumulator was read and transferred but never cleared, an accounting state-reset omission.
**Exploitation:** Admin (or anyone triggering the withdrawal path) calls withdrawAdminFees multiple times; each invocation re-sends the full accumulated adminFees balance to the recipient, draining pooled LP tokens beyond fees actually earned.
**Insight:** In fee/accumulator withdrawal functions, verify the stored balance is zeroed before or atomically with the transfer; a read-without-reset lets the same recorded amount be paid out repeatedly.

