What does revert(add(32, data), datasize) really do? Why 32?

I have seen the revert(add(32, data), datasize) in multiple contracts in Openzeppelin library. However, I fail to understand what it actually does. It just reverts while returning datasize bytes from the offset add(32, data)? But why? Why do we use 32?

:1234: Code to reproduce

Following is the code from Address.sol:

 function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }

When data is a bytes array in memory, it's a pointer that points to the length of the array followed by the array contents. The length of the array is always 32 bytes, mload(data) will read the length. The data will begin at data + 32.

revert(a, len) will revert with returndata set to the bytes starting at a with length l. This will contain for example the revert reason.

revert(add(32, data), mload(data)) is just saying to revert with the data from the data array.

1 Like