Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add LibErrorHandler #4

Merged
merged 2 commits into from
Nov 20, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/LibErrorHandler.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

library LibErrorHandler {
/// @dev Reserves error definition to upload to signature database.
error ExternalCallFailed(bytes4 msgSig, bytes4 callSig);

/// @notice handle low level call revert if call failed,
/// If extcall return empty bytes, reverts with custom error.
/// @param status Status of external call
/// @param callSig function signature of the calldata
/// @param returnOrRevertData bytes result from external call
function handleRevert(bool status, bytes4 callSig, bytes memory returnOrRevertData) internal pure {
// Get the function signature of current context
bytes4 msgSig = msg.sig;
assembly ("memory-safe") {
if iszero(status) {
// Load the length of bytes array
let revertLength := mload(returnOrRevertData)
// Check if length != 0 => revert following reason from external call
if iszero(iszero(revertLength)) {
// Start of revert data bytes. The 0x20 offset is always the same.
revert(add(returnOrRevertData, 0x20), revertLength)
}

// Load free memory pointer
let ptr := mload(0x40)
// Store 4 bytes the function selector of ExternalCallFailed(msg.sig, callSig)
// Equivalent to revert ExternalCallFailed(bytes4,bytes4)
mstore(ptr, 0x49bf4104)
// Store 4 bytes of msgSig parameter in the next slot
mstore(add(ptr, 0x20), msgSig)
// Store 4 bytes of callSig parameter in the next slot
mstore(add(ptr, 0x40), callSig)
// Revert 68 bytes of error starting from 0x1c
revert(add(ptr, 0x1c), 0x44)
}
}
}
}