Platform: Code4rena
Start Date: 30/03/2022
Pot Size: $30,000 USDC
Total HM: 21
Participants: 38
Period: 3 days
Judge: Michael De Luca
Total Solo HM: 10
Id: 104
League: ETH
Rank: 12/38
Findings: 4
Award: $1,040.55
🌟 Selected for report: 1
🚀 Solo Findings: 1
🌟 Selected for report: hyh
Also found by: Ruhum, WatchPug, hubble, kirk-baird, leastwood, pedroais, rayn, saian, securerodd
70.1719 USDC - $70.17
The initialize function in CoreCollection.sol is not protected properly and can be called by the Owner multiple times. The modifier onlyUnInitialized() is missing in the intialize() function.
If by mistake wrong/different values of maxSupply, mintFee, or payableToken is set again in the initialize(), then the protocol state will become inconsistent, and any subsequent operations on the contract may cause loss of value depending on the differences in the new values set.
Contract CoreCollection.sol
Function initialize()
Add the modifier onlyUnInitialized() in the initialize() function of the CoreCollection.sol contract
#0 - sofianeOuafir
2022-04-14T19:52:06Z
duplicate of #4
🌟 Selected for report: kirk-baird
Also found by: 0xDjango, Dravee, Ruhum, TomFrenchBlockchain, WatchPug, defsec, hubble, hyh, leastwood, minhquanym
85.0569 USDC - $85.06
https://github.com/code-423n4/2022-03-joyn/blob/c9297ccd925ebb2c44dbc6eaa3effd8db5d2368a/royalty-vault/contracts/RoyaltyVault.sol#L67-L68 https://github.com/code-423n4/2022-03-joyn/blob/c9297ccd925ebb2c44dbc6eaa3effd8db5d2368a/royalty-vault/contracts/RoyaltyVault.sol#L40-L41
(at RoyaltyVault.sol) Presently platformFee, does not have a upper limit and can be set to any value through setPlatformFee function. If the value is set beyond 10,000 it would cause an underflow during split share calculation at sendToSplitter function.
Manual review
#0 - sofianeOuafir
2022-04-14T20:50:19Z
duplicate of #9
🌟 Selected for report: hubble
805.0047 USDC - $805.00
https://github.com/code-423n4/2022-03-joyn/blob/c9297ccd925ebb2c44dbc6eaa3effd8db5d2368a/core-contracts/contracts/CoreCollection.sol#L175-L176 https://github.com/code-423n4/2022-03-joyn/blob/c9297ccd925ebb2c44dbc6eaa3effd8db5d2368a/core-contracts/contracts/ERC721Payable.sol#L54-L55
The below transferFrom command is called at two places in the core contracts, followed by an emit event
payableToken.transferFrom(msg.sender,recipient,_amount) emit ...(...);
The return value is not checked during the payableToken.transferFrom
In the event of failure of payableToken.transferFrom(...), the emit event is still generated causing the downstream applications to capture wrong transaction / state of the protocol.
Contract CoreCollection.sol
function withdraw()
Contract ERC721Payable.sol function _handlePayment
Add a require statement as being used in the RoyaltyVault.sol
require( payableToken.transferFrom(msg.sender,recipient,_amount) == true, "Failed to transfer amount to recipient" );
#0 - sofianeOuafir
2022-04-14T15:15:12Z
In my opinion, the severity level should be 3 (High Risk) instead of 2 (Med Risk) duplicate of #52
#1 - deluca-mike
2022-06-11T21:53:19Z
No longer a duplicate because this issue pertains specifically to the false emission of events when an underlying call would have failed.
80.3226 USDC - $80.32
Issue#1 : Null address input check missing in few functions Issue#2 : No check on upper bound value of platformFee in function setPlatformFee Issue#3 : Unused state variable HASHED_PROOF in CoreCollection.sol Issue#4 : Check for getVaultBalance() is redundant in Contract CoreCollection.sol Issue#5 : Solidity Pragma not fixed to a particular version
Title : Null address input check missing in few functions
Listed below few functions with missing check.
a. Contract CoreCollection.sol, function setRoyaltyVault(address _royaltyVault) b. Contract RoyaltyVault.sol , function setPlatformFeeRecipient (address _platformFeeRecipient)
Add a require statement to check for null address for the input address parameters
Title : No check on upper bound value of platformFee in function setPlatformFee
In contract RoyaltyVault.sol
function setPlatformFee(uint256 _platformFee) external override onlyOwner { platformFee = _platformFee; emit NewRoyaltyVaultPlatformFee(_platformFee); }
There is no check on the upper bound value, and in case of wrong value set, the platformShare and splitterShare values calculated will be affected.
Add a require statement to check for a max value defined.
Title : Unused state variable HASHED_PROOF in CoreCollection.sol
The state variable HASHED_PROOF is defined in the CoreCollection.sol contract and its value is also being set by the function setHashedProof(). However this variable does not seem to be used in any of the contracts.
Remove the unwanted dead code.
Title : Check for getVaultBalance() is redundant in Contract CoreCollection.sol
Contract : CoreCollection.sol function _beforeTokenTransfer(...) Line 305 : IRoyaltyVault(royaltyVault).getVaultBalance() > 0
This check is redundant because, this value for getVaultBalance is again checked in the subsequent call in IRoyaltyVault(royaltyVault).sendToSplitter()
Remove the redundant check from the _beforeTokenTransfer(...) function
Title : Solidity Pragma not fixed to a particular version
Almost all of the contracts are using a floating pragma definition, which is not as per best practice.
pragma solidity ^0.8.0;
Decide on a particular version say 0.8.10 and hardcode it in all the contracts.
pragma solidity 0.8.10;