Skip to content
This repository has been archived by the owner on Apr 10, 2024. It is now read-only.

Commit

Permalink
fix: large floating point wei conversion (#32)
Browse files Browse the repository at this point in the history
* Fix invalid conversion on decimal numbers

* Fix floating unit point wei conversion

* Improve error
  • Loading branch information
mpetrun5 authored Feb 14, 2023
1 parent 1c26018 commit 741da0e
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 20 deletions.
24 changes: 13 additions & 11 deletions util/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package util
import (
"bytes"
"errors"
"fmt"
"math/big"
"strings"
)
Expand All @@ -21,20 +22,21 @@ func Str2BigInt(small string) (*big.Int, error) {
}

func Large2SmallUnitConverter(large string, decimal uint) (*big.Int, error) {
curFloat, ok := zero().SetString(large)
a := strings.Split(large, ".")
for i := 0; i < int(decimal); i++ {
if len(a) > 1 && len(a[1]) > i {
a[0] += string(a[1][i])
} else {
a[0] += "0"
}
}

b, ok := new(big.Int).SetString(a[0], 10)
if !ok {
return big.NewInt(0), errors.New("failed to convert on the given decimal")
return nil, fmt.Errorf("failed to convert string to big int")
}
exp, _ := zero().SetString("1" + strings.Repeat("0", int(decimal)) + ".0")
weiFloat := zero().Mul(curFloat, exp)
weiInt, _ := weiFloat.Int(nil)
return weiInt, nil
}

func zero() *big.Float {
r := big.NewFloat(0.0)
r.SetPrec(512)
return r
return b, nil
}

func PaddingZero(data []byte, length int) []byte {
Expand Down
37 changes: 28 additions & 9 deletions util/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
package util_test

import (
"errors"

"github.com/ChainSafe/sygma-fee-oracle/util"

"math/big"
Expand Down Expand Up @@ -97,20 +95,41 @@ func TestLarge2SmallUnitConverter(t *testing.T) {
output: big.NewInt(1000000000),
outputErr: nil,
})
testcases = append(testcases, large2SmallUnitConverterTest{
name: "invalid string as input",
input1: "1a2b3c",
input2: 9,
output: big.NewInt(0),
outputErr: errors.New("failed to convert on the given decimal"),
})
testcases = append(testcases, large2SmallUnitConverterTest{
name: "valid string as input 4",
input1: "100",
input2: 0,
output: big.NewInt(100),
outputErr: nil,
})
testcases = append(testcases, large2SmallUnitConverterTest{
name: "short decimal number",
input1: "0.12",
input2: 18,
output: big.NewInt(120000000000000000),
outputErr: nil,
})
testcases = append(testcases, large2SmallUnitConverterTest{
name: "long decimal number",
input1: "0.00000012512521",
input2: 18,
output: big.NewInt(125125210000),
outputErr: nil,
})
testcases = append(testcases, large2SmallUnitConverterTest{
name: "large exponent",
input1: "0.000000000000000012512521",
input2: 32,
output: big.NewInt(1251252100000000),
outputErr: nil,
})
testcases = append(testcases, large2SmallUnitConverterTest{
name: "huge exponent",
input1: "0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012512521",
input2: 128,
output: big.NewInt(125125210000000000),
outputErr: nil,
})

for _, testcase := range testcases {
re, err := util.Large2SmallUnitConverter(testcase.input1, testcase.input2)
Expand Down

0 comments on commit 741da0e

Please sign in to comment.