Sablier

Sablier
DeFiFoundry
53,440 USDC
View results
Submission Details
Severity: low
Invalid

`SablierV2NFTDescriptor::generateAccentColor` fails to utilize full color spectrum and risks color repetition

Description

The function SablierV2NFTDescriptor::generateAccentColor is designed to generate a pseudo-random HSL color. It does this by hashing the chainid, sablier address, and streamId together. The resulting color is then used as the accent color for the SVG. However, the mathematical operations within the function do not align with the comments, resulting in the exclusion of one value each for saturation and lightness:

// The saturation is a percentage where 0% is grayscale and 100%, but here the range is bounded to [20,100]
// to make the colors more lively.
// Shifting 8 bits to the right and applying an 8-bit mask means using the bits at positions [15:8].
uint256 saturation = (((bitField >> 8) & 0xFF) % 80) + 20;
// The lightness is typically a percentage between 0% (black) and 100% (white), but here the range
// is bounded to [30,100] to avoid dark colors.
// Applying an 8-bit mask means using the bits at positions [7:0].
uint256 lightness = ((bitField & 0xFF) % 70) + 30;

The issue arises from the modulo operation, where x % x = 0 and not x. As a result, the current code allows saturation to range from [20:99] and lightness from [30:99], but not up to 100.

Another concern is the lightness value exceeding 95. A high lightness value results in a white color, rendering the hue and saturation almost insignificant. When the lightness is above 95-96, the difference caused by hue and saturation becomes so minimal that it's barely noticeable to the human eye. This will lead to many NFT colors appearing identical.

Risk

Likelyhood: Medium/High

  • Saturation and lightness will never reach 100.

  • In 4 out of 69 instances, the hue and saturation will have negligible impact.

Impact: Low

  • More NFTs will appear identical due to less color variation.

Proof of Concept

For a better understanding of the lightness issue, you can conduct your own tests using this site:
https://www.w3schools.com/colors/colors_hsl.asp

Recommended Mitigation

  • Increase both modulos by 1

  • Limit the lightness range to [30:95]

// The saturation is a percentage where 0% is grayscale and 100%, but here the range is bounded to [20,100]
// to make the colors more lively.
// Shifting 8 bits to the right and applying an 8-bit mask means using the bits at positions [15:8].
- uint256 saturation = (((bitField >> 8) & 0xFF) % 80) + 20;
+ uint256 saturation = (((bitField >> 8) & 0xFF) % 81) + 20;
// The lightness is typically a percentage between 0% (black) and 100% (white), but here the range
- // is bounded to [30,100] to avoid dark colors.
+ // is bounded to [30,95] to avoid dark and white colors.
// Applying an 8-bit mask means using the bits at positions [7:0].
- uint256 lightness = ((bitField & 0xFF) % 70) + 30;
+ uint256 lightness = ((bitField & 0xFF) % 71) + 25;
Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Info/Gas/Invalid as per Docs

https://docs.codehawks.com/hawks-auditors/how-to-determine-a-finding-validity

n0kto Submitter
over 1 year ago
0xnevi Judge
over 1 year ago
n0kto Submitter
over 1 year ago
inallhonesty Lead Judge
over 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Info/Gas/Invalid as per Docs

https://docs.codehawks.com/hawks-auditors/how-to-determine-a-finding-validity

Support

FAQs

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