# Malicious early user/attacker can malfunction the contract and even freeze users' funds in edge cases

First depositor locks 1 wei, inflates _pointsPerUnit via updateDistribution, causing overflow that blocks other users' lock/unlock and freezes funds.

- Payout: Audit contest
- Severity: high
- Program: XDEFI
- Found by: WatchPug
- Disclosed: 2022-02-10
- Write-up quality: 8/10
- Original: https://github.com/code-423n4/2022-01-xdefi-findings/issues/156
- Library page: https://bugbountylibrary.com/r/c4%3A2022-01-xdefi%3AH-01
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:dos

**Target:** Solidity staking/distribution contract (XDEFIDistribution.sol)
**Root cause:** _pointsPerUnit is scaled by _pointsMultiplier (2**128) and divided by totalUnitsCached; with totalUnits=1 from a 1-wei first lock, a large donation makes _pointsPerUnit huge, so _pointsPerUnit * units overflows int256 in later lock/unlock math.
**Steps:**
1. Alice `lock(1, 2592000, alice)` as first user; totalUnits=1, units=1
2. Alice transfers `170141183460469 wei` XDEFI to contract and calls `updateDistribution()`; `_pointsPerUnit += (170141183460469 * 2**128) / 1`
3. Bob `lock(1_100_000e18, 2592000, bob)` reverts with `_toInt256Safe failed` (overflow)
4. Bob locks `1_000_000e18`; rewarder sends `250_000e18` and calls `updateDistribution()`
5. After 30 days Bob `unlock(nft2, bob)` reverts with `_toInt256Safe failed`
**How found:** Code review of updateDistribution() math: noticed _pointsPerUnit divides by totalUnitsCached which can be 1, and that _pointsMultiplier=2**128 leaves little headroom before int256 overflow in _pointsPerUnit*units.
**Exploitation:** Attacker needs only 1 wei to become first depositor, then donates a modest amount and permissionlessly calls updateDistribution() to blow up _pointsPerUnit; subsequent users' lock/unlock arithmetic overflows, bricking the contract and trapping deposits.
**Insight:** In share/points accounting contracts, check the first-depositor state (totalUnits=1) and whether a permissionless donation+update can push the accumulator near type limits; fixed-point multipliers near 2**128 leave almost no overflow headroom.
