# Staking#_unstake removes votes from wrong person if msg.sender != owner

Staking._unstake deducts voting power from msg.sender instead of the token owner when an approved third party unstakes, trapping the caller's NFT.

- Payout: Contest reward
- Severity: high
- Program: Frankendao
- Credited: cccz
- Disclosed: 2022-10-31
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2022-11-frankendao-judging/issues/30
- Library page: https://bugbountylibrary.com/r/sherlock%3A2022-11-frankendao%3AH-4
- Tags: domain:web3 impact:funds-loss impact:integrity kind:contest platform:sherlock sev:high tech:solidity technique:source-review vuln:access-control vuln:accounting-error vuln:governance

**Target:** Staking.sol unstake function
**Root cause:** _unstakeToken loop removes accumulated lostVotingPower from votesFromOwnedTokens[msg.sender] and getDelegate(msg.sender) rather than the actual token owner, so an approved caller loses votes for tokens they don't own.
**Steps:**
1. User A and User B each stake tokens, 10 votes each.
2. User A calls setApprovalForAll(User B, true).
3. User B calls `unstake([A_tokenId], to)`; msg.sender=B, owner=A.
4. Observe votesFromOwnedTokens[B] -= 10 and tokenVotingPower[delegate(B)] -= 10 while A keeps 10 votes.
5. User B's votes now 0 but token still locked; subsequent unstake underflows, trapping NFT.
**How found:** Code reading of the unstake flow: noticed authorization allows msg.sender != owner, then traced that vote accounting keys off msg.sender instead of ownerOf(_tokenId).
**Exploitation:** Any approved operator unstakes on behalf of an owner; the owner retains voting power while the caller's vote balance is drained, and the caller's own staked NFT becomes permanently un-unstakeable due to underflow.
**Escalation:** Repeated unstake-for-others calls drain a delegate's voting power, enabling vote hijacking or griefing of governance.
**Insight:** When a function permits third-party callers via approvals, audit every state mutation that keys off msg.sender versus the resolved owner — vote/balance accounting is a common mismatch that yields underflow-locked funds.
