It is not possible to withdraw collected fees from the Treasury contract due to an incorrect deposit mechanism. Fees in FeeCollector::_distributecollectedFees are transferred directly via the ERC20 transfer()
function instead of using the Treasury's deposit()
function, causing the Treasury’s internal accounting to remain unchanged. As a result, any attempt to withdraw fees from the Treasury contract will revert.
The FeeCollector
contract is responsible for collecting fees and distributing them to the Treasury.
In the _distributeCollectedFees()
function, fees are sent to the Treasury contract using the reward token's ERC20 transfer()
function.
However, the Treasury contract relies on its deposit()
function to update balances[token]
when receiving funds. This balance is then chedked in the withdraw()
function.
Since transfer()
does not trigger deposit()
, the Treasury’s balance remains unchanged, even though it holds the transferred tokens.
When attempting to withdraw funds, the Treasury contract checks its internal balance, which has not been updated, leading to an underflow and transaction failure.
High severity.
The Treasury contract's withdraw() function is effectively blocked, so collected fees cannot be accessed and are permanently locked in the contract.
Manual code review
In FeeCollector::_processDistributions, use the Treasury’s deposit()
function instead of direct ERC20 transfer()
to ensure proper balance tracking.
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.