Created
December 16, 2022 16:04
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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