# Caller-supplied account not bound to owner

Handler acts on caller-supplied account or position without binding it to caller or canonical record

_Area: Smart contract access control and control flow. Seen in 3 disclosed reports; latest 2025-02-18. Updated 2026-10-30._

## How it works
A handler receives an account, position, or parameter from the caller and acts on it, but never proves that this input belongs to the caller or matches the canonical record. The authorization check is either absent or keyed on the wrong thing, so the caller can point the handler at someone else's resource, or at a resource whose stored data diverges from what the core actually uses. The broken assumption is that "the caller passed it, so it is theirs" or "the companion instruction exists, so it applies here."

## Where it shows up
- Companion-instruction validation by presence (sysvar instructions) rather than by matching account keys [E1](https://bugbountylibrary.com/r/c4%3A2024-04-lavarage%3AH-02.md)
- Periphery caches a parameter the core silently overrides [E2](https://bugbountylibrary.com/r/sherlock%3A2024-02-smilee-finance%3AM-2.md)
- Access-control mappings keyed owner=>resource instead of resource=>owner [E3](https://bugbountylibrary.com/r/c4%3A2024-12-secondswap%3AM-04.md)
- Handlers taking a position/account argument with no owner or canonical-key equality check [E1](https://bugbountylibrary.com/r/c4%3A2024-04-lavarage%3AH-02.md)[E3](https://bugbountylibrary.com/r/c4%3A2024-12-secondswap%3AM-04.md)

## How to review
For every handler that accepts an account or position argument, find the exact check binding it to the caller and to the canonical record. For caller-bound handlers (E1, E3), the invariant: the acted-on account's owner/creator equals msg.sender (or the authorized party), and any companion instruction's account keys equal the primary instruction's keys. For cached parameters (E2), confirm the stored value equals what the core contract actually consumes. For mappings, confirm the key direction permits exactly one owner per resource.

## Variants seen
- Borrow validated only that an addCollateral instruction existed, not that it targeted the same position; collateral attributed to a different position [E1](https://bugbountylibrary.com/r/c4%3A2024-04-lavarage%3AH-02.md)
- PositionManager stored the user-supplied strike while IG used currentStrike, leaving positions unburnable [E2](https://bugbountylibrary.com/r/sherlock%3A2024-02-smilee-finance%3AM-2.md)
- VestingDeployer mapped owner=>token, letting any token owner act on another owner's plan [E3](https://bugbountylibrary.com/r/c4%3A2024-12-secondswap%3AM-04.md)

## Impact and severity
Led to unbacked borrowing and draining of SOL [E1](https://bugbountylibrary.com/r/c4%3A2024-04-lavarage%3AH-02.md), stuck unburnable funds [E2](https://bugbountylibrary.com/r/sherlock%3A2024-02-smilee-finance%3AM-2.md), and funds pulled from the wrong issuer [E3](https://bugbountylibrary.com/r/c4%3A2024-12-secondswap%3AM-04.md). Severity is high where the mismatch enables direct fund loss; worse when the divergence is silent and persists in stored state.

## Why fixes fail
Presence-only checks look like authorization but authorize the wrong party [E1](https://bugbountylibrary.com/r/c4%3A2024-04-lavarage%3AH-02.md); owner-keyed mappings look like authorization but permit many owners per resource [E3](https://bugbountylibrary.com/r/c4%3A2024-12-secondswap%3AM-04.md). Fixing one call site without correcting the key direction or the binding check leaves the same gap elsewhere.

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2024-04-lavarage%3AH-02.md
- E2: https://bugbountylibrary.com/r/sherlock%3A2024-02-smilee-finance%3AM-2.md
- E3: https://bugbountylibrary.com/r/c4%3A2024-12-secondswap%3AM-04.md
