diff --git a/src/SablierV2LockupLinear.sol b/src/SablierV2LockupLinear.sol index a9ca622f4..5d448b048 100644 --- a/src/SablierV2LockupLinear.sol +++ b/src/SablierV2LockupLinear.sol @@ -187,10 +187,12 @@ contract SablierV2LockupLinear is /// - $d$ is the deposited amount. /// - $c$ is the cliff amount. function _calculateStreamedAmount(uint256 streamId) internal view override returns (uint128) { - // If the cliff time is in the future, return zero. uint256 cliffTime = uint256(_cliffs[streamId]); + uint256 startTime = uint256(_streams[streamId].startTime); uint256 blockTimestamp = block.timestamp; - if (cliffTime > blockTimestamp) { + + // If the cliff time or the start time is in the future, return zero. + if (cliffTime > blockTimestamp || startTime > blockTimestamp) { return 0; } @@ -204,7 +206,6 @@ contract SablierV2LockupLinear is // because there is no mix of amounts with different decimals. unchecked { // Calculate how much time has passed since the stream started, and the stream's total duration. - uint256 startTime = uint256(_streams[streamId].startTime); UD60x18 elapsedTime = ud(blockTimestamp - startTime); UD60x18 totalDuration = ud(endTime - startTime); diff --git a/test/integration/concrete/lockup-linear/streamed-amount-of/streamedAmountOf.t.sol b/test/integration/concrete/lockup-linear/streamed-amount-of/streamedAmountOf.t.sol index a49582dcc..b1a94746d 100644 --- a/test/integration/concrete/lockup-linear/streamed-amount-of/streamedAmountOf.t.sol +++ b/test/integration/concrete/lockup-linear/streamed-amount-of/streamedAmountOf.t.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.22 <0.9.0; +import { LockupLinear } from "src/types/DataTypes.sol"; + import { LockupLinear_Integration_Concrete_Test } from "../LockupLinear.t.sol"; import { StreamedAmountOf_Integration_Concrete_Test } from "../../lockup/streamed-amount-of/streamedAmountOf.t.sol"; @@ -17,7 +19,28 @@ contract StreamedAmountOf_LockupLinear_Integration_Concrete_Test is StreamedAmountOf_Integration_Concrete_Test.setUp(); } - function test_StreamedAmountOf_CliffTimeInThePast() + modifier givenStatusPendind() { + _; + } + + function test_StreamedAmountOf_CliffTimeZero() + external + givenNotNull + givenStreamHasNotBeenCanceled + givenStatusPendind + { + vm.warp({ newTimestamp: defaults.START_TIME() - 1 }); + + LockupLinear.Timestamps memory timestamps = defaults.lockupLinearTimestamps(); + timestamps.cliff = 0; + uint256 streamId = createDefaultStreamWithTimestamps(timestamps); + + uint128 actualStreamedAmount = lockupLinear.streamedAmountOf(streamId); + uint128 expectedStreamedAmount = 0; + assertEq(actualStreamedAmount, expectedStreamedAmount, "streamedAmount"); + } + + function test_StreamedAmountOf_CliffTimeInTheFuture() external view givenNotNull @@ -41,7 +64,7 @@ contract StreamedAmountOf_LockupLinear_Integration_Concrete_Test is assertEq(actualStreamedAmount, expectedStreamedAmount, "streamedAmount"); } - function test_StreamedAmountOf_CliffTimeInTheFuture() + function test_StreamedAmountOf_CliffTimeInThePast() external givenNotNull givenStreamHasNotBeenCanceled diff --git a/test/integration/concrete/lockup-linear/streamed-amount-of/streamedAmountOf.tree b/test/integration/concrete/lockup-linear/streamed-amount-of/streamedAmountOf.tree index 4a8e35c69..e87b5df2f 100644 --- a/test/integration/concrete/lockup-linear/streamed-amount-of/streamedAmountOf.tree +++ b/test/integration/concrete/lockup-linear/streamed-amount-of/streamedAmountOf.tree @@ -1,8 +1,11 @@ streamedAmountOf.t.sol +├── given the stream's status is "PENDING" +│ └── given the cliff time is zero +│ └── it should return zero └── given the stream's status is "STREAMING" - ├── given the cliff time is in the past + ├── given the cliff time is in the future │ └── it should return zero ├── given the cliff time is in the present │ └── it should return the correct streamed amount - └── given the cliff time is in the future + └── given the cliff time is in the past └── it should return the correct streamed amount