# Missing recipient validation in payout paths

Push transfers to owner- or user-chosen addresses that can revert or be invalid, blocking settlement

_Area: DeFi accounting and math bugs. Seen in 2 disclosed reports; latest 2026-03-13. Updated 2026-10-29._

## How it works
A payout path assumes the recipient address it is given is valid and will accept the transfer. That assumption breaks in two ways: the address can be a contract-only target that rejects plain EOAs, or it can be an address the token issuer blocks (USDC/USDT blocklists). When the protocol *pushes* funds to that address, the transfer reverts, and the whole settlement step reverts with it. The funds are not lost to the attacker directly; instead the legitimate path is frozen, and a second party (a liquidator, a peer, a caller) can then take value through the now-unusable path.

## Where it shows up
- Payee derived from `ownerOf(tokenId)` or any user-controlled field, then used as the `to` of an ERC20 `transfer`/`transferFrom` [E1](https://bugbountylibrary.com/r/c4%3A2023-01-astaria%3AH-01.md).
- Refund helpers that call a contract-only function (e.g. `functionCallWithValue`) on a recipient that may be an EOA [E2](https://bugbountylibrary.com/r/c4%3A2025-02-recall%3AM-02.md).
- Token `transferFrom`/`transfer` that never checks `to != address(0)` or that `to` is a sane account [E3](https://bugbountylibrary.com/r/dhl%3A20240215-miner.md).
- Comments claiming a path is "handled elsewhere" while the code still executes it [E2](https://bugbountylibrary.com/r/c4%3A2025-02-recall%3AM-02.md).
- Any loop or callback that re-enters a transfer with an attacker-chosen destination [E3](https://bugbountylibrary.com/r/dhl%3A20240215-miner.md).

## How to review
The invariant: every push-transfer recipient must be an address that is guaranteed to accept the transfer, or the transfer must be pull-based. Check each payout site: who controls the recipient, can it be a blocklisted or codeless address, and does a revert there block a critical path (repayment, auction, refund, swap)? Prefer pull-payment or try/catch with a fallback sink. For tokens, require explicit `to` validation.

## Variants seen
- Bearer-asset payee set to a blocklisted address freezes repayment and auction, letting a colluding liquidator seize collateral [E1](https://bugbountylibrary.com/r/c4%3A2023-01-astaria%3AH-01.md).
- Refund to an EOA reverts because the helper requires contract code, trapping value in the gateway [E2](https://bugbountylibrary.com/r/c4%3A2025-02-recall%3AM-02.md).
- Missing `dst` validation in `transferFrom` enables pool drain via swap-callback loops [E3](https://bugbountylibrary.com/r/dhl%3A20240215-miner.md).

## Impact and severity
High: frozen settlement leading to collateral seizure [E1](https://bugbountylibrary.com/r/c4%3A2023-01-astaria%3AH-01.md), stuck user funds [E2](https://bugbountylibrary.com/r/c4%3A2025-02-recall%3AM-02.md), and full pool drain [E3](https://bugbountylibrary.com/r/dhl%3A20240215-miner.md). Worse when the payout sits on a critical path with no alternate recipient.

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2023-01-astaria%3AH-01.md
- E2: https://bugbountylibrary.com/r/c4%3A2025-02-recall%3AM-02.md
- E3: https://bugbountylibrary.com/r/dhl%3A20240215-miner.md
