Flow

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

H1 Approver can withdraw

Summary

When the recipient approve a operator , the oprator is not able to withdraw

Vulnerability Details

Impact

The apporover that have the right to withdraw is not able to withdraw for the recipient

Tools Used

Foundry

Add this code in the test

````javascript

function test_WithdrawApprover()
external
whenNoDelegateCall
givenNotNull
whenAmountNotZero
whenWithdrawalAddressNotZero
whenWithdrawalAddressNotOwner
{
//flow.transferFrom({ from: users.recipient, to: users.eve, tokenId: defaultStreamId });
address boby = address(0xabc2345);
flow.approve({ to: boby, tokenId: defaultStreamId });
// It should withdraw.
uint256 streamId = defaultStreamId;
address to = users.eve;
uint128 depositAmount = DEPOSIT_AMOUNT_6D;
uint128 protocolFeeAmount = 0;
uint128 withdrawAmount = WITHDRAW_AMOUNT_6D;
vars.token = flow.getToken(streamId);
vars.previousSnapshotTime = flow.getSnapshotTime(streamId);
vars.previousTotalDebt = flow.totalDebtOf(streamId);
vars.previousAggregateAmount = flow.aggregateBalance(vars.token);
vars.expectedProtocolRevenue = flow.protocolRevenue(vars.token) + protocolFeeAmount;
// It should emit 1 {Transfer}, 1 {WithdrawFromFlowStream} and 1 {MetadataUpdated} events.
vm.expectEmit({ emitter: address(vars.token) });
emit IERC20.Transfer({ from: address(flow), to: to, value: withdrawAmount - protocolFeeAmount });
vm.expectEmit({ emitter: address(flow) });
emit ISablierFlow.WithdrawFromFlowStream({
streamId: streamId,
to: to,
token: vars.token,
caller: users.recipient,
protocolFeeAmount: protocolFeeAmount,
withdrawAmount: withdrawAmount - protocolFeeAmount
});
vm.expectEmit({ emitter: address(flow) });
emit IERC4906.MetadataUpdate({ _tokenId: streamId });
// It should perform the ERC-20 transfer.
expectCallToTransfer({ token: vars.token, to: to, amount: withdrawAmount - protocolFeeAmount });
vars.previousTokenBalance = vars.token.balanceOf(address(flow));
(, address msgSender, address txOrigin) = vm.readCallers();
console.log("msgSender: %s", msgSender);
console.log("txOrigin: %s", txOrigin);
vm.stopPrank();
vm.prank(boby);
(vars.actualWithdrawnAmount, vars.actualProtocolFeeAmount) =
flow.withdraw({ streamId: streamId, to: to, amount: withdrawAmount });
// Check the returned values.
assertEq(vars.actualProtocolFeeAmount, protocolFeeAmount, "protocol fee amount");
assertEq(vars.actualWithdrawnAmount, withdrawAmount - protocolFeeAmount, "withdrawn amount");
// Assert the protocol revenue.
assertEq(flow.protocolRevenue(vars.token), vars.expectedProtocolRevenue, "protocol revenue");
// It should update snapshot time.
vars.expectedSnapshotTime = flow.isPaused(streamId) ? vars.previousSnapshotTime : getBlockTimestamp();
assertEq(flow.getSnapshotTime(streamId), vars.expectedSnapshotTime, "snapshot time");
// It should decrease the total debt by the withdrawn value and fee amount.
vars.expectedTotalDebt = vars.previousTotalDebt - withdrawAmount;
assertEq(flow.totalDebtOf(streamId), vars.expectedTotalDebt, "total debt");
// It should reduce the stream balance by the withdrawn value and fee amount.
vars.expectedStreamBalance = depositAmount - withdrawAmount;
assertEq(flow.getBalance(streamId), vars.expectedStreamBalance, "stream balance");
// It should reduce the token balance of stream.
vars.expectedTokenBalance = vars.previousTokenBalance - vars.actualWithdrawnAmount;
assertEq(vars.token.balanceOf(address(flow)), vars.expectedTokenBalance, "token balance");
// It should decrease the aggregate amount.
assertEq(
flow.aggregateBalance(vars.token),
vars.previousAggregateAmount - vars.actualWithdrawnAmount,
"aggregate amount"
);
}
we get an exception
│ ├─ [11428] USDC::transfer(eve: [0xa959355654849CbEAbBf65235f8235833b9e031D], 2500000000 [2.5e9])
│ │ ├─ emit Transfer(from: Flow: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], to: eve: [0xa959355654849CbEAbBf65235f8235833b9e031D], value: 2500000000 [2.5e9])
│ │ └─ ← [Return] true
│ ├─ emit WithdrawFromFlowStream(streamId: 1, to: eve: [0xa959355654849CbEAbBf65235f8235833b9e031D], token: USDC: [0xa0Cb889707d426A7A386870A03bc70d1b0697598], caller: 0x000000000000000000000000000000000ABc2345, withdrawAmount: 2500000000 [2.5e9], protocolFeeAmount: 0)
│ ├─ emit MetadataUpdate(_tokenId: 1)
│ └─ ← [Return] 2500000000 [2.5e9], 0
└─ ← [Revert] log != expected log

Recommendations

Updates

Lead Judging Commences

inallhonesty Lead Judge
7 months ago
inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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