It is possible to avoid paying the protocolFee
via withdrawing small amounts of tokens. Although gas fees for transactions would deter users from withdrawing small amounts, considering that the Sablier protocol is supporting any ERC20 token that has less than 19 decimals, this becomes a valid attack vector for tokens with little decimals.
Sablier admin can implement protocol fees for a token with the setProtocolFee
function found in the SablierFlowBase.sol
contract.
This protocolFee
is applied when a user calls the withdraw
function which calls the _withdraw
in the SablierFlow.sol
contract.
As seen from this function, the protocolFee that will be applied is calculated in the calculateAmountsFromFee
function in the Helpers.sol
contract.
Due to the use of UD60x18 math, in low totalAmount
inputs, the feeAmount
will return 0. This can be verified by adding the following line in the function.
This creates an attack vector where users can withdraw small amounts of tokens (e.g. withdraw 9 tokens at a time when fee is 10%) to avoid paying fees. Tokens with industry standard decimals (decimals >= 6) make this attack vector unlikely as malicious actors would have to pay a lot of gas fees to avoid paying protocolFee
. However, as specified in the Scope of the audit:
Any ERC-20 token can be used with Flow as long as it adheres to the following assumptions:
The total supply of any ERC-20 token remains below , i.e.,
type(uint128).max
.The
transfer
andtransferFrom
methods of any ERC-20 token strictly reduce the sender's balance by the transfer amount and increase the recipient's balance by the same amount. In other words, tokens that charge fees on transfers are not supported.An address' ERC-20 balance can only change as a result of a
transfer
call by the sender or atransferFrom
call by an approved address. This excludes rebase tokens, interest-bearing tokens, and permissioned tokens where the admin can arbitrarily change balances.The token contract does not allow callbacks (e.g., ERC-777 is not supported).
This means that Sablier Flow is expected to support ERC20 tokens with low decimals. Tokens with low decimals make this attack vector very likely to happen as amount of calls needed to make to withdraw full amount while avoiding fees will be low. This amount calculated with the following solidity calculation assuming the protocolFee
is 10%.
This calculation can also be written as the following math equation once again assuming the protocolFee
is 10%, where N
is the amount of calls required, T
is the amount of tokens and d
is the amount of decimals.
As an example, using this calculation, we can find out that in order to withdraw 10 tokens with 0 decimals it would take 2 different calls to withdraw the full amount while avoiding fees, for 10 tokens and 2 decimals 112 different calls. Making tokens with low decimals very susceptible to this attack as it would be profitable for malicious actors to split their withdraw in multiple calls to avoid paying the protocolFee
and pay less of that amount in gas fees.
Consider that as the protocolFee
goes down, amount of tokens that can be withdraw in a single transaction goes up making the attack cost less gas to perform. Even if no tokens with low decimals become widely used, this attack can very well be worth to execute if gas prices keep going down and BTC (widely used token with most value for 1 wei) price goes up.
Add the following test contract in the tests file and run it to observe the vulnerability. In order to run this test, add a mint
function in the MockERC20.sol
Likelihood: Low as tokens with such little decimals are not widely used at the moment
Impact: High as this vulnerability leads to direct loss of funds for the protocol
Manual review, foundry
Implement a standard base fee of 1 when protocolFee > ZERO
but protocolFeeAmount returns 0
. An example of this is shown below.
Alternatively, protocol already reverts when stream's token decimals are greater than 18, protocol must add another check to make sure that the token decimals can not be too little. The amount can be set according to what protocol deems is acceptable (such as 4). An example of this recommendation is shown below.
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.