Flow

Sablier
FoundryDeFi
20,000 USDC
View results
Submission Details
Severity: high
Invalid

Arithmetic Operations (Unchecked Arithmetic)

Summary

The SablierFlowBase contract uses unchecked arithmetic in the collectProtocolRevenue function, which can lead to underflow issues. This could allow a malicious actor to manipulate the protocol revenue, resulting in potential loss of funds.

Finding Description

In the collectProtocolRevenue function, the following line of code uses unchecked arithmetic:

aggregateBalance[token] -= revenue;

If the aggregateBalance[token] is less than revenue, this line would result in an underflow, causing aggregateBalance[token] to wrap around to a very large number (due to Solidity's handling of integers), which can create inconsistencies in the state. This situation can be exploited by a malicious user to trigger this underflow by crafting transactions that manipulate the state before this line is executed, potentially allowing them to withdraw more tokens than they are entitled to.

This breaks the security guarantee of consistency of state as it allows the contract's internal accounting to become corrupt, leading to unintended behavior in fund distribution and balances.

Vulnerability Details

  • Location: SablierFlowBase.sol

  • Function: collectProtocolRevenue(IERC20 token, address to)

  • Type: Arithmetic Underflow

The unchecked arithmetic operation is particularly dangerous because:

  1. It is not caught by Solidity's compiler since it is wrapped in an unchecked block.

  2. This vulnerability can lead to unintended transfers of funds, which is particularly critical in financial contracts.

Impact

This vulnerability poses a high impact risk to the protocol. If exploited, it could allow an attacker to siphon off funds from the contract, leading to financial losses for both the protocol and its users. The potential for fund loss directly undermines user trust and could affect the contract's viability and reputation.

Proof of Concept

To demonstrate this vulnerability, an attacker could:

  1. Deploy a contract that interacts with SablierFlowBase to manipulate aggregateBalance[token].

  2. Call collectProtocolRevenue after ensuring that the aggregateBalance[token] is set to a value lower than the revenue they intend to collect.

  3. This would trigger the underflow and allow the attacker to withdraw more funds than they should be entitled to.

Example scenario:

  • Assume aggregateBalance[token] is 100 and revenue is 150.

  • The unchecked subtraction would wrap aggregateBalance[token] to a very large number (e.g., 2^256 - 1), allowing the attacker to exploit this discrepancy.

Recommendations

To mitigate this vulnerability, the arithmetic operation should be protected against underflow by including a require statement to check the balance before the subtraction. Here is the suggested fix:

function collectProtocolRevenue(IERC20 token, address to) external override onlyAdmin {
uint128 revenue = protocolRevenue[token];
// Check: there is protocol revenue to collect.
if (revenue == 0) {
revert Errors.SablierFlowBase_NoProtocolRevenue(address(token));
}
// Ensure there are sufficient funds before performing the subtraction.
require(aggregateBalance[token] >= revenue, "Insufficient aggregate balance");
// Effect: reset the protocol revenue.
protocolRevenue[token] = 0;
unchecked {
// Effect: update the aggregate balance.
aggregateBalance[token] -= revenue;
}
// Interaction: transfer the protocol revenue to the provided address.
token.safeTransfer({ to: to, value: revenue });
emit ISablierFlowBase.CollectProtocolRevenue({ admin: msg.sender, token: token, to: to, revenue: revenue });
}

By adding the require statement to check the balance before proceeding with the subtraction, we can prevent underflow and ensure that the contract behaves as intended, maintaining the integrity of its financial operations.

File Location

  • SablierFlowBase.sol

Updates

Lead Judging Commences

inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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