try/catch doesn't catch some call errors.
- Dominant language
- C++
- Stars
- 25.7k
- Forks
- 6.2k
- Avg merge
- 2d 19h
- Merged PRs (30d)
- 29
Description
The following code is expected (by a developer using any other language) to catch failures related to the call.
But instead, it reverts.
This is due to the very confusing semantics of the "try/catch" construct in solidity: the catch block will only be called if the actual external code was reverted, but it might still revert in some **compiler-generated** code
```solidity
pragma solidity ^0.8.12;
interface Xface {
function func() external;
}
contract Test {
function run() external {
try Xface(address(0)).func() {
console.log('successfully called');
} catch {
console.log('catch everything');
}
}
}
```
**Suggestion**: solidity should not generate a "revert" code between the try and catch. Instead, it should jump into the catch block.
Currently, the following checks are done by solidity, and it reverts if any of these validation fails:
- if the called method is "void", it first performs `extcodesize`, to validate the target indeed has some code
- if the called method is expected to return something, it validates that `returndatasize` is not zero
- if there are returned values, it decodes them and of course validates they were encoded correctly.
Contributor guide
Research direction
Start by reproducing the Solidity example and tracing the compiler-generated checks between the external call and its try/catch handlers, including extcodesize, returndatasize, and return-data decoding. Done means failures from these checks enter the catch block instead of reverting outside it.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- solidity
- Domain
- blockchain, compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100