# SettV3.transferFrom block lock can be circumvented

SettV3._blockLocked checks msg.sender not the token holder, so an attacker using a second account can transferFrom and withdraw in the same block, bypassing the flashloan guard.

- Payout: Audit contest
- Severity: medium
- Program: BadgerDAO
- Found by: cmichel
- Disclosed: 2021-11-05
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-09-bvecvx-findings/issues/49
- Library page: https://bugbountylibrary.com/r/c4%3A2021-09-bvecvx%3AM-01
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** SettV3 vault contract (Solidity)
**Root cause:** _blockLocked() checks blockLock[msg.sender] rather than the account whose tokens are being moved, so transferFrom by a different caller bypasses the lock.
**Steps:**
1. Account A calls deposit; _lockForBlock(A) sets blockLock[A] = block.number.
2. A approves account B to spend its tokens.
3. B calls transferFrom(from=A, to=C, amount); _blockLocked() checks blockLock[B] which is unlocked, so it passes.
4. C calls withdraw() in the same block, bypassing the intended same-block lock.
**How found:** Code reading of _blockLocked() revealed it keys on msg.sender; researcher reasoned that transferFrom moves another account's tokens while the lock check applies to the caller, so a second account circumvents it.
**Exploitation:** Attacker controls accounts A, B, C; deposits from A, uses B to transferFrom A's tokens to C, then C withdraws in the same block, defeating the flashloan-attack guard.
**Insight:** When a same-block/flashloan guard keys on msg.sender, check every path that moves another account's assets (transferFrom, operator/approval flows) — the lock must follow the token holder, not the caller.

