# Blocked follower can keep follow with batchMigrateFollows

LensV2Migration.batchMigrateFollows skips block checks, letting a blocked follower migrate a V1 follow NFT and remain following the blocker.

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

**Target:** LensV2Migration / FollowNFT.tryMigrate migration path
**Root cause:** FollowNFT.tryMigrate validates ownership and migration state but never checks whether followerProfileId is blocked by idOfProfileFollowed, so migration re-establishes a follow the blocker had revoked.
**Steps:**
1. Owner of profile 8 calls `hub.setBlockStatus(idOfProfileFollowed, followerProfileIds, blockStatuses)` with blockStatuses all true.
2. Confirm `hub.isBlocked(followerProfileIds[0], idOfProfileFollowed)` returns true.
3. Anyone calls `hub.batchMigrateFollows(followerProfileIds, idsOfProfileFollowed, followTokenIds)` with the blocked follower's V1 follow token IDs.
4. tryMigrate burns the follow NFT, sets followerProfileId and increments _followerCount without a block check.
5. Assert `FollowNFT(followNFTAddress).isFollowing(followerProfileIds[0])` returns true despite the block.
**How found:** Reading the migration path, noticed tryMigrate's checks cover already-migrated, wrong profile, nonexistent token, and owner mismatch, but no isBlocked check, then wrote a fork PoC blocking followers before migration.
**Exploitation:** A blocked follower (or anyone) calls the permissionless batchMigrateFollows with the follower's profile ID, the blocker's profile ID, and the V1 follow token ID; tryMigrate accepts since the follower still owns both NFTs, restoring the follow relationship the blocker had severed.
**Insight:** When a protocol adds a new state-transition path (migration) alongside an existing access-control feature (blocking), check that the new path re-applies every restriction the old follow path enforced; block lists are easy to forget in migration code.

