diff --git a/CHANGELOG.md b/CHANGELOG.md index 18252553e38..df185c1bc67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,8 +45,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Features * [#6427](https://github.com/osmosis-labs/osmosis/pull/6427) sdk.Coins Mul and Quo helpers in osmoutils +<<<<<<< HEAD * [#6437](https://github.com/osmosis-labs/osmosis/pull/6437) mutative version for QuoRoundUp. Replace some non-mutative calls with mutative for better performance. * [#6416](https://github.com/osmosis-labs/osmosis/pull/6416) feat[CL]: add num initialized ticks query +======= +* [#6428](https://github.com/osmosis-labs/osmosis/pull/6428) osmomath: QuoTruncateMut +* [#6437](https://github.com/osmosis-labs/osmosis/pull/6437) mutative version for QuoRoundUp +>>>>>>> 114f055f (osmomath: QuoTruncate with no reallocation (#6428)) * [#6261](https://github.com/osmosis-labs/osmosis/pull/6261) mutative and efficient BigDec truncations with arbitrary decimals ### Misc Improvements diff --git a/go.mod b/go.mod index 3bc707f504c..34ba61a22e8 100644 --- a/go.mod +++ b/go.mod @@ -22,10 +22,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.20230920194312-3eba9e93e29b github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20230920012324-f1a1ca887bd2 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.20230920194803-25ef84411155 + 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 +>>>>>>> 114f055f (osmomath: QuoTruncate with no reallocation (#6428)) github.com/pkg/errors v0.9.1 github.com/rakyll/statik v0.1.7 github.com/spf13/cast v1.5.1 diff --git a/go.sum b/go.sum index 9f43b91d325..3488bfd2fe5 100644 --- a/go.sum +++ b/go.sum @@ -963,6 +963,7 @@ github.com/osmosis-labs/cosmos-sdk v0.45.0-rc1.0.20230913192254-a2075590d5a3 h1: github.com/osmosis-labs/cosmos-sdk v0.45.0-rc1.0.20230913192254-a2075590d5a3/go.mod h1:mFGH2RJhuZa6vBuFMNe4JN85fGtIhROtdeQIyIw9isA= 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.20230920090526-bc02685001d4 h1:inSXiNHfKdWXrff3oU4FYFVmbK/9VYSIc73MtOpKApg= github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230920090526-bc02685001d4/go.mod h1:oBmsOov8oxuWoI/yMQwyKGA6QfP0cBxylLt75gFbT8s= github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230920173345-6401a459cb14 h1:SR8J54Bi55oHr1KN7E+8PS1IZDXJJDPuBG+hrn/JoQA= @@ -975,6 +976,22 @@ 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.20230920134650-28712c635b4f h1:SwZwcklK2EHIQLD8gVTqMsUTD1GpTyF6X8HlMywrxTc= +github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230920134650-28712c635b4f/go.mod h1:pIItelRYvonB+H8A6KqucOi7xFnJxzDHaWJqOdFNLI4= +github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230920190757-3f566b965c22 h1:D2Qx9OPINxTQVaXQZwklajC04XUYGvY5g+8Z8rMMXas= +github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230920190757-3f566b965c22/go.mod h1:pIItelRYvonB+H8A6KqucOi7xFnJxzDHaWJqOdFNLI4= +github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230920192334-7fb82821ef90 h1:GRKUSGlACYPYFfU5Beu7NBILX8UYHGTWw09gzTfsdwc= +github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230920192334-7fb82821ef90/go.mod h1:pIItelRYvonB+H8A6KqucOi7xFnJxzDHaWJqOdFNLI4= +github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230920194803-25ef84411155 h1:/oHIhbkOkYIL2mhIEaF2Z0EquQQEfy7NyF/Vo6Kf6Jo= +github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230920194803-25ef84411155/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= +>>>>>>> 114f055f (osmomath: QuoTruncate with no reallocation (#6428)) 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= diff --git a/osmomath/decimal.go b/osmomath/decimal.go index 9eb12bbe348..a717d2df452 100644 --- a/osmomath/decimal.go +++ b/osmomath/decimal.go @@ -395,6 +395,19 @@ func (d BigDec) QuoTruncate(d2 BigDec) BigDec { return BigDec{chopped} } +// quotient truncate (mutative) +func (d BigDec) QuoTruncateMut(d2 BigDec) BigDec { + // multiply precision twice + d.i.Mul(d.i, squaredPrecisionReuse) + d.i.Quo(d.i, d2.i) + + chopPrecisionAndTruncateMut(d.i) + if d.i.BitLen() > maxDecBitLen { + panic("Int overflow") + } + return d +} + // quotient, round up func (d BigDec) QuoRoundUp(d2 BigDec) BigDec { // multiply precision twice diff --git a/osmomath/decimal_test.go b/osmomath/decimal_test.go index 9861f61f02c..03ef3698457 100644 --- a/osmomath/decimal_test.go +++ b/osmomath/decimal_test.go @@ -1638,3 +1638,62 @@ func (s *decimalTestSuite) TestQuoRoundUp_MutativeAndNonMutative() { } } } + +func (s *decimalTestSuite) TestQuoTruncate_MutativeAndNonMutative() { + tests := []struct { + d1, d2, expQuoTruncateMut osmomath.BigDec + }{ + {osmomath.NewBigDec(0), osmomath.NewBigDec(0), osmomath.NewBigDec(0)}, + {osmomath.NewBigDec(1), osmomath.NewBigDec(0), osmomath.NewBigDec(0)}, + {osmomath.NewBigDec(0), osmomath.NewBigDec(1), osmomath.NewBigDec(0)}, + {osmomath.NewBigDec(0), osmomath.NewBigDec(-1), osmomath.NewBigDec(0)}, + {osmomath.NewBigDec(-1), osmomath.NewBigDec(0), osmomath.NewBigDec(0)}, + + {osmomath.NewBigDec(1), osmomath.NewBigDec(1), osmomath.NewBigDec(1)}, + {osmomath.NewBigDec(-1), osmomath.NewBigDec(-1), osmomath.NewBigDec(1)}, + {osmomath.NewBigDec(1), osmomath.NewBigDec(-1), osmomath.NewBigDec(-1)}, + {osmomath.NewBigDec(-1), osmomath.NewBigDec(1), osmomath.NewBigDec(-1)}, + + { + osmomath.NewBigDec(3), osmomath.NewBigDec(7), osmomath.MustNewBigDecFromStr("0.428571428571428571428571428571428571"), + }, + { + osmomath.NewBigDec(2), osmomath.NewBigDec(4), osmomath.NewBigDecWithPrec(5, 1), + }, + + {osmomath.NewBigDec(100), osmomath.NewBigDec(100), osmomath.NewBigDec(1)}, + + { + osmomath.NewBigDecWithPrec(15, 1), osmomath.NewBigDecWithPrec(15, 1), osmomath.NewBigDec(1), + }, + { + osmomath.NewBigDecWithPrec(3333, 4), osmomath.NewBigDecWithPrec(333, 4), osmomath.MustNewBigDecFromStr("10.009009009009009009009009009009009009"), + }, + } + + for tcIndex, tc := range tests { + tc := tc + + if tc.d2.IsZero() { // panic for divide by zero + s.Require().Panics(func() { tc.d1.QuoTruncateMut(tc.d2) }) + } else { + + copy := tc.d1.Clone() + + nonMutResult := copy.QuoTruncate(tc.d2) + + // Return is as expected + s.Require().Equal(tc.expQuoTruncateMut, nonMutResult, "exp %v, res %v, tc %d", tc.expQuoTruncateMut.String(), tc.d1.String(), tcIndex) + + // Receiver is not mutated + s.Require().Equal(tc.d1, copy, "exp %v, res %v, tc %d", tc.expQuoTruncateMut.String(), tc.d1.String(), tcIndex) + + // Receiver is mutated. + tc.d1.QuoTruncateMut(tc.d2) + + // Make sure d1 equals to expected + s.Require().True(tc.expQuoTruncateMut.Equal(tc.d1), "exp %v, res %v, tc %d", tc.expQuoTruncateMut.String(), tc.d1.String(), tcIndex) + } + } +} + diff --git a/x/concentrated-liquidity/math/math.go b/x/concentrated-liquidity/math/math.go index 64c55e63262..360c5aee2e8 100644 --- a/x/concentrated-liquidity/math/math.go +++ b/x/concentrated-liquidity/math/math.go @@ -80,10 +80,17 @@ func CalcAmount0Delta(liq, sqrtPriceA, sqrtPriceB osmomath.BigDec, roundUp bool) // These are truncated at precision end to round in favor of the pool when: // - calculating amount out during swap // - withdrawing liquidity +<<<<<<< HEAD // The denominator is rounded up to get a smaller final amount. denom := sqrtPriceA.MulRoundUp(sqrtPriceB) return liq.MulTruncate(diff).QuoTruncate(denom) +======= + // Each intermediary step is truncated at precision end to get a smaller final amount. + // Note that the order of divisions is important here. First, we divide by a larger number (sqrtPriceB) and then by a smaller number (sqrtPriceA). + // This leads to a smaller error amplification. + return liq.MulTruncate(diff).QuoTruncateMut(sqrtPriceB).QuoTruncateMut(sqrtPriceA) +>>>>>>> 114f055f (osmomath: QuoTruncate with no reallocation (#6428)) } // CalcAmount1Delta takes the asset with the smaller liquidity in the pool as well as the sqrtpCur and the nextPrice and calculates the amount of asset 1