Juicebox contest - Rolezn's results

The decentralized fundraising and treasury protocol.

General Information

Platform: Code4rena

Start Date: 18/10/2022

Pot Size: $50,000 USDC

Total HM: 13

Participants: 67

Period: 5 days

Judge: Picodes

Total Solo HM: 7

Id: 172

League: ETH

Juicebox

Findings Distribution

Researcher Performance

Rank: 37/67

Findings: 1

Award: $37.88

QA:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Summary<a name="Summary">

Low Risk Issues

IssueInstances
LOW‑1Missing Checks for Address(0x0)6
LOW‑2Use _safeMint instead of _mint4
LOW‑3Contracts are not using their OZ Upgradeable counterparts4
LOW‑4Critical Changes Should Use Two-step Procedure6
LOW‑5Upgrade OpenZeppelin Contract Dependency1

Total: 21 instances over 5 issues

Non-critical Issues

IssueInstances
NC‑1Adding A Return Statement When The Function Defines A Named Return Variable, Is Redundant1
NC‑2Public Functions Not Called By The Contract Should Be Declared External Instead4
NC‑3require() / revert() Statements Should Have Descriptive Reason Strings2
NC‑4Implementation contract may not be initialized3
NC‑5Use of Block.Timestamp1
NC‑6Non-usage of specific imports22
NC‑7Lines are too long22
NC‑8Use bytes.concat()2

Total: 57 instances over 8 issues

Low Risk Issues

<a href="#Summary">[LOW‑1]</a><a name="LOW&#x2011;1"> Missing Checks for Address(0x0)

Lack of zero-address validation on address parameters may lead to transaction reverts, waste gas, require resubmission of transactions and may even force contract redeployments in certain cases within the protocol.

<ins>Proof Of Concept</ins>
370: function setDefaultReservedTokenBeneficiary: address _beneficiary

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L370

480: function mintFor: address _beneficiary

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L480

71: function launchProjectFor: address _owner

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateProjectDeployer.sol#L71

854: function recordSetDefaultReservedTokenBeneficiary: address _beneficiary

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateStore.sol#L854

1123: function recordSetFirstOwnerOf: address _owner

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateStore.sol#L1123

1173: function cleanTiers: address _nft

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateStore.sol#L1173

<ins>Recommended Mitigation Steps</ins>

Consider adding explicit zero-address validation on input parameters of address type.

<a href="#Summary">[LOW‑2]</a><a name="LOW&#x2011;2"> Use _safeMint instead of _mint

According to openzepplin's ERC721, the use of _mint is discouraged, use _safeMint whenever possible. https://docs.openzeppelin.com/contracts/3.x/api/token/erc721#ERC721-_mint-address-uint256-

<ins>Proof Of Concept</ins>
461: _mint(_reservedTokenBeneficiary, _tokenId);

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L461

504: _mint(_beneficiary, _tokenId);

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L504

635: _mint(_beneficiary, _tokenId);

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L635

677: _mint(_beneficiary, _tokenId);

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L677

<ins>Recommended Mitigation Steps</ins>

Use _safeMint whenever possible instead of _mint

<a href="#Summary">[LOW‑3]</a><a name="LOW&#x2011;3"> Contracts are not using their OZ Upgradeable counterparts

The non-upgradeable standard version of OpenZeppelin’s library are inherited / used by the contracts. It would be safer to use the upgradeable versions of the library contracts to avoid unexpected behaviour.

<ins>Proof of Concept</ins>
4: import '@openzeppelin/contracts/utils/Checkpoints.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JB721TieredGovernance.sol#L4

5: import '@openzeppelin/contracts/access/Ownable.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L5

<ins>Recommended Mitigation Steps</ins>

Where applicable, use the contracts from @openzeppelin/contracts-upgradeable instead of @openzeppelin/contracts.

<a href="#Summary">[LOW‑4]</a><a name="LOW&#x2011;4"> Critical Changes Should Use Two-step Procedure

The critical procedures should be two step process.

See similar findings in previous Code4rena contests for reference: https://code4rena.com/reports/2022-06-illuminate/#2-critical-changes-should-use-two-step-procedure

<ins>Proof Of Concept</ins>
147: function setTierDelegates(JBTiered721SetTierDelegatesData[] memory _setTierDelegatesData)

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JB721TieredGovernance.sol#L147

177: function setTierDelegate(address _delegatee, uint256 _tierId) public virtual override {

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JB721TieredGovernance.sol#L177

370: function setDefaultReservedTokenBeneficiary(address _beneficiary) external override onlyOwner {

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L370

386: function setBaseUri(string memory _baseUri) external override onlyOwner {

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L386

402: function setContractUri(string calldata _contractUri) external override onlyOwner {

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L402

418: function setTokenUriResolver(IJBTokenUriResolver _tokenUriResolver) external override onlyOwner {

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L418

<ins>Recommended Mitigation Steps</ins>

Lack of two-step procedure for critical operations leaves them error-prone. Consider adding two step procedure on the critical functions.

<a href="#Summary">[LOW‑5]</a><a name="LOW&#x2011;5"> Upgrade OpenZeppelin Contract Dependency

An outdated OZ version is used (which has known vulnerabilities, see: https://github.com/OpenZeppelin/openzeppelin-contracts/security/advisories).

<ins>Proof Of Concept</ins>
@openzeppelin/contracts: ^4.6.0

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/package.json#L14

<ins>Recommended Mitigation Steps</ins>

Update OpenZeppelin Contracts Usage in package.json

Non Critical Issues

<a href="#Summary">[NC‑1]</a><a name="NC&#x2011;1"> Adding A Return Statement When The Function Defines A Named Return Variable, Is Redundant

<ins>Proof Of Concept</ins>
631: return leftoverAmount

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L631

<a href="#Summary">[NC‑2]</a><a name="NC&#x2011;2"> Public Functions Not Called By The Contract Should Be Declared External Instead

Contracts are allowed to override their parents’ functions and change the visibility from external to public.

<ins>Proof Of Concept</ins>
function setTierDelegates(JBTiered721SetTierDelegatesData[] memory _setTierDelegatesData) public virtual override {

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JB721TieredGovernance.sol#L147

function setTierDelegate(address _delegatee, uint256 _tierId) public virtual override {

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JB721TieredGovernance.sol#L177

function mintReservesFor(uint256 _tierId, uint256 _count) public override {

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L264

function mintFor(uint16[] memory _tierIds, address _beneficiary) public override onlyOwner returns (uint256[] memory tokenIds) {

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L290

<a href="#Summary">[NC‑3]</a><a name="NC&#x2011;3"> require() / revert() Statements Should Have Descriptive Reason Strings

<ins>Proof Of Concept</ins>
216: require(address(this) != codeOrigin);

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L216

218: require(address(store) == address(0));

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L218

<a href="#Summary">[NC‑4]</a><a name="NC&#x2011;4"> Implementation contract may not be initialized

OpenZeppelin recommends that the initializer modifier be applied to constructors. Per OZs Post implementation contract should be initialized to avoid potential griefs or exploits. https://forum.openzeppelin.com/t/uupsupgradeable-vulnerability-post-mortem/15680/5

<ins>Proof Of Concept</ins>
constructor() { codeOrigin = address(this); }

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L185-L187

constructor( JB721GlobalGovernance _globalGovernance, JB721TieredGovernance _tieredGovernance, JBTiered721Delegate _noGovernance ) { globalGovernance = _globalGovernance; tieredGovernance = _tieredGovernance; noGovernance = _noGovernance; }

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateDeployer.sol#L46-L54

constructor( IJBController _controller, IJBTiered721DelegateDeployer _delegateDeployer, IJBOperatorStore _operatorStore ) JBOperatable(_operatorStore) { controller = _controller; delegateDeployer = _delegateDeployer; }

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateProjectDeployer.sol#L47-L54

<a href="#Summary">[NC‑5]</a><a name="NC&#x2011;5"> Use of Block.Timestamp

Block timestamps have historically been used for a variety of applications, such as entropy for random numbers (see the Entropy Illusion for further details), locking funds for periods of time, and various state-changing conditional statements that are time-dependent. Miners have the ability to adjust timestamps slightly, which can prove to be dangerous if block timestamps are used incorrectly in smart contracts. References: SWC ID: 116

<ins>Proof Of Concept</ins>
903: if (_storedTierOf[msg.sender][_tierId].lockedUntil >= block.timestamp) revert TIER_LOCKED();

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateStore.sol#L903

<ins>Recommended Mitigation Steps</ins>

Block timestamps should not be used for entropy or generating random numbers—i.e., they should not be the deciding factor (either directly or through some derivation) for winning a game or changing an important state.

Time-sensitive logic is sometimes required; e.g., for unlocking contracts (time-locking), completing an ICO after a few weeks, or enforcing expiry dates. It is sometimes recommended to use block.number and an average block time to estimate times; with a 10 second block time, 1 week equates to approximately, 60480 blocks. Thus, specifying a block number at which to change a contract state can be more secure, as miners are unable to easily manipulate the block number.

<a href="#Summary">[NC‑6]</a><a name="NC&#x2011;6"> Non-usage of specific imports

The current form of relative path import is not recommended for use because it can unpredictably pollute the namespace. Instead, the Solidity docs recommend specifying imported symbols explicitly. https://docs.soliditylang.org/en/v0.8.15/layout-of-source-files.html#importing-other-source-files

<ins>Proof Of Concept</ins>
4: import './abstract/Votes.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JB721GlobalGovernance.sol#L4

5: import './JBTiered721Delegate.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JB721GlobalGovernance.sol#L5

5: import './interfaces/IJB721TieredGovernance.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JB721TieredGovernance.sol#L5

6: import './JBTiered721Delegate.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JB721TieredGovernance.sol#L6

6: import './abstract/JB721Delegate.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L6

7: import './interfaces/IJBTiered721Delegate.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L7

8: import './libraries/JBIpfsDecoder.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L8

9: import './libraries/JBTiered721FundingCycleMetadataResolver.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L9

10: import './structs/JBTiered721Flags.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L10

4: import './interfaces/IJBTiered721DelegateDeployer.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateDeployer.sol#L4

5: import './JBTiered721Delegate.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateDeployer.sol#L5

6: import './JB721TieredGovernance.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateDeployer.sol#L6

7: import './JB721GlobalGovernance.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateDeployer.sol#L7

7: import './interfaces/IJBTiered721DelegateProjectDeployer.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateProjectDeployer.sol#L7

5: import './interfaces/IJBTiered721DelegateStore.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateStore.sol#L5

6: import './libraries/JBBitmap.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateStore.sol#L6

7: import './structs/JBBitmapWord.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateStore.sol#L7

8: import './structs/JBStored721Tier.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateStore.sol#L8

10: import '../interfaces/IJB721Delegate.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/abstract/JB721Delegate.sol#L10

11: import './ERC721.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/abstract/JB721Delegate.sol#L11

4: import '../structs/JBBitmapWord.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/libraries/JBBitmap.sol#L4

4: import './../structs/JBTiered721FundingCycleMetadata.sol';

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/libraries/JBTiered721FundingCycleMetadataResolver.sol#L4

<ins>Recommended Mitigation Steps</ins>

Use specific imports syntax per solidity docs recommendation.

<a href="#Summary">[NC‑7]</a><a name="NC&#x2011;7"> Lines are too long

Usually lines in source code are limited to 80 characters. Today's screens are much larger so it's reasonable to stretch this in some cases. Since the files will most likely reside in GitHub, and GitHub starts using a scroll bar in all cases when the length is over 164 characters, the lines below should be split when they reach that length Reference: https://docs.soliditylang.org/en/v0.8.10/style-guide.html#maximum-line-length

<ins>Proof Of Concept</ins>
539: // Set the leftover amount as the initial value, including any credits the beneficiary might already have.

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L539

542: // Keep a reference to a flag indicating if a mint is expected from discretionary funds. Defaults to false, meaning to mint is not expected.

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L542

545: // Keep a reference to the flag indicating if the transaction should revert if all provded funds aren't spent. Defaults to false, meaning only a minimum payment is enforced.

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L545

548: // Skip the first 32 bytes which are used by the JB protocol to pass the paying project's ID when paying from a JBSplit.

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L548

743: // If there's no stored first owner, and the transfer isn't originating from the zero address as expected for mints, store the first owner.

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721Delegate.sol#L743

120: // Get a bit of freemem to land the bytecode, not updated as we'll leave this scope right after create(..)

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateDeployer.sol#L120

663: // Make sure the tier's contribution floor is greater than or equal to the previous contribution floor.

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateStore.sol#L663

739: // If this is the last tier being added, track the current last sort index if it's not already tracked.

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateStore.sol#L739

747: // Set the tier after the previous one being iterated on as the tier being added, or 0 if the index is incremented.

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateStore.sol#L747

1193: // If the current index being iterated on isn't an increment of the previous, set the correct tier after if needed.

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateStore.sol#L1193

1197: // Otherwise if the current index is an increment of the previous and the after index isn't 0, set it to 0.

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateStore.sol#L1197

1242: // Get a reference to the number of tokens already minted in the tier, not counting reserves or burned tokens.

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateStore.sol#L1242

1250: // Get the number of reserved tokens mintable given the number of non reserved tokens minted. This will round down.

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/JBTiered721DelegateStore.sol#L1250

118: // Check the 4 bytes interfaceId and handle the case where the metadata was not intended for this contract

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/abstract/JB721Delegate.sol#L118

257: // Check the 4 bytes interfaceId and handle the case where the metadata was not intended for this contract

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/abstract/JB721Delegate.sol#L257

144: // These conditions are all part of the same curve. Edge conditions are separated because fewer operation are necessary.

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/abstract/JB721Delegate.sol#L144

229: // Make sure the caller is a terminal of the project, and the call is being made on behalf of an interaction with the correct project.

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/abstract/JB721Delegate.sol#L229

250: // Make sure the caller is a terminal of the project, and the call is being made on behalf of an interaction with the correct project.

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/abstract/JB721Delegate.sol#L250

<a href="#Summary">[NC‑8]</a><a name="NC&#x2011;8"> Use bytes.concat()

Solidity version 0.8.4 introduces bytes.concat() (vs abi.encodePacked(<bytes>,<bytes>))

<ins>Proof Of Concept</ins>
28: bytes memory completeHexString = abi.encodePacked(bytes2(0x1220)

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/libraries/JBIpfsDecoder.sol#L28

34: return string(abi.encodePacked(_baseUri, ipfsHash)

https://github.com/jbx-protocol/juice-nft-rewards/tree/f9893b1497098241dd3a664956d8016ff0d0efd0/contracts/libraries/JBIpfsDecoder.sol#L34

<ins>Recommended Mitigation Steps</ins>

Use bytes.concat() and upgrade to at least Solidity version 0.8.4 if required.

#0 - Picodes

2022-11-08T16:47:09Z

Some invalid stuffs (contracts are not upgradeable, block.timestamp)

#1 - c4-judge

2022-11-08T16:47:15Z

Picodes marked the issue as grade-b

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter