Platform: Code4rena
Start Date: 04/03/2024
Pot Size: $140,000 USDC
Total HM: 19
Participants: 69
Period: 21 days
Judge: 0xean
Total Solo HM: 4
Id: 343
League: ETH
Rank: 60/69
Findings: 1
Award: $33.54
π Selected for report: 0
π Solo Findings: 0
π Selected for report: MrPotatoMagic
Also found by: 0x11singh99, DadeKuma, Fassi_Security, JCK, Kalyan-Singh, Masamune, Myd, Pechenite, Sathish9098, Shield, albahaca, alexfilippov314, cheatc0d3, clara, foxb868, grearlake, hihen, imare, joaovwfreire, josephdara, ladboy233, monrel, n1punp, oualidpro, pa6kuda, pfapostol, rjs, slvDev, sxima, t0x1c, t4sk, zabihullahazadzoi
33.5408 USDC - $33.54
https://github.com/code-423n4/2024-03-taiko/blob/a30b5b6afd121e4de8ceff7165a2091e62194992/packages/protocol/contracts/bridge/IBridge.sol#L60-L64 https://github.com/code-423n4/2024-03-taiko/blob/a30b5b6afd121e4de8ceff7165a2091e62194992/packages/protocol/contracts/bridge/Bridge.sol#L29-L48
Possible storage collision Impact - High Chances - Low to medium Severity - medium
__gap
variable is used in upgradeble contracts to ensure that any new variable if added in parent or child contract does not collide with any other previously used storage slot. Hence its size must clearly defined, which Taiko contracts do except in Bridge.sol
, in the mentioned file they have assumed that Context
struct uses 3 slots but it only uses 2 slots.
struct Context { bytes32 msgHash; // Message hash. address from; // 20 bytes uint64 srcChainId; ///@audit 8 bytes , 20 + 8 bytes will be packed in 1 slot }
This wrong assumption has lead to incorrect allotment size to __gap array, which should be 44 instead of 43.
It can also be verified by running
forge inspect contracts/bridge/Bridge.sol:Bridge storage --pretty
Manual Review
/// @notice The next message ID. /// @dev Slot 1. uint128 public nextMessageId; /// @notice Mapping to store the status of a message from its hash. /// @dev Slot 2. mapping(bytes32 msgHash => Status status) public messageStatus; -- /// @dev Slots 3, 4, and 5. ++ /// @audit Slots 3,4 Context private __ctx; /// @notice Mapping to store banned addresses. -- /// @dev Slot 6. ++ /// @audit slot 5 mapping(address addr => bool banned) public addressBanned; /// @notice Mapping to store the proof receipt of a message from its hash. -- /// @dev Slot 7. ++ /// @audit slot 6 mapping(bytes32 msgHash => ProofReceipt receipt) public proofReceipt; -- uint256[43] private __gap; ++ uint256[44] private __gap;
Some real world hacks and previous findings explaining why consistent gap size is important- audius hack , finding 1 , finding 2
Upgradable
#0 - c4-pre-sort
2024-03-28T19:12:20Z
minhquanym marked the issue as sufficient quality report
#1 - dantaik
2024-04-02T03:17:20Z
#2 - c4-sponsor
2024-04-02T03:17:26Z
dantaik marked the issue as disagree with severity
#3 - c4-sponsor
2024-04-02T03:17:29Z
dantaik (sponsor) confirmed
#4 - c4-judge
2024-04-09T22:23:53Z
0xean changed the severity to QA (Quality Assurance)
#5 - c4-judge
2024-04-10T10:51:40Z
0xean marked the issue as grade-b