Treasury contract is designed to manage protocol funds. The only contract that interacts with the Treasury contract is the FeeCollector contract, to transfer RAAC tokens in distributeCollectedFees
and emergencyWithdraw
functions.
The problem arises because both distributeCollectedFees
and emergencyWithdraw
functions send tokens to the Treasury contract using direct transfers with safeTransfer
function.
Because deposit
function is not used to send funds, _balances
mapping token is not updated, making it impossible to execute future withdraw
.
The only way to withdraw tokens from Treasury contract is through the withdraw
function:
Withdrawals require that _balances[token] >= amount
which will not be the case if deposit
function is not used to send tokens.
The impact of this issue is high as it leads to protocol funds being stuck in the treasury forever.
Manual review.
Make sure to use deposit
function of Treasury contract when distributing collected fees or during emergency withdraw procedure. Note that this will require an approval from the FeeCollector contract to the Treasury contract to allow transferFrom
function to transfer tokens in deposit
function. This approval can be done in FeeCollector constructor or with a decidated additionnal function.
Possible implementation for processDistribution
and emergencyWithdraw
:
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.