# Old permissions in handlerCan mapping are still attached to the safeHandler of a transferred safe

ODSafeManager keeps stale handlerCan permissions on a safeHandler after the safe is transferred, letting the previous owner bypass handlerAllowed checks on the new owner's safe.

- Payout: Contest reward
- Severity: medium
- Program: Open Dollar
- Credited: MrPotatoMagic
- Disclosed: 2023-12-20
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-10-opendollar-findings/issues/382
- Library page: https://bugbountylibrary.com/r/c4%3A2023-10-opendollar%3AM-02
- Tags: domain:web3 impact:integrity kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** ODSafeManager / Vault721 ERC721 safe transfer
**Root cause:** handlerCan is keyed only by safeHandler, not owner, and transferSAFEOwnership never clears it, so approvals granted by the prior owner persist after the safe moves to a new owner.
**Steps:**
1. Owner A calls `allowHandler(X, 1)` on their safeHandler, setting `handlerCan[safeHandler][X]=1`.
2. Owner A transfers the safe NFT via `safeTransferFrom` on Vault721.
3. `_afterTokenTransfer` calls `transferSAFEOwnership`, which updates `_safeData[_safe].owner` but leaves `handlerCan` untouched.
4. Address X still passes `handlerAllowed()` for the safeHandler now owned by B.
**How found:** Code reading of ODSafeManager: noticed handlerCan keyed only by safeHandler and that transferSAFEOwnership updates ownership but not the permission mapping, unlike safeCan which includes owner.
**Exploitation:** Judge notes a malicious prior owner could call `quitSystem()` using their own safe and the new owner's safeHandler to shift debt onto the new owner, but the report itself does not elaborate an end-to-end exploit.
**Insight:** When auditing permission mappings, check whether the key includes the current owner; any mapping keyed by a transferable identity (handler, NFT, account) must be reset or re-keyed on transfer, and compare against sibling mappings that already do this correctly.
