Skip to content

Commit

Permalink
preprocess non-compliant ABIs
Browse files Browse the repository at this point in the history
  • Loading branch information
chen4903 committed Aug 18, 2024
1 parent 710c3f3 commit c771b8b
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 1 deletion.
96 changes: 95 additions & 1 deletion accounts/abi/abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"fmt"
"io"
"math/big"
"strings"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
Expand All @@ -44,9 +45,100 @@ type ABI struct {
Receive Method
}

// Define the PreComponent struct to represent the inner components
type PreComponent struct {
InternalType string `json:"internalType"`
Name string `json:"name"`
Type string `json:"type"`
Components []PreComponent `json:"components,omitempty"`
}

// Define the PreInput struct which can contain Components
type PreInput struct {
Components []PreComponent `json:"components,omitempty"`
InternalType string `json:"internalType"`
Name string `json:"name"`
Type string `json:"type"`
}

// Define the PreFunction struct to represent the overall function structure
type PreFunction struct {
Inputs []PreInput `json:"inputs,omitempty"`
Name string `json:"name"`
Outputs []PreComponent `json:"outputs,omitempty"`
StateMutability string `json:"stateMutability"`
Type string `json:"type"`
}

// modifyComponent recursively checks and modifies the type field for Components
func modifyComponent(component *PreComponent, modified *bool) {
if strings.Contains(component.InternalType, "contract") {
// If internalType contains "contract", set type to "address"
component.Type = "address"
*modified = true
}
for i := range component.Components {
modifyComponent(&component.Components[i], modified)
}
}

// modifyInput recursively checks and modifies the type field for Inputs
func modifyInput(input *PreInput, modified *bool) {
if strings.Contains(input.InternalType, "contract") {
// If internalType contains "contract", set type to "address"
input.Type = "address"
*modified = true
}
for i := range input.Components {
modifyComponent(&input.Components[i], modified)
}
}

// preProcessing The ABI parameters that do not conform to the specification are corrected.
func preProcessing(reader io.Reader) (io.Reader, error) {
jsonStr, err := io.ReadAll(reader)
if err != nil {
return nil, err
}

var functions []PreFunction
// Unmarshal the JSON string into a slice of Function structs
err = json.Unmarshal([]byte(string(jsonStr)), &functions)
if err != nil {
return nil, err
}

modified := false

// Iterate over each function and modify its inputs
for i := range functions {
for j := range functions[i].Inputs {
modifyInput(&functions[i].Inputs[j], &modified)
}
}

// If no modifications were made, return the original JSON string
if !modified {
return strings.NewReader(string(jsonStr)), nil
}

// Marshal the modified functions back to a JSON string
modifiedJSON, err := json.Marshal(functions)
if err != nil {
return nil, err
}

return strings.NewReader(string(modifiedJSON)), nil
}

// JSON returns a parsed ABI interface and error if it failed.
func JSON(reader io.Reader) (ABI, error) {
dec := json.NewDecoder(reader)
preReader, err := preProcessing(reader)
if err != nil {
return ABI{}, err
}

dec := json.NewDecoder(preReader)

var abi ABI
if err := dec.Decode(&abi); err != nil {
Expand All @@ -55,6 +147,8 @@ func JSON(reader io.Reader) (ABI, error) {
return abi, nil
}

//////////////////////////////////////////////////////////////////////

// Pack the given method name to conform the ABI. Method call's data
// will consist of method_id, args0, arg1, ... argN. Method id consists
// of 4 bytes and arguments are all 32 bytes.
Expand Down
9 changes: 9 additions & 0 deletions accounts/abi/abi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1218,3 +1218,12 @@ func TestUnpackRevert(t *testing.T) {
})
}
}


func TestPreProcessing(t *testing.T){
jsonData := `[{"inputs":[{"components":[{"internalType":"uint256","name":"dailyLimit","type":"uint256"},{"internalType":"uint256","name":"txLimit","type":"uint256"},{"internalType":"uint256","name":"accountDailyLimit","type":"uint256"},{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"bool","name":"onlyWhitelisted","type":"bool"}],"internalType":"struct IMessagePassingBridge.BridgeLimits","name":"bridgeLimits","type":"tuple"},{"components":[{"internalType":"uint256","name":"lastTransferReset","type":"uint256"},{"internalType":"uint256","name":"bridged24Hours","type":"uint256"}],"internalType":"struct IMessagePassingBridge.AccountLimit","name":"accountDailyLimit","type":"tuple"},{"components":[{"internalType":"uint256","name":"lastTransferReset","type":"uint256"},{"internalType":"uint256","name":"bridged24Hours","type":"uint256"}],"internalType":"struct IMessagePassingBridge.BridgeDailyLimit","name":"bridgeDailyLimit","type":"tuple"},{"internalType":"contract INameService","name":"nameService","type":"INameService"},{"internalType":"bool","name":"isClosed","type":"bool"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"canBridge","outputs":[{"internalType":"bool","name":"isWithinLimit","type":"bool"},{"internalType":"string","name":"error","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"normalizeFrom18ToTokenDecimals","outputs":[{"internalType":"uint256","name":"normalized","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"normalizeFromTokenTo18Decimals","outputs":[{"internalType":"uint256","name":"normalized","type":"uint256"}],"stateMutability":"pure","type":"function"}]`
_, err := JSON(strings.NewReader(jsonData))
if err != nil {
t.Fatal("ERROR:", err)
}
}

0 comments on commit c771b8b

Please sign in to comment.