Skip to content

Commit

Permalink
feat(bpmath): MulDec (#2166)
Browse files Browse the repository at this point in the history
* feat(bpmath): MulDec

* changelog
  • Loading branch information
robert-zaremba authored Jul 25, 2023
1 parent 8b5ac11 commit b5b77d7
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ Ref: https://keepachangelog.com/en/1.0.0/
- [2146](https://github.com/umee-network/umee/pull/2146) Add store `GetTimeMs` and `SetTimeMs`.
- [2157](https://github.com/umee-network/umee/pull/2157) Add `x/metoken` module.
- [2145](https://github.com/umee-network/umee/pull/2145) Add hard market cap for token emission.
- [2155](https://github.com/umee-network/umee/pull/2155) `bpmath`: basis points math package.
- [2166](https://github.com/umee-network/umee/pull/2166) Basis Points: `MulDec`

### Improvements

Expand Down
19 changes: 18 additions & 1 deletion util/bpmath/bp.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ func (bp BP) Mul(a cmath.Int) cmath.Int {
return Mul(a, bp)
}

// MulDec return a*bp rounding towards zero.
func (bp BP) MulDec(a sdk.Dec) sdk.Dec {
return MulDec(a, bp)
}

// FromQuo returns a/b in basis points.
// Contract: a>=0 and b > 0.
// Panics if a/b >= MaxUint32/10'000 or if b==0.
Expand All @@ -44,7 +49,7 @@ func quo(a, b cmath.Int, rounding Rounding, max uint64) uint64 {

// Mul returns a * b_basis_points rounding towards zero.
// Contract: b in [0, MaxUint32]
func Mul[T BP | FixedBP](a cmath.Int, b T) cmath.Int {
func Mul[T BP | FixedBP | int](a cmath.Int, b T) cmath.Int {
if b == 0 {
return cmath.ZeroInt()
}
Expand All @@ -53,3 +58,15 @@ func Mul[T BP | FixedBP](a cmath.Int, b T) cmath.Int {
}
return a.MulRaw(int64(b)).Quo(oneBigInt)
}

// MulDec returns a * b_basis_points rounding towards zero.
// Contract: b in [0, MaxUint32]
func MulDec[T BP | FixedBP | int](a sdk.Dec, b T) sdk.Dec {
if b == 0 {
return sdk.ZeroDec()
}
if b == One {
return a
}
return a.MulInt64(int64(b)).Quo(oneDec)
}
23 changes: 23 additions & 0 deletions util/bpmath/bp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,26 @@ func TestInt(t *testing.T) {
si = sdk.NewInt(-1201)
require.Equal(bp.Mul(si), sdk.NewInt(-12))
}

func TestBPMulDec(t *testing.T) {
t.Parallel()
require := require.New(t)

bp := BP(1000)
bp2 := BP(1)
bp3 := BP(5000)
bp4 := BP(20000)
d := sdk.MustNewDecFromStr("12.5002")
d2 := sdk.NewDec(10000)
d3 := sdk.NewDec(1000)

require.Equal(d, MulDec(d, One))
require.Equal(sdk.ZeroDec(), MulDec(d, Zero))
require.Equal(sdk.OneDec(), bp2.MulDec(d2))
require.Equal(sdk.MustNewDecFromStr("0.1"), bp2.MulDec(d3))

require.Equal(sdk.MustNewDecFromStr("1.25002"), bp.MulDec(d))
require.Equal(sdk.MustNewDecFromStr("0.00125002"), bp2.MulDec(d))
require.Equal(sdk.MustNewDecFromStr("6.2501"), bp3.MulDec(d))
require.Equal(sdk.MustNewDecFromStr("25.0004"), bp4.MulDec(d))
}
5 changes: 5 additions & 0 deletions util/bpmath/fixed_bp.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,8 @@ func (bp FixedBP) ToDec() sdk.Dec {
func (bp FixedBP) Mul(a math.Int) math.Int {
return Mul(a, bp)
}

// MulDec return a*bp rounding towards zero.
func (bp FixedBP) MulDec(a sdk.Dec) sdk.Dec {
return MulDec(a, bp)
}
24 changes: 24 additions & 0 deletions util/bpmath/fixed_bp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -107,3 +108,26 @@ func TestFixedToDec(t *testing.T) {
require.Equal(tc.exp.String(), bp.String(), fmt.Sprint("test-bp ", tc.name))
}
}

func TestFixedBPMulDec(t *testing.T) {
t.Parallel()
require := require.New(t)

bp := FixedBP(1000)
bp2 := FixedBP(1)
bp3 := FixedBP(5000)
bp4 := FixedBP(20000)
d := sdk.MustNewDecFromStr("12.5002")
d2 := sdk.NewDec(10000)
d3 := sdk.NewDec(1000)

require.Equal(d, MulDec(d, One))
require.Equal(sdk.ZeroDec(), MulDec(d, Zero))
require.Equal(sdk.OneDec(), bp2.MulDec(d2))
require.Equal(sdk.MustNewDecFromStr("0.1"), bp2.MulDec(d3))

require.Equal(sdk.MustNewDecFromStr("1.25002"), bp.MulDec(d))
require.Equal(sdk.MustNewDecFromStr("0.00125002"), bp2.MulDec(d))
require.Equal(sdk.MustNewDecFromStr("6.2501"), bp3.MulDec(d))
require.Equal(sdk.MustNewDecFromStr("25.0004"), bp4.MulDec(d))
}
3 changes: 3 additions & 0 deletions util/bpmath/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package bpmath

import (
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
)

type Rounding uint
Expand All @@ -14,6 +15,8 @@ const (
const (
One = 10000
Half = One / 2
Zero = 0
)

var oneBigInt = math.NewIntFromUint64(One)
var oneDec = sdk.NewDec(One)

0 comments on commit b5b77d7

Please sign in to comment.