From e5024097af329d8f49249fa7e18108c2e4168d3d Mon Sep 17 00:00:00 2001 From: Andrei Vlad Birgaoanu Date: Tue, 7 Jan 2025 23:54:47 +0200 Subject: [PATCH] refactor: use unchecked and casting in calculateStreamedPercentage docs: last polishes --- src/LockupNFTDescriptor.sol | 5 ++++- src/SablierLockup.sol | 8 ++++---- src/libraries/VestingMath.sol | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/LockupNFTDescriptor.sol b/src/LockupNFTDescriptor.sol index 0f5e35edf..d0885901e 100644 --- a/src/LockupNFTDescriptor.sol +++ b/src/LockupNFTDescriptor.sol @@ -198,7 +198,10 @@ contract LockupNFTDescriptor is ILockupNFTDescriptor { pure returns (uint256) { - return streamedAmount * 10_000 / depositedAmount; + // This cannot overflow because both inputs are uint128s, and zero deposit amounts are not allowed in Sablier. + unchecked { + return uint256(streamedAmount) * 10_000 / depositedAmount; + } } /// @notice Generates a pseudo-random HSL color by hashing together the `chainid`, the `sablier` address, diff --git a/src/SablierLockup.sol b/src/SablierLockup.sol index bd8300504..47389397b 100644 --- a/src/SablierLockup.sol +++ b/src/SablierLockup.sol @@ -297,7 +297,7 @@ contract SablierLockup is ISablierLockup, SablierLockupBase { /// @inheritdoc SablierLockupBase function _calculateStreamedAmount(uint256 streamId) internal view override returns (uint128) { - // Load the stream's parameters in memory. + // Load in memory the parameters used in {VestingMath}. uint40 blockTimestamp = uint40(block.timestamp); uint128 depositedAmount = _streams[streamId].amounts.deposited; Lockup.Model lockupModel = _streams[streamId].lockupModel; @@ -305,7 +305,7 @@ contract SablierLockup is ISablierLockup, SablierLockupBase { Lockup.Timestamps memory timestamps = Lockup.Timestamps({ start: _streams[streamId].startTime, end: _streams[streamId].endTime }); - // Calculate streamed amount for the Lockup Dynamic model. + // Calculate the streamed amount for the Lockup Dynamic model. if (lockupModel == Lockup.Model.LOCKUP_DYNAMIC) { streamedAmount = VestingMath.calculateLockupDynamicStreamedAmount({ depositedAmount: depositedAmount, @@ -315,7 +315,7 @@ contract SablierLockup is ISablierLockup, SablierLockupBase { withdrawnAmount: _streams[streamId].amounts.withdrawn }); } - // Calculate streamed amount for the Lockup Linear model. + // Calculate the streamed amount for the Lockup Linear model. else if (lockupModel == Lockup.Model.LOCKUP_LINEAR) { streamedAmount = VestingMath.calculateLockupLinearStreamedAmount({ depositedAmount: depositedAmount, @@ -326,7 +326,7 @@ contract SablierLockup is ISablierLockup, SablierLockupBase { withdrawnAmount: _streams[streamId].amounts.withdrawn }); } - // Calculate streamed amount for the Lockup Tranched model. + // Calculate the streamed amount for the Lockup Tranched model. else if (lockupModel == Lockup.Model.LOCKUP_TRANCHED) { streamedAmount = VestingMath.calculateLockupTranchedStreamedAmount({ depositedAmount: depositedAmount, diff --git a/src/libraries/VestingMath.sol b/src/libraries/VestingMath.sol index be75ac47b..43a591095 100644 --- a/src/libraries/VestingMath.sol +++ b/src/libraries/VestingMath.sol @@ -115,9 +115,9 @@ library VestingMath { /// @dev Lockup linear model uses the following distribution function: /// /// $$ - /// ( x * sa + s, cliffTime > blockTimestamp + /// ( x * sa + s, cliff time > block timestamp /// f(x) = ( - /// ( x * sa + s + c, cliffTime <= blockTimestamp + /// ( x * sa + s + c, cliff time <= block timestamp /// $$ /// /// Where: