Category: Business Logic
Zero-value entityID allows wallet rebinding
Low Impact
Low Severity
Low Likelihood
Description
The walletToEntityID treats bytes16(0) as unbound, yet entityID = 0 is a valid permit. A wallet that first deposits with entity 0 gets stored as zero, but later checks still see it as unbound and allow another permit with a nonzero entity. The same wallet can therefore bind to multiple entity IDs, breaking the promised 1:1 mapping.
function deposit(uint256 amount, PurchasePermit calldata permit, bytes calldata permitSignature) external {
bytes16 entityID = permit.entityID;
...
bytes16 existingEntityID = walletToEntityID[msg.sender];
if (existingEntityID != bytes16(0) && existingEntityID != entityID) {
revert WalletAlreadyBound(msg.sender, existingEntityID);
}
...
walletToEntityID[msg.sender] = entityID;
}Impact
An attacker can reuse a single wallet to deposit under multiple entity IDs, enabling allocation circumvention and bypassing the intended one-wallet-per-entity constraint.
Recommendations
Consider adding a check to block zero entityID.
Remediation
This issue has been acknowledged by MegaETH, and a fix was implemented in commit 776da3c9↗.