Repository: osmosis-labs/osmosis
Pull request #2778 (2022-09-19 07:49:36)

[x/stableswap]: Increase precision of osmomath BigDec to prevent stableswap CFMM precision issues
<!-- < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < ☺
v                               ✰  Thanks for creating a PR! ✰    
v    Before smashing the submit button please review the checkboxes.
v    If a checkbox is n/a - please still include it but + a little note why
v    If your PR doesn't close an issue, that's OK!  Just remove the Closes: #XXX line!
☺ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >  -->

Closes: #2591

## What is the purpose of the change

This PR (finally!) fixes all the precision-related issues we have with our stableswap CFMM. I haven't checked exact bounds yet, but our binary search solver was able to comfortably support trillion token asset pools with this change.

A large part of the diff is #2777, which this PR branches off of.

## Brief Changelog

- Increase max bitlen from 512 to 1024
- Increase max decimal precision from 18 to 36
- Update all related tests to correctly reflect the new bounds

## Testing and Verifying

- All the tests in `osmomath/decimal_test.go` and `osmomath/int_test.go` should be up to date with the new bounds

## Documentation and Release Note

  - Does this pull request introduce a new feature or user-facing behavior changes? (no)
  - Is a relevant changelog entry added to the `Unreleased` section in `CHANGELOG.md`? (yes / no)
  - How is the feature or change documented? (not documented)


Patch:
diff --git a/go.mod b/go.mod
index 7880bbe8f..b6d7bf6a9 100644
--- a/go.mod
+++ b/go.mod
@@ -7,8 +7,8 @@ require (
 	github.com/cosmos/cosmos-proto v1.0.0-alpha7
 	github.com/cosmos/cosmos-sdk v0.46.1
 	github.com/cosmos/go-bip39 v1.0.0
-	github.com/cosmos/iavl v0.19.0
-	github.com/cosmos/ibc-go/v3 v3.2.0
+	github.com/cosmos/iavl v0.19.1
+	github.com/cosmos/ibc-go/v3 v3.2.1
 	github.com/gogo/protobuf v1.3.3
 	github.com/golang/mock v1.6.0
 	github.com/golang/protobuf v1.5.2
diff --git a/go.sum b/go.sum
index 6ef3dd550..bb87f1a0f 100644
--- a/go.sum
+++ b/go.sum
@@ -240,8 +240,8 @@ github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY
 github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw=
 github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y=
 github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw=
-github.com/cosmos/ibc-go/v3 v3.2.0 h1:Mh+RWo5FHPMM1Xsrar3uwKufdEGdIp5LDkVk9cYKYYA=
-github.com/cosmos/ibc-go/v3 v3.2.0/go.mod h1:DrDYXJjWNwgv72cK1Il+BegtyGIDXcx+cnJwWGzve6o=
+github.com/cosmos/ibc-go/v3 v3.2.1 h1:cURaZNryZ7J+UrcirDzrGfuDjvfB28Zd1UJupayFdho=
+github.com/cosmos/ibc-go/v3 v3.2.1/go.mod h1:VUWLHw0C3USmTQZnTdkuXXdUdLbW8zsK3lV1Ieposog=
 github.com/cosmos/interchain-accounts v0.1.0 h1:QmuwNsf1Hxl3P5GSGt7Z+JeuHPiZw4Z34R/038P5T6s=
 github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4=
 github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY=
diff --git a/osmomath/decimal.go b/osmomath/decimal.go
index b6aa442ad..527bab9ca 100644
--- a/osmomath/decimal.go
+++ b/osmomath/decimal.go
@@ -8,6 +8,8 @@ import (
 	"strconv"
 	"strings"
 	"testing"
+
+	sdk "github.com/cosmos/cosmos-sdk/types"
 )
 
 // NOTE: never use new(BigDec) or else we will panic unmarshalling into the
@@ -18,11 +20,11 @@ type BigDec struct {
 
 const (
 	// number of decimal places
-	Precision = 18
+	Precision = 36
 
 	// bytes required to represent the above precision
-	// Ceiling[Log2[999 999 999 999 999 999]]
-	DecimalPrecisionBits = 60
+	// Ceiling[Log2[10**Precision - 1]]
+	DecimalPrecisionBits = 120
 
 	maxDecBitLen = maxBitLen + DecimalPrecisionBits
 
@@ -494,6 +496,27 @@ func (d BigDec) MustFloat64() float64 {
 	}
 }
 
+// SdkDec returns the Sdk.Dec representation of a BigDec.
+// Values in any additional decimal places are truncated.
+func (d BigDec) SdkDec() sdk.Dec {
+	precisionDiff := Precision - sdk.Precision
+	precisionFactor := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(precisionDiff)), nil)
+
+	if precisionDiff < 0 {
+		panic("invalid decimal precision")
+	}
+
+	truncatedDec := sdk.NewDecFromBigIntWithPrec(new(big.Int).Quo(d.BigInt(), precisionFactor), sdk.Precision)
+
+	return truncatedDec
+}
+
+// BigDecFromSdkDec returns the BigDec representation of an SdkDec.
+// Values in any additional decimal places are truncated.
+func BigDecFromSdkDec(d sdk.Dec) BigDec {
+	return NewDecFromBigIntWithPrec(d.BigInt(), sdk.Precision)
+}
+
 //     ____
 //  __|    |__   "chop 'em
 //       ` \     round!"
diff --git a/osmomath/int.go b/osmomath/int.go
index 9d4f5e650..c3ae4ef28 100644
--- a/osmomath/int.go
+++ b/osmomath/int.go
@@ -8,7 +8,7 @@ import (
 	"testing"
 )
 
-const maxBitLen = 512
+const maxBitLen = 1024
 
 func newIntegerFromString(s string) (*big.Int, bool) {
 	return new(big.Int).SetString(s, 0)
diff --git a/x/gamm/pool-models/stableswap/amm.go b/x/gamm/pool-models/stableswap/amm.go
index 30c926208..186c39b4a 100644
--- a/x/gamm/pool-models/stableswap/amm.go
+++ b/x/gamm/pool-models/stableswap/amm.go
@@ -5,17 +5,18 @@ import (
 
 	sdk "github.com/cosmos/cosmos-sdk/types"
 
+	"github.com/osmosis-labs/osmosis/v12/osmomath"
 	"github.com/osmosis-labs/osmosis/v12/x/gamm/pool-models/internal/cfmm_common"
 	types "github.com/osmosis-labs/osmosis/v12/x/gamm/types"
 )
 
 var (
-	cubeRootTwo, _   = sdk.NewDec(2).ApproxRoot(3)
+	cubeRootTwo, _   = osmomath.NewBigDec(2).ApproxRoot(3)
 	threeCubeRootTwo = cubeRootTwo.MulInt64(3)
 )
 
 // solidly CFMM is xy(x^2 + y^2) = k
-func cfmmConstant(xReserve, yReserve sdk.Dec) sdk.Dec {
+func cfmmConstant(xReserve, yReserve osmomath.BigDec) osmomath.BigDec {
 	if !xReserve.IsPositive() || !yReserve.IsPositive() {
 		panic("invalid input: reserves must be positive")
 	}
@@ -30,7 +31,7 @@ func cfmmConstant(xReserve, yReserve sdk.Dec) sdk.Dec {
 // outside of x and y (e.g. u = wz), and v is the sum
 // of their squares (e.g. v = w^2 + z^2).
 // When u = 1 and v = 0, this is equivalent to solidly's CFMM
-func cfmmConstantMulti(xReserve, yReserve, uReserve, vSumSquares sdk.Dec) sdk.Dec {
+func cfmmConstantMulti(xReserve, yReserve, uReserve, vSumSquares osmomath.BigDec) osmomath.BigDec {
 	if !xReserve.IsPositive() || !yReserve.IsPositive() || !uReserve.IsPositive() || vSumSquares.IsNegative() {
 		panic("invalid input: reserves must be positive")
 	}
@@ -46,7 +47,7 @@ func cfmmConstantMulti(xReserve, yReserve, uReserve, vSumSquares sdk.Dec) sdk.De
 // how many units `a` of x do we get out.
 // So we solve the following expression for `a`
 // xy(x^2 + y^2) = (x - a)(y + b)((x - a)^2 + (y + b)^2)
-func solveCfmm(xReserve, yReserve, yIn sdk.Dec) sdk.Dec {
+func solveCfmm(xReserve, yReserve, yIn osmomath.BigDec) osmomath.BigDec {
 	if !xReserve.IsPositive() || !yReserve.IsPositive() || !yIn.IsPositive() {
 		panic("invalid input: reserves and input must be positive")
 	}
@@ -94,7 +95,7 @@ func solveCfmm(xReserve, yReserve, yIn sdk.Dec) sdk.Dec {
 	// and maybe in state.
 	x := xReserve
 	y := yReserve
-	x2py2 := x.Mul(x).AddMut(y.Mul(y))
+	x2py2 := x.Mul(x).Add(y.Mul(y))
 
 	xy := x.Mul(y)
 
@@ -128,19 +129,19 @@ func solveCfmm(xReserve, yReserve, yIn sdk.Dec) sdk.Dec {
 	e := xy.Mul(x2py2) // xy(x^2 + y^2)
 
 	// t1 = -27 (b + y)^2 e
-	t1 := e.Mul(bpy2).MulInt64Mut(-27)
+	t1 := e.Mul(bpy2).MulInt64(-27)
 
 	// compute d = (b + y)^2 sqrt(729 e^2 + 108 (b+y)^8)
 	bpy8 := bpy4.Mul(bpy4)
-	sqrt_inner := e.MulMut(e).MulInt64Mut(729).AddMut(bpy8.MulInt64Mut(108)) // 729 e^2 + 108 (b+y)^8
+	sqrt_inner := e.Mul(e).MulInt64(729).Add(bpy8.MulInt64(108)) // 729 e^2 + 108 (b+y)^8
 	sqrt, err := sqrt_inner.ApproxSqrt()
 	if err != nil {
 		panic(err)
 	}
-	d := sqrt.MulMut(bpy2)
+	d := sqrt.Mul(bpy2)
 
 	// foo = (t1 + d)^(1/3)
-	foo3 := t1.AddMut(d)
+	foo3 := t1.Add(d)
 	foo, _ := foo3.ApproxRoot(3)
 
 	// a = {foo / (3 2^(1/3) (b + y))}
@@ -171,7 +172,7 @@ func solveCfmm(xReserve, yReserve, yIn sdk.Dec) sdk.Dec {
 // how many units `a` of x do we get out.
 // So we solve the following expression for `a`
 // xyz(x^2 + y^2 + w) = (x - a)(y + b)z((x - a)^2 + (y + b)^2 + w)
-func solveCfmmMulti(xReserve, yReserve, wSumSquares, yIn sdk.Dec) sdk.Dec {
+func solveCfmmMulti(xReserve, yReserve, wSumSquares, yIn osmomath.BigDec) osmomath.BigDec {
 	if !xReserve.IsPositive() || !yReserve.IsPositive() || !yIn.IsPositive() {
 		panic("invalid input: reserves and input must be positive")
 	}
@@ -275,23 +276,23 @@ func solveCfmmMulti(xReserve, yReserve, wSumSquares, yIn sdk.Dec) sdk.Dec {
 	return a
 }
 
-func approxDecEqual(a, b, tol sdk.Dec) bool {
+func approxDecEqual(a, b, tol osmomath.BigDec) bool {
 	diff := a.Sub(b).Abs()
 	return diff.Quo(a).LTE(tol) && diff.Quo(b).LTE(tol)
 }
 
 var (
-	twodec    = sdk.MustNewDecFromStr("2.0")
-	threshold = sdk.NewDecWithPrec(1, 10) // Correct within a factor of 1 * 10^{-10}
+	twodec    = osmomath.MustNewDecFromStr("2.0")
+	threshold = osmomath.NewDecWithPrec(1, 10) // Correct within a factor of 1 * 10^{-10}
 )
 
 // solveCFMMBinarySearch searches the correct dx using binary search over constant K.
 // added for future extension
-func solveCFMMBinarySearch(constantFunction func(sdk.Dec, sdk.Dec) sdk.Dec) func(sdk.Dec, sdk.Dec, sdk.Dec) sdk.Dec {
-	return func(xReserve, yReserve, yIn sdk.Dec) sdk.Dec {
+func solveCFMMBinarySearch(constantFunction func(osmomath.BigDec, osmomath.BigDec) osmomath.BigDec) func(osmomath.BigDec, osmomath.BigDec, osmomath.BigDec) osmomath.BigDec {
+	return func(xReserve, yReserve, yIn osmomath.BigDec) osmomath.BigDec {
 		k := constantFunction(xReserve, yReserve)
 		yf := yReserve.Add(yIn)
-		x_low_est := sdk.ZeroDec()
+		x_low_est := osmomath.ZeroDec()
 		x_high_est := xReserve
 		x_est := (x_high_est.Add(x_low_est)).Quo(twodec)
 		cur_k := constantFunction(x_est, yf)
@@ -310,11 +311,11 @@ func solveCFMMBinarySearch(constantFunction func(sdk.Dec, sdk.Dec) sdk.Dec) func
 
 // solveCFMMBinarySearch searches the correct dx using binary search over constant K.
 // added for future extension
-func solveCFMMBinarySearchMulti(constantFunction func(sdk.Dec, sdk.Dec, sdk.Dec, sdk.Dec) sdk.Dec) func(sdk.Dec, sdk.Dec, sdk.Dec, sdk.Dec, sdk.Dec) sdk.Dec {
-	return func(xReserve, yReserve, uReserve, wSumSquares, yIn sdk.Dec) sdk.Dec {
+func solveCFMMBinarySearchMulti(constantFunction func(osmomath.BigDec, osmomath.BigDec, osmomath.BigDec, osmomath.BigDec) osmomath.BigDec) func(osmomath.BigDec, osmomath.BigDec, osmomath.BigDec, osmomath.BigDec, osmomath.BigDec) osmomath.BigDec {
+	return func(xReserve, yReserve, uReserve, wSumSquares, yIn osmomath.BigDec) osmomath.BigDec {
 		k := constantFunction(xReserve, yReserve, uReserve, wSumSquares)
 		yf := yReserve.Add(yIn)
-		x_low_est := sdk.ZeroDec()
+		x_low_est := osmomath.ZeroDec()
 		x_high_est := xReserve
 		x_est := (x_high_est.Add(x_low_est)).Quo(twodec)
 		cur_k := constantFunction(x_est, yf, uReserve, wSumSquares)
@@ -331,7 +332,7 @@ func solveCFMMBinarySearchMulti(constantFunction func(sdk.Dec, sdk.Dec, sdk.Dec,
 	}
 }
 
-func spotPrice(baseReserve, quoteReserve sdk.Dec) sdk.Dec {
+func spotPrice(baseReserve, quoteReserve osmomath.BigDec) osmomath.BigDec {
 	// y = baseAsset, x = quoteAsset
 	// Define f_{y -> x}(a) as the function that outputs the amount of tokens X you'd get by
 	// trading "a" units of Y against the pool, assuming 0 swap fee, at the current liquidity.
@@ -346,7 +347,7 @@ func spotPrice(baseReserve, quoteReserve sdk.Dec) sdk.Dec {
 
 	// We arbitrarily choose a = 1, and anticipate that this is a small value at the scale of
 	// xReserve & yReserve.
-	a := sdk.OneDec()
+	a := osmomath.OneDec()
 	// no need to divide by a, since a = 1.
 	return solveCfmm(baseReserve, quoteReserve, a)
 }
@@ -359,9 +360,9 @@ func (p *Pool) calcOutAmtGivenIn(tokenIn sdk.Coin, tokenOutDenom string, swapFee
 	}
 	tokenInSupply, tokenOutSupply := reserves[0], reserves[1]
 	// We are solving for the amount of token out, hence x = tokenOutSupply, y = tokenInSupply
-	cfmmOut := solveCfmm(tokenOutSupply, tokenInSupply, tokenIn.Amount.ToDec())
+	cfmmOut := solveCfmm(osmomath.BigDecFromSdkDec(tokenOutSupply), osmomath.BigDecFromSdkDec(tokenInSupply), osmomath.BigDecFromSdkDec(tokenIn.Amount.ToDec()))
 	outAmt := p.getDescaledPoolAmt(tokenOutDenom, cfmmOut)
-	return outAmt, nil
+	return outAmt.SdkDec(), nil
 }
 
 // returns inAmt as a decimal
@@ -373,9 +374,9 @@ func (p *Pool) calcInAmtGivenOut(tokenOut sdk.Coin, tokenInDenom string, swapFee
 	tokenInSupply, tokenOutSupply := reserves[0], reserves[1]
 	// We are solving for the amount of token in, cfmm(x,y) = cfmm(x + x_in, y - y_out)
 	// x = tokenInSupply, y = tokenOutSupply, yIn = -tokenOutAmount
-	cfmmIn := solveCfmm(tokenInSupply, tokenOutSupply, tokenOut.Amount.ToDec().Neg())
-	inAmt := p.getDescaledPoolAmt(tokenInDenom, cfmmIn.NegMut())
-	return inAmt, nil
+	cfmmIn := solveCfmm(osmomath.BigDecFromSdkDec(tokenInSupply), osmomath.BigDecFromSdkDec(tokenOutSupply), osmomath.BigDecFromSdkDec(tokenOut.Amount.ToDec().Neg()))
+	inAmt := p.getDescaledPoolAmt(tokenInDenom, cfmmIn.Neg())
+	return inAmt.SdkDec(), nil
 }
 
 func (p *Pool) calcSingleAssetJoinShares(tokenIn sdk.Coin, swapFee sdk.Dec) (sdk.Int, error) {
diff --git a/x/gamm/pool-models/stableswap/pool.go b/x/gamm/pool-models/stableswap/pool.go
index 464c7a569..d88e63ab2 100644
--- a/x/gamm/pool-models/stableswap/pool.go
+++ b/x/gamm/pool-models/stableswap/pool.go
@@ -9,6 +9,7 @@ import (
 	sdk "github.com/cosmos/cosmos-sdk/types"
 	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
 
+	"github.com/osmosis-labs/osmosis/v12/osmomath"
 	"github.com/osmosis-labs/osmosis/v12/x/gamm/pool-models/internal/cfmm_common"
 	"github.com/osmosis-labs/osmosis/v12/x/gamm/types"
 )
@@ -128,7 +129,7 @@ func (p Pool) getScaledPoolAmts(denoms ...string) ([]sdk.Dec, error) {
 }
 
 // getDescaledPoolAmts gets descaled amount of given denom and amount
-func (p Pool) getDescaledPoolAmt(denom string, amount sdk.Dec) sdk.Dec {
+func (p Pool) getDescaledPoolAmt(denom string, amount osmomath.BigDec) osmomath.BigDec {
 	liquidityIndexes := p.getLiquidityIndexMap()
 	liquidityIndex := liquidityIndexes[denom]
 
@@ -241,10 +242,12 @@ func (p Pool) SpotPrice(ctx sdk.Context, baseAssetDenom string, quoteAssetDenom
 	if err != nil {
 		return sdk.Dec{}, err
 	}
-	scaledSpotPrice := spotPrice(reserves[0], reserves[1])
+
+	scaledSpotPrice := spotPrice(osmomath.BigDecFromSdkDec(reserves[0]), osmomath.BigDecFromSdkDec(reserves[1]))
 	spotPrice := p.getDescaledPoolAmt(baseAssetDenom, scaledSpotPrice)
+	spotPriceSdkDec := spotPrice.SdkDec()
 
-	return spotPrice, nil
+	return spotPriceSdkDec, nil
 }
 
 func (p Pool) Copy() Pool {


Test patch:
diff --git a/osmomath/decimal_test.go b/osmomath/decimal_test.go
index f02e581cb..b5441930e 100644
--- a/osmomath/decimal_test.go
+++ b/osmomath/decimal_test.go
@@ -7,6 +7,7 @@ import (
 	"math/big"
 	"testing"
 
+	sdk "github.com/cosmos/cosmos-sdk/types"
 	"github.com/stretchr/testify/require"
 	"github.com/stretchr/testify/suite"
 	"gopkg.in/yaml.v2"
@@ -68,9 +69,9 @@ func (s *decimalTestSuite) TestNewDecFromStr() {
 		{"0.75", false, NewDecWithPrec(75, 2)},
 		{"0.8", false, NewDecWithPrec(8, 1)},
 		{"0.11111", false, NewDecWithPrec(11111, 5)},
-		{"314460551102969.3144278234343371835", true, NewBigDec(3141203149163817869)},
+		{"314460551102969.31442782343433718353144278234343371835", true, NewBigDec(3141203149163817869)},
 		{
-			"314460551102969314427823434337.1835718092488231350",
+			"314460551102969314427823434337.18357180924882313501835718092488231350",
 			true, NewDecFromBigIntWithPrec(largeBigInt, 4),
 		},
 		{
@@ -83,7 +84,7 @@ func (s *decimalTestSuite) TestNewDecFromStr() {
 		{"foobar", true, BigDec{}},
 		{"0.foobar", true, BigDec{}},
 		{"0.foobar.", true, BigDec{}},
-		{"23258839177459420497578361852416145099316523541994177929007686373780457219628733546438113622840434097944400691400517693873107252115668992", true, BigDec{}},
+		{"179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216", true, BigDec{}},
 	}
 
 	for tcIndex, tc := range tests {
@@ -112,14 +113,15 @@ func (s *decimalTestSuite) TestDecString() {
 		d    BigDec
 		want string
 	}{
-		{NewBigDec(0), "0.000000000000000000"},
-		{NewBigDec(1), "1.000000000000000000"},
-		{NewBigDec(10), "10.000000000000000000"},
-		{NewBigDec(12340), "12340.000000000000000000"},
-		{NewDecWithPrec(12340, 4), "1.234000000000000000"},
-		{NewDecWithPrec(12340, 5), "0.123400000000000000"},
-		{NewDecWithPrec(12340, 8), "0.000123400000000000"},
-		{NewDecWithPrec(1009009009009009009, 17), "10.090090090090090090"},
+		{NewBigDec(0), "0.000000000000000000000000000000000000"},
+		{NewBigDec(1), "1.000000000000000000000000000000000000"},
+		{NewBigDec(10), "10.000000000000000000000000000000000000"},
+		{NewBigDec(12340), "12340.000000000000000000000000000000000000"},
+		{NewDecWithPrec(12340, 4), "1.234000000000000000000000000000000000"},
+		{NewDecWithPrec(12340, 5), "0.123400000000000000000000000000000000"},
+		{NewDecWithPrec(12340, 8), "0.000123400000000000000000000000000000"},
+		{NewDecWithPrec(1009009009009009009, 17), "10.090090090090090090000000000000000000"},
+		{MustNewDecFromStr("10.090090090090090090090090090090090090"), "10.090090090090090090090090090090090090"},
 	}
 	for tcIndex, tc := range tests {
 		s.Require().Equal(tc.want, tc.d.String(), "bad String(), index: %v", tcIndex)
@@ -148,6 +150,56 @@ func (s *decimalTestSuite) TestDecFloat64() {
 	}
 }
 
+func (s *decimalTestSuite) TestSdkDec() {
+	tests := []struct {
+		d    BigDec
+		want sdk.Dec
+		expPanic bool
+	}{
+		{NewBigDec(0), sdk.MustNewDecFromStr("0.000000000000000000"), false},
+		{NewBigDec(1), sdk.MustNewDecFromStr("1.000000000000000000"), false},
+		{NewBigDec(10), sdk.MustNewDecFromStr("10.000000000000000000"), false},
+		{NewBigDec(12340), sdk.MustNewDecFromStr("12340.000000000000000000"), false},
+		{NewDecWithPrec(12340, 4), sdk.MustNewDecFromStr("1.234000000000000000"), false},
+		{NewDecWithPrec(12340, 5), sdk.MustNewDecFromStr("0.123400000000000000"), false},
+		{NewDecWithPrec(12340, 8), sdk.MustNewDecFromStr("0.000123400000000000"), false},
+		{NewDecWithPrec(1009009009009009009, 17), sdk.MustNewDecFromStr("10.090090090090090090"), false},
+	}
+	for tcIndex, tc := range tests {
+		if tc.expPanic {
+			s.Require().Panics(func() { tc.d.SdkDec() })
+		} else {
+			value := tc.d.SdkDec()
+			s.Require().Equal(tc.want, value, "bad SdkDec(), index: %v", tcIndex)
+		}
+	}
+}
+
+func (s *decimalTestSuite) TestBigDecFromSdkDec() {
+	tests := []struct {
+		d    sdk.Dec
+		want BigDec
+		expPanic bool
+	}{
+		{sdk.MustNewDecFromStr("0.000000000000000000"), NewBigDec(0), false},
+		{sdk.MustNewDecFromStr("1.000000000000000000"), NewBigDec(1), false},
+		{sdk.MustNewDecFromStr("10.000000000000000000"), NewBigDec(10), false},
+		{sdk.MustNewDecFromStr("12340.000000000000000000"), NewBigDec(12340), false},
+		{sdk.MustNewDecFromStr("1.234000000000000000"), NewDecWithPrec(12340, 4), false},
+		{sdk.MustNewDecFromStr("0.123400000000000000"), NewDecWithPrec(12340, 5), false},
+		{sdk.MustNewDecFromStr("0.000123400000000000"), NewDecWithPrec(12340, 8), false},
+		{sdk.MustNewDecFromStr("10.090090090090090090"), NewDecWithPrec(1009009009009009009, 17), false},
+	}
+	for tcIndex, tc := range tests {
+		if tc.expPanic {
+			s.Require().Panics(func() { BigDecFromSdkDec(tc.d) })
+		} else {
+			value := BigDecFromSdkDec(tc.d)
+			s.Require().Equal(tc.want, value, "bad BigDecFromSdkDec(), index: %v", tcIndex)
+		}
+	}
+}
+
 func (s *decimalTestSuite) TestEqualities() {
 	tests := []struct {
 		d1, d2     BigDec
@@ -227,7 +279,7 @@ func (s *decimalTestSuite) TestArithmetic() {
 
 		{
 			NewBigDec(3), NewBigDec(7), NewBigDec(21), NewBigDec(21),
-			NewDecWithPrec(428571428571428571, 18), NewDecWithPrec(428571428571428572, 18), NewDecWithPrec(428571428571428571, 18),
+			MustNewDecFromStr("0.428571428571428571428571428571428571"), MustNewDecFromStr("0.428571428571428571428571428571428572"), MustNewDecFromStr("0.428571428571428571428571428571428571"),
 			NewBigDec(10), NewBigDec(-4),
 		},
 		{
@@ -243,7 +295,7 @@ func (s *decimalTestSuite) TestArithmetic() {
 		},
 		{
 			NewDecWithPrec(3333, 4), NewDecWithPrec(333, 4), NewDecWithPrec(1109889, 8), NewDecWithPrec(1109889, 8),
-			MustNewDecFromStr("10.009009009009009009"), MustNewDecFromStr("10.009009009009009010"), MustNewDecFromStr("10.009009009009009009"),
+			MustNewDecFromStr("10.009009009009009009009009009009009009"), MustNewDecFromStr("10.009009009009009009009009009009009010"), MustNewDecFromStr("10.009009009009009009009009009009009009"),
 			NewDecWithPrec(3666, 4), NewDecWithPrec(3, 1),
 		},
 	}
@@ -336,7 +388,7 @@ func (s *decimalTestSuite) TestStringOverflow() {
 	s.Require().NoError(err)
 	dec3 := dec1.Add(dec2)
 	s.Require().Equal(
-		"19844653375691057515930281852116324640.000000000000000000",
+		"19844653375691057515930281852116324640.000000000000000000000000000000000000",
 		dec3.String(),
 	)
 }
@@ -363,14 +415,14 @@ func (s *decimalTestSuite) TestDecCeil() {
 		input    BigDec
 		expected BigDec
 	}{
-		{NewDecWithPrec(1000000000000000, Precision), NewBigDec(1)}, // 0.001 => 1.0
-		{NewDecWithPrec(-1000000000000000, Precision), ZeroDec()},   // -0.001 => 0.0
+		{MustNewDecFromStr("0.001"), NewBigDec(1)}, // 0.001 => 1.0
+		{MustNewDecFromStr("-0.001"), ZeroDec()},   // -0.001 => 0.0
 		{ZeroDec(), ZeroDec()}, // 0.0 => 0.0
-		{NewDecWithPrec(900000000000000000, Precision), NewBigDec(1)},    // 0.9 => 1.0
-		{NewDecWithPrec(4001000000000000000, Precision), NewBigDec(5)},   // 4.001 => 5.0
-		{NewDecWithPrec(-4001000000000000000, Precision), NewBigDec(-4)}, // -4.001 => -4.0
-		{NewDecWithPrec(4700000000000000000, Precision), NewBigDec(5)},   // 4.7 => 5.0
-		{NewDecWithPrec(-4700000000000000000, Precision), NewBigDec(-4)}, // -4.7 => -4.0
+		{MustNewDecFromStr("0.9"), NewBigDec(1)},    // 0.9 => 1.0
+		{MustNewDecFromStr("4.001"), NewBigDec(5)},   // 4.001 => 5.0
+		{MustNewDecFromStr("-4.001"), NewBigDec(-4)}, // -4.001 => -4.0
+		{MustNewDecFromStr("4.7"), NewBigDec(5)},   // 4.7 => 5.0
+		{MustNewDecFromStr("-4.7"), NewBigDec(-4)}, // -4.7 => -4.0
 	}
 
 	for i, tc := range testCases {
@@ -390,7 +442,7 @@ func (s *decimalTestSuite) TestPower() {
 		{NewDecWithPrec(2, 1), 2, NewDecWithPrec(4, 2)},                        // 0.2 ^ 2 => 0.04
 		{NewDecFromInt(NewInt(3)), 3, NewDecFromInt(NewInt(27))},               // 3 ^ 3 => 27
 		{NewDecFromInt(NewInt(-3)), 4, NewDecFromInt(NewInt(81))},              // -3 ^ 4 = 81
-		{NewDecWithPrec(1414213562373095049, 18), 2, NewDecFromInt(NewInt(2))}, // 1.414213562373095049 ^ 2 = 2
+		{MustNewDecFromStr("1.414213562373095048801688724209698079"), 2, NewDecFromInt(NewInt(2))}, // 1.414213562373095048801688724209698079 ^ 2 = 2
 	}
 
 	for i, tc := range testCases {
@@ -410,11 +462,11 @@ func (s *decimalTestSuite) TestApproxRoot() {
 		{NewDecWithPrec(4, 2), 2, NewDecWithPrec(2, 1)},                                // 0.04 ^ (0.5) => 0.2
 		{NewDecFromInt(NewInt(27)), 3, NewDecFromInt(NewInt(3))},                       // 27 ^ (1/3) => 3
 		{NewDecFromInt(NewInt(-81)), 4, NewDecFromInt(NewInt(-3))},                     // -81 ^ (0.25) => -3
-		{NewDecFromInt(NewInt(2)), 2, NewDecWithPrec(1414213562373095049, 18)},         // 2 ^ (0.5) => 1.414213562373095049
-		{NewDecWithPrec(1005, 3), 31536000, MustNewDecFromStr("1.000000000158153904")}, // 1.005 ^ (1/31536000) ≈ 1.00000000016
-		{SmallestDec(), 2, NewDecWithPrec(1, 9)},                                       // 1e-18 ^ (0.5) => 1e-9
-		{SmallestDec(), 3, MustNewDecFromStr("0.000000999999999997")},                  // 1e-18 ^ (1/3) => 1e-6
-		{NewDecWithPrec(1, 8), 3, MustNewDecFromStr("0.002154434690031900")},           // 1e-8 ^ (1/3) ≈ 0.00215443469
+		{NewDecFromInt(NewInt(2)), 2, MustNewDecFromStr("1.414213562373095048801688724209698079")},         // 2 ^ (0.5) => 1.414213562373095048801688724209698079
+		{NewDecWithPrec(1005, 3), 31536000, MustNewDecFromStr("1.000000000158153903837946258002096839")}, // 1.005 ^ (1/31536000) ≈ 1.000000000158153903837946258002096839
+		{SmallestDec(), 2, NewDecWithPrec(1, 18)},                                       // 1e-36 ^ (0.5) => 1e-18
+		{SmallestDec(), 3, MustNewDecFromStr("0.000000000001000000000000000002431786")},                  // 1e-36 ^ (1/3) => 1e-12
+		{NewDecWithPrec(1, 8), 3, MustNewDecFromStr("0.002154434690031883721759293566519280")},           // 1e-8 ^ (1/3) ≈ 0.002154434690031883721759293566519
 	}
 
 	// In the case of 1e-8 ^ (1/3), the result repeats every 5 iterations starting from iteration 24
@@ -438,7 +490,7 @@ func (s *decimalTestSuite) TestApproxSqrt() {
 		{NewDecWithPrec(4, 2), NewDecWithPrec(2, 1)},                        // 0.09 => 0.3
 		{NewDecFromInt(NewInt(9)), NewDecFromInt(NewInt(3))},                // 9 => 3
 		{NewDecFromInt(NewInt(-9)), NewDecFromInt(NewInt(-3))},              // -9 => -3
-		{NewDecFromInt(NewInt(2)), NewDecWithPrec(1414213562373095049, 18)}, // 2 => 1.414213562373095049
+		{NewDecFromInt(NewInt(2)), MustNewDecFromStr("1.414213562373095048801688724209698079")}, // 2 => 1.414213562373095048801688724209698079
 	}
 
 	for i, tc := range testCases {
@@ -453,24 +505,24 @@ func (s *decimalTestSuite) TestDecSortableBytes() {
 		d    BigDec
 		want []byte
 	}{
-		{NewBigDec(0), []byte("000000000000000000.000000000000000000")},
-		{NewBigDec(1), []byte("000000000000000001.000000000000000000")},
-		{NewBigDec(10), []byte("000000000000000010.000000000000000000")},
-		{NewBigDec(12340), []byte("000000000000012340.000000000000000000")},
-		{NewDecWithPrec(12340, 4), []byte("000000000000000001.234000000000000000")},
-		{NewDecWithPrec(12340, 5), []byte("000000000000000000.123400000000000000")},
-		{NewDecWithPrec(12340, 8), []byte("000000000000000000.000123400000000000")},
-		{NewDecWithPrec(1009009009009009009, 17), []byte("000000000000000010.090090090090090090")},
-		{NewDecWithPrec(-1009009009009009009, 17), []byte("-000000000000000010.090090090090090090")},
-		{NewBigDec(1000000000000000000), []byte("max")},
-		{NewBigDec(-1000000000000000000), []byte("--")},
+		{NewBigDec(0), []byte("000000000000000000000000000000000000.000000000000000000000000000000000000")},
+		{NewBigDec(1), []byte("000000000000000000000000000000000001.000000000000000000000000000000000000")},
+		{NewBigDec(10), []byte("000000000000000000000000000000000010.000000000000000000000000000000000000")},
+		{NewBigDec(12340), []byte("000000000000000000000000000000012340.000000000000000000000000000000000000")},
+		{NewDecWithPrec(12340, 4), []byte("000000000000000000000000000000000001.234000000000000000000000000000000000")},
+		{NewDecWithPrec(12340, 5), []byte("000000000000000000000000000000000000.123400000000000000000000000000000000")},
+		{NewDecWithPrec(12340, 8), []byte("000000000000000000000000000000000000.000123400000000000000000000000000000")},
+		{NewDecWithPrec(1009009009009009009, 17), []byte("000000000000000000000000000000000010.090090090090090090000000000000000000")},
+		{NewDecWithPrec(-1009009009009009009, 17), []byte("-000000000000000000000000000000000010.090090090090090090000000000000000000")},
+		{MustNewDecFromStr("1000000000000000000000000000000000000"), []byte("max")},
+		{MustNewDecFromStr("-1000000000000000000000000000000000000"), []byte("--")},
 	}
 	for tcIndex, tc := range tests {
 		s.Require().Equal(tc.want, SortableDecBytes(tc.d), "bad String(), index: %v", tcIndex)
 	}
 
-	s.Require().Panics(func() { SortableDecBytes(NewBigDec(1000000000000000001)) })
-	s.Require().Panics(func() { SortableDecBytes(NewBigDec(-1000000000000000001)) })
+	s.Require().Panics(func() { SortableDecBytes(MustNewDecFromStr("1000000000000000000000000000000000001")) })
+	s.Require().Panics(func() { SortableDecBytes(MustNewDecFromStr("-1000000000000000000000000000000000001")) })
 }
 
 func (s *decimalTestSuite) TestDecEncoding() {
@@ -482,32 +534,32 @@ func (s *decimalTestSuite) TestDecEncoding() {
 	}{
 		{
 			NewBigDec(0), "30",
-			"\"0.000000000000000000\"",
-			"\"0.000000000000000000\"\n",
+			"\"0.000000000000000000000000000000000000\"",
+			"\"0.000000000000000000000000000000000000\"\n",
 		},
 		{
 			NewDecWithPrec(4, 2),
-			"3430303030303030303030303030303030",
-			"\"0.040000000000000000\"",
-			"\"0.040000000000000000\"\n",
+			"3430303030303030303030303030303030303030303030303030303030303030303030",
+			"\"0.040000000000000000000000000000000000\"",
+			"\"0.040000000000000000000000000000000000\"\n",
 		},
 		{
 			NewDecWithPrec(-4, 2),
-			"2D3430303030303030303030303030303030",
-			"\"-0.040000000000000000\"",
-			"\"-0.040000000000000000\"\n",
+			"2D3430303030303030303030303030303030303030303030303030303030303030303030",
+			"\"-0.040000000000000000000000000000000000\"",
+			"\"-0.040000000000000000000000000000000000\"\n",
 		},
 		{
-			NewDecWithPrec(1414213562373095049, 18),
-			"31343134323133353632333733303935303439",
-			"\"1.414213562373095049\"",
-			"\"1.414213562373095049\"\n",
+			MustNewDecFromStr("1.414213562373095048801688724209698079"),
+			"31343134323133353632333733303935303438383031363838373234323039363938303739",
+			"\"1.414213562373095048801688724209698079\"",
+			"\"1.414213562373095048801688724209698079\"\n",
 		},
 		{
-			NewDecWithPrec(-1414213562373095049, 18),
-			"2D31343134323133353632333733303935303439",
-			"\"-1.414213562373095049\"",
-			"\"-1.414213562373095049\"\n",
+			MustNewDecFromStr("-1.414213562373095048801688724209698079"),
+			"2D31343134323133353632333733303935303438383031363838373234323039363938303739",
+			"\"-1.414213562373095048801688724209698079\"",
+			"\"-1.414213562373095048801688724209698079\"\n",
 		},
 	}
 
diff --git a/osmomath/int_test.go b/osmomath/int_test.go
index 33fe5dbc7..a3e376a95 100644
--- a/osmomath/int_test.go
+++ b/osmomath/int_test.go
@@ -40,17 +40,17 @@ func (s *intTestSuite) TestFromUint64() {
 }
 
 func (s *intTestSuite) TestIntPanic() {
-	// Max Int = 2^512-1 = 1.340781e+154
-	// Min Int = -(2^512-1) = -1.340781e+154
-	s.Require().NotPanics(func() { NewIntWithDecimal(4, 153) })
-	i1 := NewIntWithDecimal(5, 153)
-	s.Require().NotPanics(func() { NewIntWithDecimal(5, 153) })
-	i2 := NewIntWithDecimal(6, 153)
-	s.Require().NotPanics(func() { NewIntWithDecimal(6, 153) })
-	i3 := NewIntWithDecimal(7, 153)
-
-	s.Require().Panics(func() { NewIntWithDecimal(2, 154) })
-	s.Require().Panics(func() { NewIntWithDecimal(9, 160) })
+	// Max Int = 2^1024-1 = 8.988466e+308
+	// Min Int = -(2^1024-1) = -8.988466e+308
+	s.Require().NotPanics(func() { NewIntWithDecimal(4, 307) })
+	i1 := NewIntWithDecimal(4, 307)
+	s.Require().NotPanics(func() { NewIntWithDecimal(5, 307) })
+	i2 := NewIntWithDecimal(5, 307)
+	s.Require().NotPanics(func() { NewIntWithDecimal(92, 306) })
+	i3 := NewIntWithDecimal(92, 306)
+
+	s.Require().Panics(func() { NewIntWithDecimal(2, 308) })
+	s.Require().Panics(func() { NewIntWithDecimal(9, 340) })
 
 	// Overflow check
 	s.Require().NotPanics(func() { i1.Add(i1) })
@@ -84,7 +84,7 @@ func (s *intTestSuite) TestIntPanic() {
 	s.Require().Panics(func() { i3.Mul(i3.Neg()) })
 
 	// Bound check
-	intmax := NewIntFromBigInt(new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(512), nil), big.NewInt(1)))
+	intmax := NewIntFromBigInt(new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(1024), nil), big.NewInt(1)))
 	intmin := intmax.Neg()
 	s.Require().NotPanics(func() { intmax.Add(ZeroInt()) })
 	s.Require().NotPanics(func() { intmin.Sub(ZeroInt()) })
diff --git a/x/gamm/pool-models/stableswap/amm_bench_test.go b/x/gamm/pool-models/stableswap/amm_bench_test.go
index a23546376..a868b8f86 100644
--- a/x/gamm/pool-models/stableswap/amm_bench_test.go
+++ b/x/gamm/pool-models/stableswap/amm_bench_test.go
@@ -4,7 +4,7 @@ import (
 	"math/rand"
 	"testing"
 
-	sdk "github.com/cosmos/cosmos-sdk/types"
+	"github.com/osmosis-labs/osmosis/v12/osmomath"
 )
 
 func BenchmarkCFMM(b *testing.B) {
@@ -20,9 +20,9 @@ func BenchmarkBinarySearch(b *testing.B) {
 	}
 }
 
-func runCalc(solve func(sdk.Dec, sdk.Dec, sdk.Dec) sdk.Dec) {
-	xReserve := sdk.NewDec(rand.Int63n(100000) + 50000)
-	yReserve := sdk.NewDec(rand.Int63n(100000) + 50000)
-	yIn := sdk.NewDec(rand.Int63n(100000))
+func runCalc(solve func(osmomath.BigDec, osmomath.BigDec, osmomath.BigDec) osmomath.BigDec) {
+	xReserve := osmomath.NewBigDec(rand.Int63n(100000) + 50000)
+	yReserve := osmomath.NewBigDec(rand.Int63n(100000) + 50000)
+	yIn := osmomath.NewBigDec(rand.Int63n(100000))
 	solve(xReserve, yReserve, yIn)
 }
diff --git a/x/gamm/pool-models/stableswap/amm_test.go b/x/gamm/pool-models/stableswap/amm_test.go
index afbf5b5a7..e2c67eadf 100644
--- a/x/gamm/pool-models/stableswap/amm_test.go
+++ b/x/gamm/pool-models/stableswap/amm_test.go
@@ -1,13 +1,14 @@
 package stableswap
 
 import (
-	fmt "fmt"
+	"fmt"
 	"testing"
 
 	sdk "github.com/cosmos/cosmos-sdk/types"
 	"github.com/stretchr/testify/require"
 
 	"github.com/osmosis-labs/osmosis/v12/app/apptesting/osmoassert"
+	"github.com/osmosis-labs/osmosis/v12/osmomath"
 	"github.com/osmosis-labs/osmosis/v12/x/gamm/pool-models/internal/test_helpers"
 )
 
@@ -16,24 +17,24 @@ type StableSwapTestSuite struct {
 }
 
 func TestCFMMInvariantTwoAssets(t *testing.T) {
-	kErrTolerance := sdk.OneDec()
+	kErrTolerance := osmomath.OneDec()
 
 	tests := map[string]struct {
-		xReserve    sdk.Dec
-		yReserve    sdk.Dec
-		yIn         sdk.Dec
+		xReserve    osmomath.BigDec
+		yReserve    osmomath.BigDec
+		yIn         osmomath.BigDec
 		expectPanic bool
 	}{
 		"small pool small input": {
-			sdk.NewDec(100),
-			sdk.NewDec(100),
-			sdk.NewDec(1),
+			osmomath.NewBigDec(100),
+			osmomath.NewBigDec(100),
+			osmomath.NewBigDec(1),
 			false,
 		},
 		"small pool large input": {
-			sdk.NewDec(100),
-			sdk.NewDec(100),
-			sdk.NewDec(1000),
+			osmomath.NewBigDec(100),
+			osmomath.NewBigDec(100),
+			osmomath.NewBigDec(1000),
 			false,
 		},
 		// This test fails due to a bug in our original solver
@@ -45,21 +46,21 @@ func TestCFMMInvariantTwoAssets(t *testing.T) {
 
 		// panic catching
 		"xReserve negative": {
-			sdk.NewDec(-100),
-			sdk.NewDec(100),
-			sdk.NewDec(1),
+			osmomath.NewBigDec(-100),
+			osmomath.NewBigDec(100),
+			osmomath.NewBigDec(1),
 			true,
 		},
 		"yReserve negative": {
-			sdk.NewDec(100),
-			sdk.NewDec(-100),
-			sdk.NewDec(1),
+			osmomath.NewBigDec(100),
+			osmomath.NewBigDec(-100),
+			osmomath.NewBigDec(1),
 			true,
 		},
 		"yIn negative": {
-			sdk.NewDec(100),
-			sdk.NewDec(100),
-			sdk.NewDec(-1),
+			osmomath.NewBigDec(100),
+			osmomath.NewBigDec(100),
+			osmomath.NewBigDec(-1),
 			true,
 		},
 	}
@@ -73,14 +74,14 @@ func TestCFMMInvariantTwoAssets(t *testing.T) {
 				xOut := solveCfmm(test.xReserve, test.yReserve, test.yIn)
 
 				k1 := cfmmConstant(test.xReserve.Sub(xOut), test.yReserve.Add(test.yIn))
-				osmoassert.DecApproxEq(t, k0, k1, kErrTolerance)
+				osmomath.DecApproxEq(t, k0, k1, kErrTolerance)
 
 				// using multi-asset cfmm (should be equivalent with u = 1, w = 0)
-				k2 := cfmmConstantMulti(test.xReserve, test.yReserve, sdk.OneDec(), sdk.ZeroDec())
-				osmoassert.DecApproxEq(t, k2, k0, kErrTolerance)
-				xOut2 := solveCfmmMulti(test.xReserve, test.yReserve, sdk.ZeroDec(), test.yIn)
-				k3 := cfmmConstantMulti(test.xReserve.Sub(xOut2), test.yReserve.Add(test.yIn), sdk.OneDec(), sdk.ZeroDec())
-				osmoassert.DecApproxEq(t, k2, k3, kErrTolerance)
+				k2 := cfmmConstantMulti(test.xReserve, test.yReserve, osmomath.OneDec(), osmomath.ZeroDec())
+				osmomath.DecApproxEq(t, k2, k0, kErrTolerance)
+				xOut2 := solveCfmmMulti(test.xReserve, test.yReserve, osmomath.ZeroDec(), test.yIn)
+				k3 := cfmmConstantMulti(test.xReserve.Sub(xOut2), test.yReserve.Add(test.yIn), osmomath.OneDec(), osmomath.ZeroDec())
+				osmomath.DecApproxEq(t, k2, k3, kErrTolerance)
 			}
 
 			osmoassert.ConditionalPanic(t, test.expectPanic, sut)
@@ -89,31 +90,31 @@ func TestCFMMInvariantTwoAssets(t *testing.T) {
 }
 
 func TestCFMMInvariantMultiAssets(t *testing.T) {
-	kErrTolerance := sdk.OneDec()
+	kErrTolerance := osmomath.OneDec()
 
 	tests := map[string]struct {
-		xReserve    sdk.Dec
-		yReserve    sdk.Dec
-		uReserve    sdk.Dec
-		wSumSquares sdk.Dec
-		yIn         sdk.Dec
+		xReserve    osmomath.BigDec
+		yReserve    osmomath.BigDec
+		uReserve    osmomath.BigDec
+		wSumSquares osmomath.BigDec
+		yIn         osmomath.BigDec
 		expectPanic bool
 	}{
 		"4-asset pool, small input": {
-			sdk.NewDec(100),
-			sdk.NewDec(100),
+			osmomath.NewBigDec(100),
+			osmomath.NewBigDec(100),
 			// represents a 4-asset pool with 100 in each reserve
-			sdk.NewDec(200),
-			sdk.NewDec(20000),
-			sdk.NewDec(1),
+			osmomath.NewBigDec(200),
+			osmomath.NewBigDec(20000),
+			osmomath.NewBigDec(1),
 			false,
 		},
 		"4-asset pool, large input": {
-			sdk.NewDec(100),
-			sdk.NewDec(100),
-			sdk.NewDec(200),
-			sdk.NewDec(20000),
-			sdk.NewDec(1000),
+			osmomath.NewBigDec(100),
+			osmomath.NewBigDec(100),
+			osmomath.NewBigDec(200),
+			osmomath.NewBigDec(20000),
+			osmomath.NewBigDec(1000),
 			false,
 		},
 		// This test fails due to a bug in our original solver
@@ -125,48 +126,48 @@ func TestCFMMInvariantMultiAssets(t *testing.T) {
 
 		// panic catching
 		"negative xReserve": {
-			sdk.NewDec(-100),
-			sdk.NewDec(100),
+			osmomath.NewBigDec(-100),
+			osmomath.NewBigDec(100),
 			// represents a 4-asset pool with 100 in each reserve
-			sdk.NewDec(200),
-			sdk.NewDec(20000),
-			sdk.NewDec(1),
+			osmomath.NewBigDec(200),
+			osmomath.NewBigDec(20000),
+			osmomath.NewBigDec(1),
 			true,
 		},
 		"negative yReserve": {
-			sdk.NewDec(100),
-			sdk.NewDec(-100),
+			osmomath.NewBigDec(100),
+			osmomath.NewBigDec(-100),
 			// represents a 4-asset pool with 100 in each reserve
-			sdk.NewDec(200),
-			sdk.NewDec(20000),
-			sdk.NewDec(1),
+			osmomath.NewBigDec(200),
+			osmomath.NewBigDec(20000),
+			osmomath.NewBigDec(1),
 			true,
 		},
 		"negative uReserve": {
-			sdk.NewDec(100),
-			sdk.NewDec(100),
+			osmomath.NewBigDec(100),
+			osmomath.NewBigDec(100),
 			// represents a 4-asset pool with 100 in each reserve
-			sdk.NewDec(-200),
-			sdk.NewDec(20000),
-			sdk.NewDec(1),
+			osmomath.NewBigDec(-200),
+			osmomath.NewBigDec(20000),
+			osmomath.NewBigDec(1),
 			true,
 		},
 		"negative sumSquares": {
-			sdk.NewDec(100),
-			sdk.NewDec(100),
+			osmomath.NewBigDec(100),
+			osmomath.NewBigDec(100),
 			// represents a 4-asset pool with 100 in each reserve
-			sdk.NewDec(200),
-			sdk.NewDec(-20000),
-			sdk.NewDec(1),
+			osmomath.NewBigDec(200),
+			osmomath.NewBigDec(-20000),
+			osmomath.NewBigDec(1),
 			true,
 		},
 		"negative yIn": {
-			sdk.NewDec(100),
-			sdk.NewDec(100),
+			osmomath.NewBigDec(100),
+			osmomath.NewBigDec(100),
 			// represents a 4-asset pool with 100 in each reserve
-			sdk.NewDec(200),
-			sdk.NewDec(-20000),
-			sdk.NewDec(1),
+			osmomath.NewBigDec(200),
+			osmomath.NewBigDec(-20000),
+			osmomath.NewBigDec(1),
 			true,
 		},
 	}
@@ -179,7 +180,7 @@ func TestCFMMInvariantMultiAssets(t *testing.T) {
 				k2 := cfmmConstantMulti(test.xReserve, test.yReserve, test.uReserve, test.wSumSquares)
 				xOut2 := solveCfmmMulti(test.xReserve, test.yReserve, test.wSumSquares, test.yIn)
 				k3 := cfmmConstantMulti(test.xReserve.Sub(xOut2), test.yReserve.Add(test.yIn), test.uReserve, test.wSumSquares)
-				osmoassert.DecApproxEq(t, k2, k3, kErrTolerance)
+				osmomath.DecApproxEq(t, k2, k3, kErrTolerance)
 			}
 
 			osmoassert.ConditionalPanic(t, test.expectPanic, sut)