Omniscia Gnosis Guild Audit
WriteOnce Manual Review Findings
WriteOnce Manual Review Findings
WOE-01M: Unsafe Casting Operation
Type | Severity | Location |
---|---|---|
Input Sanitization | ![]() | WriteOnce.sol:L110 |
Description:
The WriteOnce::creationBytecodeFor
function will cast the input's length
attribute plus 1
to a uint32
data type without properly evaluating that the length
satisfies the size limitation of the PUSH4
operation code in use by the implementation.
Impact:
A data
payload whose size exceeds the type(uint32).max
limitation will successfully execute but truncate the data
whenever it is read.
Example:
93function creationBytecodeFor(94 bytes memory data95) private pure returns (bytes memory) {96 /*97 0x00 0x63 0x63XXXXXX PUSH4 _code.length size98 0x01 0x80 0x80 DUP1 size size99 0x02 0x60 0x600e PUSH1 14 14 size size100 0x03 0x60 0x6000 PUSH1 00 0 14 size size101 0x04 0x39 0x39 CODECOPY size102 0x05 0x60 0x6000 PUSH1 00 0 size103 0x06 0xf3 0xf3 RETURN104 <CODE>105*/106
107 return108 abi.encodePacked(109 hex"63",110 uint32(data.length + 1),111 hex"80_60_0E_60_00_39_60_00_F3",112 // Append 00 to data so contract can't be called113 hex"00",114 data115 );116}
Recommendation:
We advise the data.length + 1
value to be ensured as fitting within an unsigned integer of 32-bits by ensuring that it is less-than-or-equal-to type(uint32).max
. To note, Solidity's built-in safe arithmetic in post-0.8.X
versions does not guarantee casting operations which need to be manually guarded.
Alleviation:
The Gnosis Guild team evaluated this exhibit but has opted not to apply a remediation for it as they do not foresee a production use case where an exploit would manifest as a result of this misbehaviour.
As such, we consider this exhibit safely acknowledged.