Skip to content

Commit 2346ec2

Browse files
committed
fix: unknown solidity custom errors and packing failures
1 parent 96790da commit 2346ec2

3 files changed

Lines changed: 30 additions & 2 deletions

File tree

precompiles/common/errors.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ const (
3333
ErrInvalidDescription = "invalid description: %v"
3434
// ErrInvalidCommission is raised when the input commission cannot be cast to stakingtypes.CommissionRates{}.
3535
ErrInvalidCommission = "invalid commission: %v"
36+
// ErrUnknownSolidityCustomError is raised when the ABI does not contain the provided custom error.
37+
ErrUnknownSolidityCustomError = "unknown solidity custom error: %s"
38+
// ErrPackSolidityCustomErrorFailed is raised when ABI packing custom error args fails.
39+
ErrPackSolidityCustomErrorFailed = "failed to pack solidity custom error %s: %s"
3640

3741
// SolidityErrInvalidNumberOfArgs is invalid number of arguments
3842
SolidityErrInvalidNumberOfArgs = "InvalidNumberOfArgs"

precompiles/common/revert.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package common
22

33
import (
44
"errors"
5+
"fmt"
56

67
"github.com/ethereum/go-ethereum/accounts/abi"
78
"github.com/ethereum/go-ethereum/core/vm"
@@ -33,7 +34,7 @@ func (e *RevertWithData) RevertData() []byte {
3334
func NewRevertWithSolidityError(moduleABI abi.ABI, errorName string, args ...interface{}) error {
3435
customErr, ok := moduleABI.Errors[errorName]
3536
if !ok {
36-
reason := "unknown solidity custom error: " + errorName
37+
reason := fmt.Sprintf(ErrUnknownSolidityCustomError, errorName)
3738
revertReasonBz, encErr := evmtypes.RevertReasonBytes(reason)
3839
if encErr != nil {
3940
return errors.New(reason)
@@ -43,7 +44,12 @@ func NewRevertWithSolidityError(moduleABI abi.ABI, errorName string, args ...int
4344

4445
data, err := customErr.Inputs.Pack(args...)
4546
if err != nil {
46-
return err
47+
reason := fmt.Sprintf(ErrPackSolidityCustomErrorFailed, errorName, err.Error())
48+
revertReasonBz, encErr := evmtypes.RevertReasonBytes(reason)
49+
if encErr != nil {
50+
return errors.New(reason)
51+
}
52+
return &RevertWithData{data: revertReasonBz}
4753
}
4854
return &RevertWithData{data: append(customErr.ID[:4], data...)}
4955
}

precompiles/common/revert_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"math/big"
66
"testing"
77

8+
"github.com/ethereum/go-ethereum/accounts/abi"
89
"github.com/ethereum/go-ethereum/common"
910
"github.com/ethereum/go-ethereum/core/vm"
1011
"github.com/ethereum/go-ethereum/params"
@@ -36,3 +37,20 @@ func TestReturnRevertError_WithStringFallback(t *testing.T) {
3637
require.ErrorIs(t, err, vm.ErrExecutionReverted)
3738
require.NotEmpty(t, ret)
3839
}
40+
41+
func TestReturnRevertError_WhenSolidityErrorPackFails_FallsBackToErrorStringRevert(t *testing.T) {
42+
stateDB := statedbmocks.NewStateDB(t)
43+
evm := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1), Time: 1}, stateDB, params.TestChainConfig, vm.Config{})
44+
45+
// RequesterIsNotMsgSender(address,address) expects 2 args; provide 1 wrong-typed arg to force ABI pack failure.
46+
customErr := cmn.NewRevertWithSolidityError(staking.ABI, "RequesterIsNotMsgSender", 123)
47+
ret, err := cmn.ReturnRevertError(evm, customErr)
48+
49+
require.ErrorIs(t, err, vm.ErrExecutionReverted)
50+
require.NotEmpty(t, ret)
51+
require.Equal(t, ret, evm.ReturnData())
52+
53+
reason, unpackErr := abi.UnpackRevert(ret)
54+
require.NoError(t, unpackErr)
55+
require.Contains(t, reason, "failed to pack solidity custom error RequesterIsNotMsgSender")
56+
}

0 commit comments

Comments
 (0)