The FeeCollector contract directly transfers RAAC tokens to the Treasury contract without invoking the deposit function. This bypasses the necessary state updates in the Treasury contract, specifically _balances[token] and _totalValue. As a result, when the withdraw function is called, it attempts to decrement these states, leading to underflow errors because the states were never incremented in the first place. This design flaw renders the RAAC tokens effectively stuck in the treasury.
FeeCollector Contract:
The function _processDistributions transfers RAAC tokens to the treasury using the following line:
This sends a portion of the collected fees (specifically, the treasury's share) to the treasury contract.
Treasury Contract:
The withdraw function relies on the _balances[token] and _totalValue states being correctly updated. However, these states are only updated in the deposit function:
Since the deposit function is not called when RAAC tokens are sent directly, the _balances[token] and _totalValue states remain unchanged. This causes the withdraw function to revert due to underflow when attempting to decrement these states:
The issue arises because the FeeCollector contract directly transfers RAAC tokens to the treasury without invoking the deposit function. This bypasses the state updates in the Treasury contract, leading to inconsistent state management. When the withdraw function is called, it attempts to decrement _balances[token] and _totalValue, which were never incremented, resulting in underflow errors.
RAAC tokens sent to the treasury are permanently locked, as the withdraw function will always revert due to underflow errors.
Manual Review
Instead of directly transferring RAAC tokens to the treasury, call the deposit function of the Treasury contract to ensure proper state updates.
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.