Skip to content

Commit

Permalink
Add wasmbinding for PrecDec with scientificNotation
Browse files Browse the repository at this point in the history
  • Loading branch information
jcompagni10 committed May 8, 2024
1 parent c754b4e commit a0f03c2
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 4 deletions.
11 changes: 7 additions & 4 deletions wasmbinding/bindings/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,14 +261,17 @@ type Dex struct {
// MsgPlaceLimitOrder is a copy dextypes.MsgPlaceLimitOrder with altered ExpirationTime field,
// it's a preferable way to pass timestamp as unixtime to contracts
type MsgPlaceLimitOrder struct {
Creator string `json:"creator,omitempty"`
Receiver string `json:"receiver,omitempty"`
TokenIn string `json:"token_in,omitempty"`
TokenOut string `json:"token_out,omitempty"`
Creator string `json:"creator,omitempty"`
Receiver string `json:"receiver,omitempty"`
TokenIn string `json:"token_in,omitempty"`
TokenOut string `json:"token_out,omitempty"`
// DEPRECATED: tick_index_in_to_out will be removed in future release; limit_sell_price should be used instead.
TickIndexInToOut int64 `json:"tick_index_in_to_out,omitempty"`
AmountIn math.Int `json:"amount_in"`
OrderType string `json:"order_type,omitempty"`
// expirationTime is only valid iff orderType == GOOD_TIL_TIME.
ExpirationTime *uint64 `json:"expiration_time,omitempty"`
MaxAmountOut *math.Int `json:"max_amount_out"`
// Accepts standard decimals and decimals with scientific notation (ie. 1234.23E-7)
LimitSellPrice string `json:"limit_sell_price,omitempty"`
}
10 changes: 10 additions & 0 deletions wasmbinding/message_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

dexkeeper "github.com/neutron-org/neutron/v3/x/dex/keeper"
dextypes "github.com/neutron-org/neutron/v3/x/dex/types"
dexutils "github.com/neutron-org/neutron/v3/x/dex/utils"

contractmanagerkeeper "github.com/neutron-org/neutron/v3/x/contractmanager/keeper"

Expand Down Expand Up @@ -243,6 +244,15 @@ func (m *CustomMessenger) dispatchDexMsg(ctx sdk.Context, contractAddr sdk.AccAd
t := time.Unix(int64(*(dex.PlaceLimitOrder.ExpirationTime)), 0)
msg.ExpirationTime = &t
}

if limitPriceStr := dex.PlaceLimitOrder.LimitSellPrice; limitPriceStr != "" {
limitPriceDec, err := dexutils.ParsePrecDecScientificNotation(limitPriceStr)
if err != nil {
return nil, err
}
msg.LimitSellPrice = &limitPriceDec
}

return handleDexMsg(ctx, &msg, m.DexMsgServer.PlaceLimitOrder)
case dex.CancelLimitOrder != nil:
dex.CancelLimitOrder.Creator = contractAddr.String()
Expand Down
36 changes: 36 additions & 0 deletions x/dex/utils/math.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package utils
import (
"fmt"
"math"
"regexp"
"strconv"

sdkmath "cosmossdk.io/math"
Expand Down Expand Up @@ -88,3 +89,38 @@ func Log(val, base math_utils.PrecDec) (math_utils.PrecDec, error) {
}
return logAsPrecDec, nil
}

var scientificNotationRE = regexp.MustCompile(`^([\d\.]+)(E([\-\+])(\d+))?$`)

func ParsePrecDecScientificNotation(n string) (math_utils.PrecDec, error) {

match := scientificNotationRE.FindSubmatch([]byte(n))

if len(match) == 0 {
return math_utils.ZeroPrecDec(), fmt.Errorf("error parsing string as PrecDec with possible scientific notation")
}

baseDec, err := math_utils.NewPrecDecFromStr(string(match[1]))
if err != nil {
return math_utils.ZeroPrecDec(), fmt.Errorf("error parsing string as PrecDec with possible scientific notation: %v", err)
}

// No scientific notation
if len(match[2]) == 0 {
return baseDec, nil
}

pow, err := strconv.ParseUint(string(match[4]), 10, 64)
if err != nil {
return math_utils.ZeroPrecDec(), fmt.Errorf("error parsing string as PrecDec with possible scientific notation: %v", err)
}

shift := math_utils.NewPrecDec(10).Power(pow)

if string(match[3]) == "+" { // positive exponent
return baseDec.Mul(shift), nil
} else { // string(match[3]) == "-" // negative exponent

return baseDec.Quo(shift), nil
}
}
98 changes: 98 additions & 0 deletions x/dex/utils/math_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package utils_test

import (
"testing"

math_utils "github.com/neutron-org/neutron/v3/utils/math"
"github.com/neutron-org/neutron/v3/x/dex/utils"
"github.com/stretchr/testify/require"
)

func TestParsePrecDecScientificNotation(t *testing.T) {
for _, tc := range []struct {
desc string
in string
out math_utils.PrecDec
err bool
}{
{
desc: "invalid garbage",
in: "sdfdsf",
err: true,
},
{
desc: "invalid exp",
in: "10Z-5",
err: true,
},
{
desc: "invalid exp 2",
in: "10E-",
err: true,
},
{
desc: "invalid exp 3",
in: "10E-+1",
err: true,
},
{
desc: "invalid exp 4",
in: "10E+1.0",
err: true,
},
{
desc: "valid integer",
in: "10",
out: math_utils.NewPrecDec(10),
},
{
desc: "valid decimal",
in: "10.1",
out: math_utils.MustNewPrecDecFromStr("10.1"),
},
{
desc: "valid integer with E-6",
in: "6E-6",
out: math_utils.MustNewPrecDecFromStr("0.000006"),
},
{
desc: "valid decimal with E+0",
in: "10.1E+0",
out: math_utils.MustNewPrecDecFromStr("10.1"),
},
{
desc: "valid decimal with E+1",
in: "10.1E+1",
out: math_utils.MustNewPrecDecFromStr("101"),
},
{
desc: "valid decimal with E+10",
in: "10.12345678901E+10",
out: math_utils.MustNewPrecDecFromStr("101234567890.1"),
},
{
desc: "valid decimal with E-0",
in: "0.1E-0",
out: math_utils.MustNewPrecDecFromStr("0.1"),
},
{
desc: "valid decimal with E-1",
in: "189.3E-1",
out: math_utils.MustNewPrecDecFromStr("18.93"),
},
{
desc: "valid decimal with E+10",
in: "101234567890.1E-10",
out: math_utils.MustNewPrecDecFromStr("10.12345678901"),
},
} {
t.Run(tc.desc, func(t *testing.T) {
val, err := utils.ParsePrecDecScientificNotation(tc.in)
if tc.err {
require.Error(t, err)
} else {
require.True(t, val.Equal(tc.out), "Got: %v; Expected: %v", val, tc.out)
}
})
}
}

0 comments on commit a0f03c2

Please # to comment.