Platform: Code4rena
Start Date: 26/05/2023
Pot Size: $100,000 USDC
Total HM: 0
Participants: 33
Period: 14 days
Judge: leastwood
Id: 241
League: ETH
Rank: 21/33
Findings: 1
Award: $813.40
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: rbserver
Also found by: 0x73696d616f, 0xTheC0der, 0xdeadbeef, 0xhacksmithh, Bauchibred, GalloDaSballo, KKat7531, Madalad, MohammedRizwan, Rolezn, SAAJ, SanketKogekar, Sathish9098, VictoryGod, brgltd, btk, codeslide, descharre, hunter_w3b, jauvany, kaveyjoe, ladboy233, nadin, niser93, shealtielanz, souilos, trysam2003, yongskiws
813.4016 USDC - $813.40
abi.encodePacked
results in Hash Collision sometimes when two dynamic argumants are encoded with it.>If you use keccak256(abi.encodePacked(a, b)) and both a and b are dynamic types, it is easy to craft collisions in the hash value by moving parts of an into b and vice-versa. More specifically, abi.encodePacked("a", "bc") == abi.encodePacked("ab", "c").
As the solidity docs describe, two or more dynamic types are passed to abi.encodePacked. Moreover, these dynamic values are user-specified function arguments in external functions, meaning anyone can directly specify the value of these arguments when calling the function. Many users can fail an issue while claiming their prizes because of this.
Recommendation : Use abi.encode()
instead of abi.encodePacked()
, which will prevent hash collisions
(*There are several more references of abi.encodePacked()
in the repo)
The timestamp is never accepted in params, so never compared with nextTimestamp()
as described. L1 & L2 block numbers are used instead.
GUARDIAN
should only be able to call pause() when OptimismPortal is unpaused. And similarly, should be able to unpause() when OptimismPortal is paused.Apparently there is no check, and state is changed (reassigned to same value), and event is emitted, which could cause further issues.
donateETH()
function in OptimismPortal accepts ETH and makes no action. So the funds could get stuck. No way to get accidental transfers back. It is better to remove it than making the funcion 'Intentionally empty' as described in comment.depositTransaction()
from OptimismPortal
accepts param _isCreation
which is true if user wants to create a contract, but never validates the _data
(bytecode) used to create the contract.CrossDomainMessenger
, the variable __gap has a comment description :Reserve extra slots in the storage layout for future upgrades. A gap size of 41 was chosen here, so that the first slot used in a child contract would be a multiple of 50.
uint256[42] private __gap;
(Comment says that gap should be of 41, but array size is clearly 42 in declaration)
safeApprove()
) before transfer, which can cause function failure. Make sure sufficient tokens are pre-approved before contract executes the trasfer.L1StandardBridge
contract, the onlyEOA
modifier is never used in depositETHTo()
and depositERC20To()
which I believe should exists, considering the purpose contract wants to accomplish as mentioned in comments on depositETH()
and depositERC20()
#0 - c4-judge
2023-06-16T13:54:54Z
0xleastwood marked the issue as grade-b