Skip to content

Commit

Permalink
feat(osmoutils): coin math helpers (#6427)
Browse files Browse the repository at this point in the history
* feat(osmoutils): coin math helpers

* updates

* go mod

(cherry picked from commit d00cb3e)

# Conflicts:
#	CHANGELOG.md
#	go.mod
#	go.sum
  • Loading branch information
p0mvn authored and mergify[bot] committed Sep 18, 2023
1 parent 7b8f215 commit d14700e
Show file tree
Hide file tree
Showing 5 changed files with 303 additions and 0 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

<<<<<<< HEAD
=======
### Features

* [#6427](https://github.com/osmosis-labs/osmosis/pull/6427) sdk.Coins Mul and Quo helpers in osmoutils

### Misc Improvements

* [#6309](https://github.com/osmosis-labs/osmosis/pull/6309) Add Cosmwasm Pool Queries to Stargate Query
>>>>>>> d00cb3e5 (feat(osmoutils): coin math helpers (#6427))
### Features

* [#6416](https://github.com/osmosis-labs/osmosis/pull/6416) feat[CL]: add num initialized ticks query
Expand Down
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,17 @@ require (
github.com/mattn/go-sqlite3 v1.14.17
github.com/ory/dockertest/v3 v3.10.0
github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3
<<<<<<< HEAD
github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230908171738-9abfe2e61cf4
github.com/osmosis-labs/osmosis/osmoutils v0.0.6
github.com/osmosis-labs/osmosis/x/epochs v0.0.2
github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.8
=======
github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230918184012-da92c9cdf6bd
github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20230911120014-b14342e08daf
github.com/osmosis-labs/osmosis/x/epochs v0.0.3-0.20230911120014-b14342e08daf
github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.9-0.20230911120014-b14342e08daf
>>>>>>> d00cb3e5 (feat(osmoutils): coin math helpers (#6427))
github.com/pkg/errors v0.9.1
github.com/rakyll/statik v0.1.7
github.com/spf13/cast v1.5.1
Expand Down
13 changes: 13 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,7 @@ github.com/osmosis-labs/cosmos-sdk v0.45.0-rc1.0.20230703010110-ed4eb883f2a6 h1:
github.com/osmosis-labs/cosmos-sdk v0.45.0-rc1.0.20230703010110-ed4eb883f2a6/go.mod h1:9KGhMg+7ZWgZ50Wa/x8w/jN19O0TSqYLlqUj+2wwxLU=
github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3 h1:YlmchqTmlwdWSmrRmXKR+PcU96ntOd8u10vTaTZdcNY=
github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3/go.mod h1:lV6KnqXYD/ayTe7310MHtM3I2q8Z6bBfMAi+bhwPYtI=
<<<<<<< HEAD
github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230908171738-9abfe2e61cf4 h1:pX9LmOgvRZTQVROZroz5sENUn0/DgdNRS5fbNIjk4Oo=
github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230908171738-9abfe2e61cf4/go.mod h1:UlftwozB+QObT3o0YfkuuyL9fsVdgoWt0dm6J7MLYnU=
github.com/osmosis-labs/osmosis/osmoutils v0.0.6 h1:VI4wPzxXpdg5XEUaBugY9lADwxzw3H6lEJ0D+TZc4oE=
Expand All @@ -970,6 +971,18 @@ github.com/osmosis-labs/osmosis/x/epochs v0.0.2 h1:aEeXHGCSJMgMtAvCucsD2RSaWZ8lI
github.com/osmosis-labs/osmosis/x/epochs v0.0.2/go.mod h1:8dvJFHTpu6SIxmOaSaEw0tHnQ/Z9blf5qsF/ZJnMVHo=
github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.8 h1:BUGowctYQT0vdPgULrvwraEsW+sS6DnbzndTLKLmWVY=
github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.8/go.mod h1:sR0lpev9mcm9/9RY50T1og3UC3WpZAsINh/OmgrmFlg=
=======
github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230911120014-b14342e08daf h1:sXSC/RG9sxQCB5QJ5JB+M9Bok7Xbpv2zx9ee6287glw=
github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230911120014-b14342e08daf/go.mod h1:pIItelRYvonB+H8A6KqucOi7xFnJxzDHaWJqOdFNLI4=
github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230918184012-da92c9cdf6bd h1:U7r0uBLTWeLrgGOu1re0aTl10yreX1j3dNDu12KqBpE=
github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230918184012-da92c9cdf6bd/go.mod h1:pIItelRYvonB+H8A6KqucOi7xFnJxzDHaWJqOdFNLI4=
github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20230911120014-b14342e08daf h1:r5R/L3tzH+vGPahAdvnVB2Vo0KPhZR0oMNyX4+G2FEo=
github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20230911120014-b14342e08daf/go.mod h1:7VoXHwrSSx8Sii0UFc9YIixF6C/9XfV1pdU2Dliu4WA=
github.com/osmosis-labs/osmosis/x/epochs v0.0.3-0.20230911120014-b14342e08daf h1:8lkIsAj3L7zxvOZbqVLNJRpSdDxaYhYfAIG7XjPaJiU=
github.com/osmosis-labs/osmosis/x/epochs v0.0.3-0.20230911120014-b14342e08daf/go.mod h1:C0Uqe6X4N5ASA+1xZ6guaaJyUVKLcaVJIQa4Q4LG9Vk=
github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.9-0.20230911120014-b14342e08daf h1:ZEi+yJJPgpYtmNwZ1bMiP5cMBDQ83FK/YGgmTnWmoAI=
github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.9-0.20230911120014-b14342e08daf/go.mod h1:pqkAsS04Er1kFM41gg3aWTSaYHyLe8C9Dw3Sj8KMXk8=
>>>>>>> d00cb3e5 (feat(osmoutils): coin math helpers (#6427))
github.com/osmosis-labs/wasmd v0.31.0-osmo-v16 h1:X747cZYdnqc/+RV48iPVeGprpVb/fUWSaKGsZUWrdbg=
github.com/osmosis-labs/wasmd v0.31.0-osmo-v16/go.mod h1:Rf8zW/GgBQyFRRB4s62VQHWA6sTlMFSjoDQQpoq64iI=
github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw=
Expand Down
138 changes: 138 additions & 0 deletions osmoutils/coins/coin_math.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package coins

import (
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/osmosis-labs/osmosis/osmomath"
)

// Mutative helpers that mutate the input coins

// MulIntMut multiplies the coins by the given integer
// Mutates the input coins
func MulIntMut(coins sdk.Coins, num osmomath.Int) {
for i := range coins {
coins[i].Amount = coins[i].Amount.Mul(num)
}
}

// MulRawMut multiplies the coins by the given integer
// Mutates the input coins
func MulRawMut(coins sdk.Coins, num int64) sdk.Coins {
for i := range coins {
coins[i].Amount = coins[i].Amount.MulRaw(num)
}
return coins
}

// MulDecMut multiplies the coins by the given decimal
// Mutates the input coins
func MulDecMut(coins sdk.Coins, num osmomath.Dec) {
for i := range coins {
coins[i].Amount = coins[i].Amount.ToLegacyDec().Mul(num).TruncateInt()
}
}

// QuoIntMut divides the coins by the given integer
// Mutates the input coins
func QuoIntMut(coins sdk.Coins, num osmomath.Int) {
for i := range coins {
coins[i].Amount = coins[i].Amount.Quo(num)
}
}

// QuoRawMut divides the coins by the given integer
// Mutates the input coins
func QuoRawMut(coins sdk.Coins, num int64) {
for i := range coins {
coins[i].Amount = coins[i].Amount.QuoRaw(num)
}
}

// QuoIntMut divides the coins by the given decimal
// Mutates the input coins
func QuoDecMut(coins sdk.Coins, num osmomath.Dec) {
for i := range coins {
coins[i].Amount = coins[i].Amount.ToLegacyDec().Quo(num).TruncateInt()
}
}

// Non-mutative coin helpers that reallocate and return new coins

// MulInt multiplies the coins by the given integer
// Does not mutate the input coins and returns new coins.
func MulInt(coins sdk.Coins, num osmomath.Int) sdk.Coins {
newCoins := make(sdk.Coins, len(coins))

for i := range coins {
newCoins[i].Amount = coins[i].Amount.Mul(num)
newCoins[i].Denom = coins[i].Denom
}

return newCoins
}

// MulRaw multiplies the coins by the given integer
// Does not mutate the input coins and returns new coins.
func MulRaw(coins sdk.Coins, num int64) sdk.Coins {
newCoins := make(sdk.Coins, len(coins))

for i := range coins {
newCoins[i].Amount = coins[i].Amount.MulRaw(num)
newCoins[i].Denom = coins[i].Denom
}

return newCoins
}

// MulDec multiplies the coins by the given decimal
// Does not mutate the input coins and returns new coins.
func MulDec(coins sdk.Coins, num osmomath.Dec) sdk.Coins {
newCoins := make(sdk.Coins, len(coins))

for i := range coins {
newCoins[i].Amount = coins[i].Amount.ToLegacyDec().Mul(num).TruncateInt()
newCoins[i].Denom = coins[i].Denom
}

return newCoins
}

// QuoInt divides the coins by the given integer
// Does not mutate the input coins and returns new coins.
func QuoInt(coins sdk.Coins, num osmomath.Int) sdk.Coins {
newCoins := make(sdk.Coins, len(coins))

for i := range coins {
newCoins[i].Amount = coins[i].Amount.Quo(num)
newCoins[i].Denom = coins[i].Denom
}

return newCoins
}

// QuoRaw divides the coins by the given integer
// Does not mutate the input coins and returns new coins.
func QuoRaw(coins sdk.Coins, num int64) sdk.Coins {
newCoins := make(sdk.Coins, len(coins))

for i := range coins {
newCoins[i].Amount = coins[i].Amount.QuoRaw(num)
newCoins[i].Denom = coins[i].Denom
}

return newCoins
}

// QuoDec divides the coins by the given integer
// Does not mutate the input coins and returns new coins.
func QuoDec(coins sdk.Coins, num osmomath.Dec) sdk.Coins {
newCoins := make(sdk.Coins, len(coins))

for i := range coins {
newCoins[i].Amount = coins[i].Amount.ToLegacyDec().Quo(num).TruncateInt()
newCoins[i].Denom = coins[i].Denom
}

return newCoins
}
135 changes: 135 additions & 0 deletions osmoutils/coins/coin_math_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package coins_test

import (
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"

"github.com/osmosis-labs/osmosis/osmomath"
"github.com/osmosis-labs/osmosis/osmoutils/coins"
)

var (
defaultCoins = sdk.NewCoins(
sdk.NewCoin("foo", sdk.NewInt(100)),
sdk.NewCoin("bar", sdk.NewInt(200)),
)

defaultMultiplier = osmomath.NewInt(2)

defaultMulExpectedResult = sdk.NewCoins(
sdk.NewCoin(defaultCoins[0].Denom, defaultCoins[0].Amount.Mul(defaultMultiplier)),
sdk.NewCoin(defaultCoins[1].Denom, defaultCoins[1].Amount.Mul(defaultMultiplier)),
)

defaultQuoExpectedResult = sdk.NewCoins(
sdk.NewCoin(defaultCoins[0].Denom, defaultCoins[0].Amount.Quo(defaultMultiplier)),
sdk.NewCoin(defaultCoins[1].Denom, defaultCoins[1].Amount.Quo(defaultMultiplier)),
)
)

// makes a deep copy to avoid accidentally mutating the input to a test.
func deepCopy(coins sdk.Coins) sdk.Coins {
newCoins := make(sdk.Coins, len(coins))
for i := range coins {
newCoins[i].Amount = coins[i].Amount
newCoins[i].Denom = coins[i].Denom
}
return newCoins
}

// Basic multiplication test.
func TestMul(t *testing.T) {
t.Run("test mutative multiplication", func(t *testing.T) {
t.Run("MulIntMut", func(t *testing.T) {
defaulCoins := deepCopy(defaultCoins)
coins.MulIntMut(defaulCoins, defaultMultiplier)
require.Equal(t, defaultMulExpectedResult, defaulCoins)
})

t.Run("MulIntRawMut", func(t *testing.T) {
defaulCoins := deepCopy(defaultCoins)
coins.MulRawMut(defaulCoins, defaultMultiplier.Int64())
require.Equal(t, defaultMulExpectedResult, defaulCoins)
})

t.Run("MulDecMut", func(t *testing.T) {
defaulCoins := deepCopy(defaultCoins)
coins.MulDecMut(defaulCoins, osmomath.NewDecFromInt(defaultMultiplier))
require.Equal(t, defaultMulExpectedResult, defaulCoins)
})
})

// Make a deep copy of the default coins for the input.
// Validate that the copy input coins are not mutated.
t.Run("test non-mutative multiplication", func(t *testing.T) {
t.Run("MulInt", func(t *testing.T) {
defaulCoinsCopy := deepCopy(defaultCoins)
result := coins.MulInt(defaulCoinsCopy, defaultMultiplier)
require.Equal(t, defaultMulExpectedResult, result)
require.Equal(t, defaultCoins, defaulCoinsCopy)
})

t.Run("MulIntRaw", func(t *testing.T) {
defaulCoinsCopy := deepCopy(defaultCoins)
result := coins.MulRaw(defaulCoinsCopy, defaultMultiplier.Int64())
require.Equal(t, defaultMulExpectedResult, result)
require.Equal(t, defaultCoins, defaulCoinsCopy)
})

t.Run("MulDec", func(t *testing.T) {
defaulCoinsCopy := deepCopy(defaultCoins)
result := coins.MulDec(defaulCoinsCopy, osmomath.NewDecFromInt(defaultMultiplier))
require.Equal(t, defaultMulExpectedResult, result)
require.Equal(t, defaultCoins, defaulCoinsCopy)
})
})
}

func TestQuo(t *testing.T) {
t.Run("test mutative division", func(t *testing.T) {
t.Run("QuoIntMut", func(t *testing.T) {
defaulCoins := deepCopy(defaultCoins)
coins.QuoIntMut(defaulCoins, defaultMultiplier)
require.Equal(t, defaultQuoExpectedResult, defaulCoins)
})

t.Run("QuoIntRawMut", func(t *testing.T) {
defaulCoins := deepCopy(defaultCoins)
coins.QuoRawMut(defaulCoins, defaultMultiplier.Int64())
require.Equal(t, defaultQuoExpectedResult, defaulCoins)
})

t.Run("QuoDecMut", func(t *testing.T) {
defaulCoins := deepCopy(defaultCoins)
coins.QuoDecMut(defaulCoins, osmomath.NewDecFromInt(defaultMultiplier))
require.Equal(t, defaultQuoExpectedResult, defaulCoins)
})
})

// Make a deep copy of the default coins for the input.
// Validate that the copy input coins are not mutated.
t.Run("test non-mutative division", func(t *testing.T) {
t.Run("QuoInt", func(t *testing.T) {
defaulCoinsCopy := deepCopy(defaultCoins)
result := coins.QuoInt(defaulCoinsCopy, defaultMultiplier)
require.Equal(t, defaultQuoExpectedResult, result)
require.Equal(t, defaultCoins, defaulCoinsCopy)
})

t.Run("QuoIntRaw", func(t *testing.T) {
defaulCoinsCopy := deepCopy(defaultCoins)
result := coins.QuoRaw(defaulCoinsCopy, defaultMultiplier.Int64())
require.Equal(t, defaultQuoExpectedResult, result)
require.Equal(t, defaultCoins, defaulCoinsCopy)
})

t.Run("QuoDec", func(t *testing.T) {
defaulCoinsCopy := deepCopy(defaultCoins)
result := coins.QuoDec(defaulCoinsCopy, osmomath.NewDecFromInt(defaultMultiplier))
require.Equal(t, defaultQuoExpectedResult, result)
require.Equal(t, defaultCoins, defaulCoinsCopy)
})
})
}

0 comments on commit d14700e

Please sign in to comment.