# Two address tokens can be withdrawn by the payer even when the stream has began

Stream.sol's rescueERC20 only blocks the stream token by address, so a two-address token (e.g. Synthetix proxy) lets the payer drain the streamed balance.

- Payout: Contest reward
- Severity: medium
- Program: Nounsdao
- Credited: DecorativePineapple
- Disclosed: 2022-11-23
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2022-11-nounsdao-judging/issues/52
- Library page: https://bugbountylibrary.com/r/sherlock%3A2022-11-nounsdao%3AM-4
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:medium tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** Stream.sol ERC20 streaming contract
**Root cause:** rescueERC20 guards only with `tokenAddress == address(token())`; two-address tokens (proxy + implementation) pass a different address that still transfers the streamed token balance.
**Steps:**
1. Create a stream funded with a two-address token such as Synthetix ProxyERC20 (sUSD).
2. As payer, call `rescueERC20(proxyOrImplAddress, streamBalance)` using the address that differs from `address(token())`.
3. Address check passes; `safeTransfer` moves the streamed tokens to the payer, emptying the contract.
**How found:** Code reading of rescueERC20's single address-equality guard, recognizing that proxy-style tokens expose two addresses for the same balance.
**Exploitation:** Payer of a stream funded with a two-address token calls rescueERC20 with the alternate token address to withdraw the full deposited amount, leaving recipient unable to withdraw accrued stream.
**Insight:** When a contract guards a token by address equality, check whether the token is a proxy/dual-address token (Synthetix ProxyERC20, upgradeable proxies) where a different address still controls the same balance; prefer balance-delta checks.
