# Unauthenticated callback trusts attacker payload

Callback entrypoints that decode caller data and act without binding caller to a trusted origin

_Area: Smart contract access control and control flow. Seen in 2 disclosed reports; latest 2024-08-06. Updated 2026-10-25._

## How it works
A contract exposes a callback or relay entrypoint meant to be invoked only by a specific protocol, bridge, or router. The code decodes the caller-supplied payload and acts on it (external calls, token moves, settlement state) without checking that the caller is the trusted origin the payload claims to represent. The broken assumption is that reachability implies authenticity: because the entrypoint is only *supposed* to be called by a trusted party, any invocation is treated as trusted. When the trusted party is permissionless (a flash-loan protocol, a bridge, a public router), anyone can reach the callback and supply their own payload.

## Where it shows up
- Callback functions (`onTokenBridged`, `callFunction`, `payCallback`, `retrySettlement`) that decode data and act before any sender check.
- Bridge receivers where the primitive does not expose the original L1 sender.
- Allowance logic that auto-approves the caller when allowance is zero (secondary flaw, seen alongside the callback bug in [E1](https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-hack-analysis-0xbadc0de-mev-bot-september-2022.md)).
- Pay/withdraw callbacks whose funding source is a fixed or attacker-controlled address rather than the caller.
- Permissionless retry/replay functions that set terminal state.

## How to review
For every externally reachable callback, ask: what binds this call to a trusted origin? The invariant: the acting identity (msg.sender, decoded sender, or funding source) must equal the trusted origin the payload claims, verified before any state change or transfer. If the transport cannot authenticate the sender, split authentication from payload (verify token and sender separately). For retries, require that a no-op or zero-cost call cannot flip state to a terminal status.

## Variants seen
- Flash-loan protocol callback reachable permissionlessly; arbitrary encoded calls plus auto-approve on zero allowance drains balance [E1](https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-hack-analysis-0xbadc0de-mev-bot-september-2022.md).
- Bridge receiver callback never validates L1 sender or token; fake staking data redirects incentives [E2](https://bugbountylibrary.com/r/c4%3A2024-05-olas%3AH-02.md).
- Router pay callback pulls from a fixed victim address instead of the caller, repeated across lock iterations [E3].
- Permissionless retry marks settlement Success with zero gas, blocking owner redeem [E4].

## Why fixes fail
Bridge-specific: Omnibridge does not expose the original L1 sender, so a naive sender check in the receiver is insufficient; token and data must be authenticated separately [E2](https://bugbountylibrary.com/r/c4%3A2024-05-olas%3AH-02.md).

## Impact and severity
Direct fund loss: ~$1.46m [E1](https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-hack-analysis-0xbadc0de-mev-bot-september-2022.md), ~$1.4M [E3]; incentive manipulation [E2](https://bugbountylibrary.com/r/c4%3A2024-05-olas%3AH-02.md); asset lock via DoS [E4]. Severity is high when the callback moves tokens or sets terminal state; worse when the trusted caller is permissionless and the payload controls target addresses or amounts.

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-hack-analysis-0xbadc0de-mev-bot-september-2022.md
- E2: https://bugbountylibrary.com/r/c4%3A2024-05-olas%3AH-02.md
