Skip to content

Instantly share code, notes, and snippets.

@pcaversaccio
Created December 16, 2022 16:04
Show Gist options
  • Save pcaversaccio/e1aebf9222424e9c1fbc82b8bf5fea8b to your computer and use it in GitHub Desktop.
Save pcaversaccio/e1aebf9222424e9c1fbc82b8bf5fea8b to your computer and use it in GitHub Desktop.
A simple Solidity PoC contract to showcase how revert strings are ABI encoded.
// SPDX-License-Identifier: WTFPL
pragma solidity 0.8.17;
/**
* @dev A simple contract that reverts.
*/
contract Revert {
function revertWithoutReason() external pure {
// solhint-disable-next-line reason-string
revert();
}
function revertWithEmptyReason() external pure {
revert("");
}
}
/**
* @dev A string in Solidity is length prefixed with its 256-bit (32 byte) length.
* To check whether there is a revert reason now, you must check whether the return
* data is smaller than 68 bytes. Why? Well, if there is a revert reason we get the
* following ABI-based encoding:
* - 4-byte function selector of `Error(string)` which is `0x08c379a`,
* - 32-byte string offset (where to find information about the string),
* - 32-byte length prefix,
* - x-bytes string message (=revert reason).
*/
contract StringEncodingReturnData {
Revert private revertContract = new Revert();
function revertWithoutReason() external view returns (bool, bytes memory, uint256) {
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returnData) =
address(revertContract).staticcall(abi.encodeWithSelector(revertContract.revertWithoutReason.selector));
/**
* @return success false
* @return returnData 0x
* @return returnData.length 0
*/
return (success, returnData, returnData.length);
}
function revertWithEmptyReason() external view returns (bool, bytes memory, uint256) {
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returnData) =
address(revertContract).staticcall(abi.encodeWithSelector(revertContract.revertWithEmptyReason.selector));
/**
* @return success false
* @return returnData 0x08c379a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000
* @return returnData.length 68
*/
return (success, returnData, returnData.length);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment