Severity: High
Impact Range: ERC4337 and the infrastructure built on it
My Report Link: https://github.com/eth-infinitism/account-abstraction/issues/237
The bug will lead to incorrect UserOperation hash calculation in ERC4337 entrypoint contract v0.5.
The contract calculates the hash directly from the calldata. However, Solidity doesn’t not enforce the calldata encoding. That means an attacker can add dummy data in the calldata and then generate different hash for the same UserOperation.
function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {
//lighter signature scheme. must match UserOp.ts#packUserOp
bytes calldata sig = userOp.signature;
// copy directly the userOp from calldata up to (but not including) the signature.
// this encoding depends on the ABI encoding of calldata, but is much lighter to copy
// than referencing each field separately.
assembly {
let ofs := userOp
let len := sub(sub(sig.offset, ofs), 32)
ret := mload(0x40)
mstore(0x40, add(ret, add(len, 32)))
mstore(ret, len)
calldatacopy(add(ret, 32), ofs, len)
}
}
The entrypoint contract has upgraded to v0.6 to resolve this issue.