From 96342b0771ad3f5a1491ed12cac8afa6222789ab Mon Sep 17 00:00:00 2001 From: Michael Standen Date: Fri, 22 Nov 2024 14:32:34 +1300 Subject: [PATCH] v2 signature decoding validates EIP-6492 signatures --- core/v2/v2.go | 35 +++++++++++++---------------------- eip6492/eip6492.go | 24 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/core/v2/v2.go b/core/v2/v2.go index 7d84571..5d1c4de 100644 --- a/core/v2/v2.go +++ b/core/v2/v2.go @@ -10,14 +10,12 @@ import ( "io" "math/big" - "github.com/0xsequence/ethkit/ethcontract" "github.com/0xsequence/ethkit/ethrpc" - "github.com/0xsequence/ethkit/go-ethereum/accounts/abi/bind" "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" "github.com/0xsequence/ethkit/go-ethereum/crypto" - "github.com/0xsequence/go-sequence/contracts" "github.com/0xsequence/go-sequence/core" + "github.com/0xsequence/go-sequence/eip6492" ) const ( @@ -25,8 +23,6 @@ const ( subdigestLeafImageHashPrefix = "Sequence static digest:\n" ) -var isValidSignatureMagicValue = [4]byte{0x16, 0x26, 0xba, 0x7e} - var Core core.Core[*WalletConfig, core.Signature[*WalletConfig]] = v2Core{} func init() { @@ -1055,27 +1051,22 @@ func (l *signatureTreeDynamicSignatureLeaf) recover(ctx context.Context, subdige case dynamicSignatureTypeEIP1271: effectiveWeight := l.weight + signature := l.signature if provider != nil { - contract := ethcontract.NewContractCaller(l.address, contracts.IERC1271.ABI, provider) - - var results []any - err := contract.Call(&bind.CallOpts{Context: ctx}, &results, "isValidSignature", subdigest.Hash, l.signature) + isValid, err := eip6492.ValidateEIP6492Offchain(ctx, provider, l.address, subdigest.Hash, signature, nil) if err != nil { - return nil, nil, fmt.Errorf("unable to call isValidSignature on %v: %w", l.address, err) - } - - if len(results) != 1 { - return nil, nil, fmt.Errorf("expected single return value from isValidSignature, got %v", len(results)) + return nil, nil, fmt.Errorf("unable to validate signature for %v: %w", l.address, err) } - - magicValue, ok := results[0].([4]byte) - if !ok { - return nil, nil, fmt.Errorf("expected [4]byte return value from isValidSignature, got %T", results[0]) + if !isValid { + return nil, nil, fmt.Errorf("invalid eip1271 signature for %v", l.address) } - - if magicValue != isValidSignatureMagicValue { - return nil, nil, fmt.Errorf("isValidSignature returned %v, expected %v", hexutil.Encode(magicValue[:]), hexutil.Encode(isValidSignatureMagicValue[:])) + if eip6492.IsEIP6492Signature(signature) { + // Decode the signature and use the nested signature for config recovery + _, _, signature, err = eip6492.DecodeEIP6492Signature(signature) + if err != nil { + return nil, nil, fmt.Errorf("unable to decode eip6492 signature: %w", err) + } } } else { // Set the effective weight to 0 @@ -1087,7 +1078,7 @@ func (l *signatureTreeDynamicSignatureLeaf) recover(ctx context.Context, subdige signerSignatures.Insert(l.address, core.SignerSignature{ Subdigest: subdigest, Type: l.type_.signerSignatureType(), - Signature: l.signature, + Signature: signature, }) return &WalletConfigTreeAddressLeaf{ diff --git a/eip6492/eip6492.go b/eip6492/eip6492.go index 864ca15..ab0937c 100644 --- a/eip6492/eip6492.go +++ b/eip6492/eip6492.go @@ -3,6 +3,7 @@ package eip6492 import ( "bytes" "context" + "fmt" "math/big" "github.com/0xsequence/ethkit/ethcoder" @@ -189,6 +190,29 @@ const EIP_6492_SUFFIX = "0x64926492649264926492649264926492649264926492649264926 var EIP6492MagicBytes = hexutil.MustDecode(EIP_6492_SUFFIX) +func IsEIP6492Signature(signature []byte) bool { + return bytes.HasSuffix(signature, EIP6492MagicBytes) +} + +func DecodeEIP6492Signature(signature []byte) (common.Address, []byte, []byte, error) { + if !IsEIP6492Signature(signature) { + return common.Address{}, nil, nil, fmt.Errorf("not an eip6492 signature") + } + + // Strip the magic bytes + signature = signature[:len(signature)-32] + + var create2Factory common.Address + var factoryCalldata []byte + var sigToValidate []byte + + if err := ethcoder.AbiDecoder([]string{"address", "bytes", "bytes"}, signature, []interface{}{&create2Factory, &factoryCalldata, &sigToValidate}); err != nil { + return common.Address{}, nil, nil, err + } + + return create2Factory, factoryCalldata, sigToValidate, nil +} + func ValidateEIP6492Offchain( ctx context.Context, provider *ethrpc.Provider,