The Treasury contract's accounting system only tracks balances deposited through the deposit function. Any tokens sent directly to the contract via regular transfer or transfer become permanently locked as the withdrawal mechanism relies on internally tracked balances rather than actual token balances.
The issue stems from the Treasury contract's balance tracking mechanism that fails to account for direct token transfers. Here's how the vulnerability manifests:
Balance Tracking System:
Core Issue:
The contract uses _balances[token] to track deposited tokens
Withdrawals check against and decrease this internal balance
Direct token transfers bypass the deposit function and aren't recorded in _balances
When withdrawal is attempted, _balances[token] -= amount underflows since _balances[token] is 0
The FeeCollector contract has multiple functions that directly transfer tokens to the Treasury without using the deposit function:
Emergency Withdrawals:
Fee Distribution:
In both cases:
Tokens are sent directly to Treasury
These transfers bypass Treasury's deposit function
The Treasury's internal _balances mapping isn't updated
The funds become permanently locked
Any tokens sent directly to the Treasury become permanently locked
Foundry
Manual Review
Use actual token balances instead of internal accounting:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.