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: 5/38
Findings: 4
Award: $2,029.35
π Selected for report: 2
π Solo Findings: 0
724.5042 USDC - $724.50
The CoreCollection.withdraw
function uses payableToken.transferFrom(address(this), msg.sender, amount)
to transfer tokens from the CoreCollection
contract to the msg.sender
( who is the owner of the contract). The usage of transferFrom
can result in serious issues. In fact, many ERC20 always require that in transferFrom
allowance[from][msg.sender] >= amount
, so in this case the call to the withdraw
function will revert as the allowance[CoreCollection][CoreCollection] == 0
and therefore the funds cannot ben withdrawn and will be locked forever in the contract.
Recommendation : replace transferFrom
with transfer
#0 - sofianeOuafir
2022-04-15T12:58:59Z
duplicate of #52
#1 - deluca-mike
2022-06-11T21:56:37Z
This is not a duplicate, as it pertains to the wrong use of transfer vs transferFrom, which can have implications regarding required allowances.
1207.507 USDC - $1,207.51
https://github.com/code-423n4/2022-03-joyn/blob/main/royalty-vault/contracts/RoyaltyVault.sol#L43-L46 https://github.com/code-423n4/2022-03-joyn/blob/main/royalty-vault/contracts/RoyaltyVault.sol#L51-L57
Although the ERC20 standard suggests that a transfer should return true on success, many tokens are non-compliant in this regard (including high profile, like USDT) . In that case, the .transfer() call here will revert even if the transfer is successful, because solidity will check that the RETURNDATASIZE matches the ERC20 interface.
Recommendation: Consider using OpenZeppelinβs SafeERC20
#0 - sofianeOuafir
2022-04-14T18:31:04Z
duplicate of #52
#1 - deluca-mike
2022-06-11T22:02:26Z
Actually not a duplicate of #52, since it pertains to return data size handling causing an issue, rather than failure to handle a true/false return at all. Still, same solution (use SafeERC20).
62.0706 USDC - $62.07
Splitter.transferSplitAsset
as the function is transfering ERC20 token and not ETH.35.2728 USDC - $35.27
CoreCollection
: onlyUnInitialized
and tokenExists
modifier are declared but never used.CoreCollection
: the internal function _baseURI
is declared but never used.CoreCollection.setStartingIndex()
function can be priavte. (no need to be public)ERC721Payable
: onlyVaultInitialized
modifier is declared but never used.Splitter
: attemptETHTransfer
and amountFromPercent
functions are declared but never used.unchecked
block can be used for all the for loops. Consider adding an internal function _increment
with an unchecked block and use it to increment the counter inside the for loop.