# Users cannot unfollow if they do not own the FollowNFT of the followTokenId used for their profile

Lens FollowNFT unfollow() rejects the profile owner when the follow token is wrapped and owned by another user, permanently blocking unfollow.

- Payout: Audit contest
- Severity: medium
- Program: Lens Protocol
- Found by: MiloTruck
- Disclosed: 2023-12-11
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2023-07-lens#m-03
- Library page: https://bugbountylibrary.com/r/c4%3A2023-07-lens%3AM-03
- Tags: area:web3 domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:evm tech:solidity vuln:access-control vuln:business-logic

**Target:** FollowNFT.sol unfollow() access control
**Root cause:** unfollow() only permits the follow NFT owner, its approved operators, or approved-for-all parties; it omits the unfollowerProfileOwner, unlike the follow path which allows follow approval.
**Steps:**
1. Alice follows target profile, receiving followTokenId, then calls `followNFT.wrap(followTokenId)` and `followNFT.approveFollow(bobProfileId, followTokenId)`
2. Bob calls `hub.follow(bobProfileId, [targetProfileId], [followTokenId], [''])` which succeeds via _followWithWrappedToken follow-approval check
3. Bob calls `hub.unfollow(bobProfileId, [targetProfileId])`
4. unfollow() reverts with `DoesNotHavePermissions()` because Bob is not followTokenOwner nor approved-for-all
**How found:** Compared the permission checks in _followWithWrappedToken (which honors follow approval) against unfollow() (which does not), spotting the asymmetry that lets a user follow but not unfollow.
**Insight:** When a protocol has separate follow/unfollow or grant/revoke paths, diff their authorization checks: an approval that enables one direction often fails to enable the reverse, locking users into state they cannot exit.

