Skip to content

Commit

Permalink
osmomath: QuoTruncate with no reallocation (#6428)
Browse files Browse the repository at this point in the history
* reduce reallocations of QuoTruncate

* separate funcs

* chopPrecisionAndTruncateMut

* changlog & go.mod

* mutative

* test

* go.mod

* go mod tidy

* update go.mod

* lack

* revert

* update go.mod

(cherry picked from commit 114f055)

# Conflicts:
#	CHANGELOG.md
#	go.mod
#	go.sum
#	x/concentrated-liquidity/math/math.go
  • Loading branch information
hieuvubk authored and mergify[bot] committed Sep 20, 2023
1 parent 992b5b2 commit a4b3fe3
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 17 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand All @@ -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=
Expand Down
13 changes: 13 additions & 0 deletions osmomath/decimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
59 changes: 59 additions & 0 deletions osmomath/decimal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}

7 changes: 7 additions & 0 deletions x/concentrated-liquidity/math/math.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit a4b3fe3

Please sign in to comment.