# setVoteFactor() does not change existing supply of votes. As a result, some may be unable to withdraw.

setVoteFactor changes voteFactor without adjusting already-minted vote tokens, so raising it makes prior initializers unable to burn enough votes and withdraw.

- Payout: Contest reward
- Severity: medium
- Program: Tokensoft
- Credited: 0xDjango
- Disclosed: 2023-06-30
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-06-tokensoft-judging/issues/55
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-06-tokensoft%3AM-1
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** AdvancedDistributor claim contract (ERC20Votes voting tokens)
**Root cause:** Vote tokens are minted at distribution-record initialization using the then-current voteFactor, but _executeClaim burns tokensToVotes(_claimed) using the current voteFactor; changing voteFactor leaves minted supply inconsistent with burn requirements.
**Steps:**
1. Owner sets voteFactor=1 and creates airdrop of 1000 tokens per user.
2. Users call initializeDistributionRecord(); each is minted 1000 vote tokens.
3. Owner calls setVoteFactor(2).
4. Airdrop tokens vest; user calls executeClaim().
5. _executeClaim burns tokensToVotes(claimed)=2000 vote tokens but user only holds 1000, so burn reverts and withdrawal is blocked.
**How found:** Code reading: noticed setVoteFactor only assigns the variable without touching existing vote-token supply, while _initializeDistributionRecord mints and _executeClaim burns using tokensToVotes with the live voteFactor, implying a mismatch after any change.
**Exploitation:** Not an external attack; owner-triggered misconfiguration. Raising voteFactor after initialization permanently blocks withdrawals for early initializers since vote tokens cannot be minted/burned to correct the skew; owner must sweep and manually redistribute.
**Insight:** When a config parameter scales a minted/burned derivative token, check that changing the parameter retroactively reconciles already-minted balances; asymmetric mint-at-init vs burn-at-claim with a mutable factor is a classic lock vector.
