Sablier

Sablier
DeFiFoundry
53,440 USDC
View results
Submission Details
Severity: high
Invalid

The `Helpers::checkAndCalculateBrokerFee` function reverts when charging even a `1% fee` for tokens with `> 18 decimals`.

Summary

The Sablier protocol allows third-party protocols to use Sablier streams and, if desired, charge a fee of up to 10% of the total amount streamed. Unfortunately, the prb library used for calculating the broker fee doesn't calculate the correct fee for tokens with > 18 decimals. As a result, it reverts even when brokers try to charge only a 1% fee.

Vulnerability details

The createWithDurations and createWithTimestamps functions of all types of streams call the Helpers::checkAndCalculateBrokerFee function to calculate the broker fee based on the total amount users stream. The protocol limits the broker fee using the MAX_BROKER_FEE constant variable, which is restricted to tokens with 18 decimals. If users use tokens with > 18 decimals, this function reverts and throws a SablierV2Lockup_BrokerFeeTooHigh error. This prevents users from streaming tokens with > 18 decimals.

Impact

Brokers will not be able to charge even a 1% fee when the user uses tokens with > 18 decimals for streams, and this will prevent third-party protocols from using Sablier for payment streaming.

Proof of Concept

Put this code in any file and run the test with command bun run test --mt test_checkAndCalculateBrokerFee -vvv

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.22;
import { Test } from "forge-std/src/Test.sol";
import { console } from "forge-std/src/console.sol";
import { Helpers } from "src/libraries/Helpers.sol";
import { Errors } from "src/libraries/Errors.sol";
import { UD60x18 } from "@prb/math/src/UD60x18.sol";
import { Lockup } from "src/types/DataTypes.sol";
contract HelperTest is Test {
UD60x18 public constant MAX_BROKER_FEE = UD60x18.wrap(0.1e18);
function setUp() external { }
function test_checkAndCalculateBrokerFee() external {
// tokens with higher than 18 decimals
uint128 totalAmount = 100e24; // 100 YAM-V2 - YAM-V2 has 24 decimals
uint128 brokerFee = 0.01e24;
vm.expectRevert(
abi.encodeWithSelector(
Errors.SablierV2Lockup_BrokerFeeTooHigh.selector, UD60x18.wrap(brokerFee), MAX_BROKER_FEE
)
);
Lockup.CreateAmounts memory createAmounts =
Helpers.checkAndCalculateBrokerFee(totalAmount, UD60x18.wrap(brokerFee), MAX_BROKER_FEE);
}
}

Tools Used

Manual Review, Foundry

Recommended Mitigation Steps

Make sure the prb library performs correct calculations for tokens with > 18 decimals.

Updates

Lead Judging Commences

inallhonesty Lead Judge
over 1 year ago
inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.