Omniscia Gnosis Guild Audit

WriteOnce Manual Review Findings

WriteOnce Manual Review Findings

WOE-01M: Unsafe Casting Operation

TypeSeverityLocation
Input SanitizationWriteOnce.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:

packages/evm/contracts/WriteOnce.sol
93function creationBytecodeFor(
94 bytes memory data
95) private pure returns (bytes memory) {
96 /*
97 0x00 0x63 0x63XXXXXX PUSH4 _code.length size
98 0x01 0x80 0x80 DUP1 size size
99 0x02 0x60 0x600e PUSH1 14 14 size size
100 0x03 0x60 0x6000 PUSH1 00 0 14 size size
101 0x04 0x39 0x39 CODECOPY size
102 0x05 0x60 0x6000 PUSH1 00 0 size
103 0x06 0xf3 0xf3 RETURN
104 <CODE>
105*/
106
107 return
108 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 called
113 hex"00",
114 data
115 );
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.