# _recalep2pdbalance should be called before p2udtoken.burn/mint, not after

In Goat staking, p2UDtoken mint/burn ran before _reCalEP2PDBalance, so newly minted shares captured global mining rewards they hadn't earned.

- Payout: Contest reward
- Severity: high
- Program: Goat
- Credited: cccz
- Disclosed: 2024-06-12
- Write-up quality: 7/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_goat_mar2024.pdf#3.1.4
- Library page: https://bugbountylibrary.com/r/cantina%3Agoat_mar2024%3A3.1.4
- Tags: domain:web3 impact:funds-loss kind:contest platform:cantina sev:high tech:solidity technique:source-review vuln:business-logic vuln:precision-loss vuln:reward-distribution

**Target:** Staking contract _stake/lockWithdraw and DToken reward distributor
**Root cause:** p2UDtoken.mint/burn updates pool share before _reCalEP2PDBalance triggers Distributor._distribute, so global GOAT rewards are allocated using post-mint balances instead of pre-mint balances.
**Steps:**
1. Observe _beforeTokenTransfer calls Distributor.beforeTokenTransfer -> _distribute on every DToken transfer.
2. In _stake, `p2UDtoken.mint(account_, powerMinted)` executes before `_reCalEP2PDBalance(poolOwner_)`.
3. The mint raises the user's pool share; _reCalEP2PDBalance then mints _eP2PDToken and claims global rewards using the inflated share.
4. Same ordering flaw in lockWithdraw: `p2UDtoken.burn` precedes `_reCalEP2PDBalance`.
5. Example: 1000 global rewards, poolA 10% power, Alice 50% -> stakes to 60%, receives 60 instead of 50.
**How found:** Code reading of the _stake/lockWithdraw call order versus _beforeTokenTransfer's distribute hook; noticed reward distribution depends on p2UDtoken balance which is mutated before the recalc.
**Exploitation:** Stake a small amount to bump pool share immediately before a reward distribution; the recalc claims global GOAT mining rewards proportional to the inflated post-mint balance, over-paying the staker at other users' expense. Repeatable by staking/unstaking around distributions.
**Insight:** When a token hook triggers reward distribution based on share balances, check every mint/burn site for whether the balance mutation precedes the distribution call — ordering bugs silently shift yield between users.
