Improve parsing of ETH input data
This commit is contained in:
parent
5652ca6b2e
commit
a81420fc94
@ -76,7 +76,8 @@ func decamel(s string) string {
|
|||||||
b.WriteByte(' ')
|
b.WriteByte(' ')
|
||||||
}
|
}
|
||||||
b.WriteRune(v)
|
b.WriteRune(v)
|
||||||
splittable = unicode.IsLower(v) || unicode.IsNumber(v)
|
// special handling of ETH to be able to convert "addETHToContract" to "Add ETH To Contract"
|
||||||
|
splittable = unicode.IsLower(v) || unicode.IsNumber(v) || (i >= 2 && s[i-2:i+1] == "ETH")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return b.String()
|
return b.String()
|
||||||
@ -98,7 +99,7 @@ func GetSignatureFromData(data string) uint32 {
|
|||||||
|
|
||||||
const ErrorTy byte = 255
|
const ErrorTy byte = 255
|
||||||
|
|
||||||
func processParam(data string, index int, t *abi.Type, processed []bool) ([]string, int, bool) {
|
func processParam(data string, index int, dataOffset int, t *abi.Type, processed []bool) ([]string, int, bool) {
|
||||||
var retval []string
|
var retval []string
|
||||||
d := index << 6
|
d := index << 6
|
||||||
if d+64 > len(data) {
|
if d+64 > len(data) {
|
||||||
@ -140,7 +141,7 @@ func processParam(data string, index int, t *abi.Type, processed []bool) ([]stri
|
|||||||
for i := 0; i < t.Size; i++ {
|
for i := 0; i < t.Size; i++ {
|
||||||
var r []string
|
var r []string
|
||||||
var ok bool
|
var ok bool
|
||||||
r, index, ok = processParam(data, index, t.Elem, processed)
|
r, index, ok = processParam(data, index, dataOffset, t.Elem, processed)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, 0, false
|
return nil, 0, false
|
||||||
}
|
}
|
||||||
@ -156,7 +157,7 @@ func processParam(data string, index int, t *abi.Type, processed []bool) ([]stri
|
|||||||
processed[index] = true
|
processed[index] = true
|
||||||
index++
|
index++
|
||||||
offset <<= 1
|
offset <<= 1
|
||||||
d = int(offset)
|
d = int(offset) + dataOffset
|
||||||
dynIndex := d >> 6
|
dynIndex := d >> 6
|
||||||
if d+64 > len(data) || d < 0 {
|
if d+64 > len(data) || d < 0 {
|
||||||
return nil, 0, false
|
return nil, 0, false
|
||||||
@ -195,10 +196,11 @@ func processParam(data string, index int, t *abi.Type, processed []bool) ([]stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
newOffset := dataOffset + dynIndex<<6
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
var r []string
|
var r []string
|
||||||
var ok bool
|
var ok bool
|
||||||
r, dynIndex, ok = processParam(data, dynIndex, t.Elem, processed)
|
r, dynIndex, ok = processParam(data, dynIndex, newOffset, t.Elem, processed)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, 0, false
|
return nil, 0, false
|
||||||
}
|
}
|
||||||
@ -222,7 +224,7 @@ func tryParseParams(data string, params []string, parsedParams []abi.Type) []bch
|
|||||||
var ok bool
|
var ok bool
|
||||||
for i := range params {
|
for i := range params {
|
||||||
t := &parsedParams[i]
|
t := &parsedParams[i]
|
||||||
values, index, ok = processParam(data, index, t, processed)
|
values, index, ok = processParam(data, index, 0, t, processed)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -244,7 +246,7 @@ func ParseInputData(signatures *[]bchain.FourByteSignature, data string) *bchain
|
|||||||
if len(data) <= 2 { // data is empty or 0x
|
if len(data) <= 2 { // data is empty or 0x
|
||||||
return &bchain.EthereumParsedInputData{Name: "Transfer"}
|
return &bchain.EthereumParsedInputData{Name: "Transfer"}
|
||||||
}
|
}
|
||||||
if len(data) < 10 || (len(data)-10)%64 != 0 {
|
if len(data) < 10 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
parsed := bchain.EthereumParsedInputData{
|
parsed := bchain.EthereumParsedInputData{
|
||||||
|
|||||||
@ -112,7 +112,7 @@ func TestParseInputData(t *testing.T) {
|
|||||||
Parameters: []string{"address"},
|
Parameters: []string{"address"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "addLiquidityETH",
|
Name: "addLiquidityETHToContract",
|
||||||
Parameters: []string{"address", "uint256", "uint256", "uint256", "address", "uint256"},
|
Parameters: []string{"address", "uint256", "uint256", "uint256", "address", "uint256"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -131,6 +131,10 @@ func TestParseInputData(t *testing.T) {
|
|||||||
Name: "transmitAndSellTokenForEth",
|
Name: "transmitAndSellTokenForEth",
|
||||||
Parameters: []string{"address", "uint256", "uint256", "uint256", "address", "(uint8,bytes32,bytes32)", "bytes"},
|
Parameters: []string{"address", "uint256", "uint256", "uint256", "address", "(uint8,bytes32,bytes32)", "bytes"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "execute",
|
||||||
|
Parameters: []string{"bytes", "bytes[]", "uint256"},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
@ -191,13 +195,13 @@ func TestParseInputData(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "addLiquidityETH",
|
name: "addLiquidityETHToContract",
|
||||||
signatures: &signatures,
|
signatures: &signatures,
|
||||||
data: "0xf305d719000000000000000000000000b80e5aaa2131c07568128f68b8538ed3c8951234000000000000000000000000000000000000007e37be2022c0914b2680000000000000000000000000000000000000000000007e37be2022c0914b26800000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000009f64b014ca26f2def573246543dd1115b229e4f400000000000000000000000000000000000000000000000000000000623f56f8",
|
data: "0xf305d719000000000000000000000000b80e5aaa2131c07568128f68b8538ed3c8951234000000000000000000000000000000000000007e37be2022c0914b2680000000000000000000000000000000000000000000007e37be2022c0914b26800000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000009f64b014ca26f2def573246543dd1115b229e4f400000000000000000000000000000000000000000000000000000000623f56f8",
|
||||||
want: &bchain.EthereumParsedInputData{
|
want: &bchain.EthereumParsedInputData{
|
||||||
MethodId: "0xf305d719",
|
MethodId: "0xf305d719",
|
||||||
Name: "Add Liquidity ETH",
|
Name: "Add Liquidity ETH To Contract",
|
||||||
Function: "addLiquidityETH(address, uint256, uint256, uint256, address, uint256)",
|
Function: "addLiquidityETHToContract(address, uint256, uint256, uint256, address, uint256)",
|
||||||
Params: []bchain.EthereumParsedInputParam{
|
Params: []bchain.EthereumParsedInputParam{
|
||||||
{
|
{
|
||||||
Type: "address",
|
Type: "address",
|
||||||
@ -227,7 +231,7 @@ func TestParseInputData(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "addLiquidityETH data don't match - too long",
|
name: "addLiquidityETHToContract data don't match - too long",
|
||||||
signatures: &signatures,
|
signatures: &signatures,
|
||||||
data: "0xf305d719000000000000000000000000b80e5aaa2131c07568128f68b8538ed3c8951234000000000000000000000000000000000000007e37be2022c0914b2680000000000000000000000000000000000000000000007e37be2022c0914b26800000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000009f64b014ca26f2def573246543dd1115b229e4f400000000000000000000000000000000000000000000000000000000623f56f800000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
data: "0xf305d719000000000000000000000000b80e5aaa2131c07568128f68b8538ed3c8951234000000000000000000000000000000000000007e37be2022c0914b2680000000000000000000000000000000000000000000007e37be2022c0914b26800000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000009f64b014ca26f2def573246543dd1115b229e4f400000000000000000000000000000000000000000000000000000000623f56f800000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
want: &bchain.EthereumParsedInputData{
|
want: &bchain.EthereumParsedInputData{
|
||||||
@ -235,7 +239,7 @@ func TestParseInputData(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "addLiquidityETH data don't match - too short",
|
name: "addLiquidityETHToContract data don't match - too short",
|
||||||
signatures: &signatures,
|
signatures: &signatures,
|
||||||
data: "0xf305d719000000000000000000000000b80e5aaa2131c07568128f68b8538ed3c8951234000000000000000000000000000000000000007e37be2022c0914b2680000000000000000000000000000000000000000000007e37be2022c0914b26800000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000009f64b014ca26f2def573246543dd1115b229e4f4",
|
data: "0xf305d719000000000000000000000000b80e5aaa2131c07568128f68b8538ed3c8951234000000000000000000000000000000000000007e37be2022c0914b2680000000000000000000000000000000000000000000007e37be2022c0914b26800000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000009f64b014ca26f2def573246543dd1115b229e4f4",
|
||||||
want: &bchain.EthereumParsedInputData{
|
want: &bchain.EthereumParsedInputData{
|
||||||
@ -362,6 +366,57 @@ func TestParseInputData(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "execute",
|
||||||
|
signatures: &signatures,
|
||||||
|
data: "0x3593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000063fd167b00000000000000000000000000000000000000000000000000000000000000010800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000021e19e0c9bab2400000000000000000000000000000000000000000000000000000000000002fa5e9a300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000cda4e840411c00a614ad9205caec807c7458a0e3000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
|
||||||
|
want: &bchain.EthereumParsedInputData{
|
||||||
|
MethodId: "0x3593564c",
|
||||||
|
Name: "Execute",
|
||||||
|
Function: "execute(bytes, bytes[], uint256)",
|
||||||
|
Params: []bchain.EthereumParsedInputParam{
|
||||||
|
{
|
||||||
|
Type: "bytes",
|
||||||
|
Values: []string{"0x08"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "bytes[]",
|
||||||
|
Values: []string{"0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000021e19e0c9bab2400000000000000000000000000000000000000000000000000000000000002fa5e9a300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000cda4e840411c00a614ad9205caec807c7458a0e3000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "uint256",
|
||||||
|
Values: []string{"1677530747"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "execute2",
|
||||||
|
signatures: &signatures,
|
||||||
|
data: "0x3593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000063ffd82300000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000006f05b59d3b200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000491478480c282e75df8b5700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000f0f9d895aca5c8678f706fb8216fa22957685a13",
|
||||||
|
want: &bchain.EthereumParsedInputData{
|
||||||
|
MethodId: "0x3593564c",
|
||||||
|
Name: "Execute",
|
||||||
|
Function: "execute(bytes, bytes[], uint256)",
|
||||||
|
Params: []bchain.EthereumParsedInputParam{
|
||||||
|
{
|
||||||
|
Type: "bytes",
|
||||||
|
Values: []string{"0x0b08"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "bytes[]",
|
||||||
|
Values: []string{
|
||||||
|
"0x000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000006f05b59d3b20000",
|
||||||
|
"0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000491478480c282e75df8b5700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000f0f9d895aca5c8678f706fb8216fa22957685a13",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "uint256",
|
||||||
|
Values: []string{"1677711395"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user