In SablierFlowBase.sol
, an unchecked subtraction in the collectProtocolRevenue
function can cause an underflow in the aggregateBalance
of a token when the admin attempts to collect protocol revenue. Which could cause future calls to the recover
function to revert due to underflow, effectively bricking the ability to recover surplus tokens.
The admin collects protocol revenue of a token through the collectProtocolRevenue
function in SablierFlowBase.sol
. There is an unchecked block in this function to subtract the aggregateBalance
of a token with the protocol revenue of the token.
The _withdraw
function in SablierFlow.sol
is used by user to withdraw deposit from a stream. In this function the aggregateBalance
of a token is subtracted from the withdraw amount minus the protocol fee. The protocol fee is added to the protocolRevenue
of that token.
Consider this scenario:
User 1 create a stream with 100 USDC of deposits, the recipient is User 1.
User 1 withdraws 100 USDC from the stream, some amount is deducted from the withdraw amount due to protocol fee and added to protocol revenue for that token. Protocol fee is 1% , henceprotocolRevenue
is now 1 USDC.
User 1 create a stream again with 100 USDC of deposits, the recipient is User 1.
Admin wants to collect the protocol revenue but User 1 frontrun the admin and withdraws all 100 USDC from the stream. protocolRevenue
is now 2 USDC.
The aggregateBalance
is 0 USDC is subtracted from the protocolRevenue
which is 2 USDC.
Admin successfully collects the protocol revenue but now the aggregateBalance
of that token is type(uint256).max
.
When admin needs to recover some surplus of a token through the recover
function it will most likely always revert because the token balance of the contract is subtracted from the aggregateBalance
of that token which is now a very large value. This will cause underflow and revert the function call.
The recover
function in SablierFlowBase.sol
is bricked for a certain token as a result surplus of that token cannot be recovered.
Note, that the aggregateBalance
will possibly be back to normal once another stream with that token is created and the stream receive deposit which will caused unchecked overflow for the aggregateBalance
and possibly the value will be back to 0 or more. However, the more protocol revenue collected the more tokens required to return the aggregate balance back to normal.
Manual review
Add this check in the collectProtocolRevenue
function:
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.