Skip to content

Commit

Permalink
Handle common cases for smart contract errors according to EIP 838 (#…
Browse files Browse the repository at this point in the history
…7155)

* handle smart contracts errors `Error(string)` and `Panic(uint256)`

* add tests

* update CHANGELOG.md
  • Loading branch information
Muhammad-Altabba authored Sep 5, 2024
1 parent 9b32205 commit 7a6e492
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 2 deletions.
5 changes: 4 additions & 1 deletion packages/web3-eth-abi/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,7 @@ Documentation:

- fix encodedata in EIP-712 (#7095)

## [Unreleased]
## [Unreleased]

### Added
- Handle common cases for smart contract errors according to EIP 838: `0x4e487b71` which is the ‘selector’ for `Panic(uint256)` and `0x08c379a0` is the ‘selector’ of `Error(string)`. (7155)
30 changes: 30 additions & 0 deletions packages/web3-eth-abi/src/decode_contract_error_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,36 @@ export const decodeContractErrorData = (
errorSignature = jsonInterfaceMethodToString(errorAbi);
// decode abi.inputs according to EIP-838
errorArgs = decodeParameters([...errorAbi.inputs], error.data.substring(10));
} else if (error.data.startsWith('0x08c379a0')) {
// If ABI was not provided, check for the 2 famous errors: 'Error(string)' or 'Panic(uint256)'

errorName = 'Error';
errorSignature = 'Error(string)';
// decode abi.inputs according to EIP-838
errorArgs = decodeParameters(
[
{
name: 'message',
type: 'string',
},
],
error.data.substring(10),
);
} else if (error.data.startsWith('0x4e487b71')) {
errorName = 'Panic';
errorSignature = 'Panic(uint256)';
// decode abi.inputs according to EIP-838
errorArgs = decodeParameters(
[
{
name: 'code',
type: 'uint256',
},
],
error.data.substring(10),
);
} else {
console.error('No matching error abi found for error data', error.data);
}
} catch (err) {
console.error(err);
Expand Down
34 changes: 34 additions & 0 deletions packages/web3-eth-abi/test/fixtures/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,40 @@ export const validDecodeContractErrorData: {
input: any[];
output: any;
}[] = [
{
input: [
[],
{
code: 12,
message: 'message',
data: '0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000155468697320697320612063616c6c207265766572740000000000000000000000',
},
],
output: {
errorName: 'Error',
errorSignature: 'Error(string)',
errorArgs: {
message: 'This is a call revert',
},
},
},
{
input: [
[],
{
code: 12,
message: 'message',
data: '0x4e487b71000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000',
},
],
output: {
errorName: 'Panic',
errorSignature: 'Panic(uint256)',
errorArgs: {
code: 42,
},
},
},
{
input: [
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ describe('decodeContractErrorData', () => {
expect(err.errorName).toEqual(output.errorName);
expect(err.errorSignature).toEqual(output.errorSignature);
expect(err.errorArgs?.message).toEqual(output.errorArgs?.message);
expect(Number(err.errorArgs?.code)).toEqual(output.errorArgs?.code);

// This ensures they are equal if one was provided
// It also skips if both are not provided
if (err.errorArgs?.code || output.errorArgs?.code) {
// eslint-disable-next-line jest/no-conditional-expect
expect(Number(err.errorArgs?.code)).toEqual(output.errorArgs?.code);
}
expect(err.cause?.code).toEqual(output.cause?.code);
},
);
Expand Down

1 comment on commit 7a6e492

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 7a6e492 Previous: 9b32205 Ratio
processingTx 22522 ops/sec (±8.59%) 23392 ops/sec (±7.52%) 1.04
processingContractDeploy 39622 ops/sec (±7.51%) 40479 ops/sec (±6.69%) 1.02
processingContractMethodSend 17407 ops/sec (±7.00%) 16317 ops/sec (±6.87%) 0.94
processingContractMethodCall 28383 ops/sec (±7.80%) 27614 ops/sec (±8.40%) 0.97
abiEncode 46331 ops/sec (±6.95%) 46686 ops/sec (±6.17%) 1.01
abiDecode 31565 ops/sec (±7.20%) 31121 ops/sec (±7.84%) 0.99
sign 1592 ops/sec (±0.56%) 1556 ops/sec (±0.91%) 0.98
verify 371 ops/sec (±2.76%) 369 ops/sec (±0.48%) 0.99

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.