# permitAndMulticall() May Be Used to Steal Funds Or as a Denial Of Service if _from Is Not The Message Sender

permitAndMulticall executes multicall as msg.sender not _from, letting an attacker front-run a user's permit to burn their nonce (DoS) or redirect delegation via updateDelegatee.

- Payout: Audit contest
- Severity: medium
- Program: PoolTogether
- Found by: kirk-baird
- Disclosed: 2022-04-19
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2022-02-pooltogether#m-01
- Library page: http://bugbountylibrary.com/r/c4%3A2022-02-pooltogether%3AM-01
- Tags: area:web3 domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic vuln:dos

**Target:** TWABDelegator / PermitAndMulticall Solidity contract
**Root cause:** _permitAndMulticall permits _from but then runs _multicall() with delegatecalls executed in the context of msg.sender, so state-changing calls act on the caller rather than _from.
**Steps:**
1. Attacker observes a pending permitAndMulticall() call with a victim's _from and permit signature.
2. Attacker front-runs with the same signature, consuming the victim's permit nonce so the victim's _permitToken.permit() reverts (DoS).
3. Alternatively attacker calls permitAndMulticall with their own _data invoking updateDelegatee, passing the victim's _delegator param, since delegation is computed from the passed _delegator rather than msg.sender.
4. Victim's delegation is redirected to the attacker's address, improving attacker's odds of winning.
**How found:** Code review of _permitAndMulticall: noticed _multicall() delegatecalls run as msg.sender while permit is for _from, then traced which functions (transfer, unstake, updateDelegatee) key off msg.sender vs passed params.
**Exploitation:** Front-run the victim's permitAndMulticall transaction to consume the one-time permit nonce, causing the victim's call to revert; or craft _data calling updateDelegatee with the victim's _delegator to redirect their delegation to an attacker-controlled delegatee.
**Insight:** When a permit+multicall helper separates the permit owner (_from) from the multicall executor (msg.sender), audit every delegatecalled function for whether it derives identity from msg.sender or from a caller-supplied parameter; the mismatch is where the bug lives.

