From 4d0f1678d8ac0e414a34b28631adb1bcc139ca4f Mon Sep 17 00:00:00 2001 From: it4rb Date: Tue, 10 Dec 2024 16:20:53 +0700 Subject: [PATCH 1/4] remove deleted ticks when fetching from ticklens (#640) * remove deleted ticks when fetching from ticklens * fix --- pkg/liquidity-source/algebra/integral/ticklens.go | 3 +++ pkg/liquidity-source/algebra/v1/ticklens.go | 3 +++ pkg/source/algebrav1/ticklens.go | 3 +++ pkg/util/ticklens/ticklens.go | 3 +++ 4 files changed, 12 insertions(+) diff --git a/pkg/liquidity-source/algebra/integral/ticklens.go b/pkg/liquidity-source/algebra/integral/ticklens.go index a4b75020a..8fbda5c7e 100644 --- a/pkg/liquidity-source/algebra/integral/ticklens.go +++ b/pkg/liquidity-source/algebra/integral/ticklens.go @@ -91,6 +91,9 @@ func (d *PoolTracker) getPoolTicksFromSC(ctx context.Context, pool entity.Pool, // changed, use new value combined = append(combined, tick) delete(changedTickMap, t.Index) + } else if changedTickSet.ContainsOne(int64(t.Index)) { + // some changed ticks might be consumed entirely and are not in `changedTickMap`, delete them + logger.Debugf("deleted tick %v %v", pool.Address, t) } else { // use old value combined = append(combined, TickResp{ diff --git a/pkg/liquidity-source/algebra/v1/ticklens.go b/pkg/liquidity-source/algebra/v1/ticklens.go index e27e14702..7edb04273 100644 --- a/pkg/liquidity-source/algebra/v1/ticklens.go +++ b/pkg/liquidity-source/algebra/v1/ticklens.go @@ -92,6 +92,9 @@ func (d *PoolTracker) getPoolTicksFromSC(ctx context.Context, pool entity.Pool, // changed, use new value combined = append(combined, tick) delete(changedTickMap, t.Index) + } else if changedTickSet.ContainsOne(int64(t.Index)) { + // some changed ticks might be consumed entirely and are not in `changedTickMap`, delete them + logger.Debugf("deleted tick %v %v", pool.Address, t) } else { // use old value combined = append(combined, TickResp{ diff --git a/pkg/source/algebrav1/ticklens.go b/pkg/source/algebrav1/ticklens.go index e27e14702..7edb04273 100644 --- a/pkg/source/algebrav1/ticklens.go +++ b/pkg/source/algebrav1/ticklens.go @@ -92,6 +92,9 @@ func (d *PoolTracker) getPoolTicksFromSC(ctx context.Context, pool entity.Pool, // changed, use new value combined = append(combined, tick) delete(changedTickMap, t.Index) + } else if changedTickSet.ContainsOne(int64(t.Index)) { + // some changed ticks might be consumed entirely and are not in `changedTickMap`, delete them + logger.Debugf("deleted tick %v %v", pool.Address, t) } else { // use old value combined = append(combined, TickResp{ diff --git a/pkg/util/ticklens/ticklens.go b/pkg/util/ticklens/ticklens.go index 1080234ff..7844da934 100644 --- a/pkg/util/ticklens/ticklens.go +++ b/pkg/util/ticklens/ticklens.go @@ -152,6 +152,9 @@ func GetPoolTicksFromSC( // changed, use new value combined = append(combined, tick) delete(changedTickMap, t.Index) + } else if changedTickSet.ContainsOne(int64(t.Index)) { + // some changed ticks might be consumed entirely and are not in `changedTickMap`, delete them + logger.Debugf("deleted tick %v %v", pool.Address, t) } else { // use old value combined = append(combined, TickResp{ From 642dd7e035597193dcaac0ab2867b801c893a09f Mon Sep 17 00:00:00 2001 From: Phu Ngo <12547020+NgoKimPhu@users.noreply.github.com> Date: Tue, 10 Dec 2024 18:11:47 +0700 Subject: [PATCH 2/4] ft/zkswap stable and v3 (#642) * ft: add zkswap-stable * ft: add zkswap-v3 --- pkg/source/curve/embed.go | 6 +++++ .../curve/pools/zkswap-stable/zksync.json | 26 +++++++++++++++++++ pkg/valueobject/exchange.go | 4 +++ 3 files changed, 36 insertions(+) create mode 100644 pkg/source/curve/pools/zkswap-stable/zksync.json diff --git a/pkg/source/curve/embed.go b/pkg/source/curve/embed.go index 3d476f443..92f6983e8 100644 --- a/pkg/source/curve/embed.go +++ b/pkg/source/curve/embed.go @@ -78,6 +78,11 @@ var arbitrumPancakeStablePoolsBytes []byte //go:embed pools/pancake-stable/bsc.json var bscPancakeStablePoolsBytes []byte +// ZkSwap-stable pool bytes + +//go:embed pools/zkswap-stable/zksync.json +var zksyncPoolsBytes []byte + var bytesByPath = map[string][]byte{ "pools/arbitrum.json": arbitrumPoolsBytes, "pools/avalanche.json": avalanchePoolsBytes, @@ -90,4 +95,5 @@ var bytesByPath = map[string][]byte{ "pools/ellipsis/bsc.json": ellipsisBscPoolsBytes, "pools/pancake-stable/arbitrum.json": arbitrumPancakeStablePoolsBytes, "pools/pancake-stable/bsc.json": bscPancakeStablePoolsBytes, + "pools/zkswap-stable/zksync.json": zksyncPoolsBytes, } diff --git a/pkg/source/curve/pools/zkswap-stable/zksync.json b/pkg/source/curve/pools/zkswap-stable/zksync.json new file mode 100644 index 000000000..6820b5ca3 --- /dev/null +++ b/pkg/source/curve/pools/zkswap-stable/zksync.json @@ -0,0 +1,26 @@ +[ + { + "id": "0x15309aaf4fedf346e5204331027b4ef7b75b1dd7", + "name": "USDC/USDC/USDT", + "type": "curve-base", + "lpToken": "0x31c330f2febda65693ec8801b77a93c6d1f479e4", + "aPrecision": "2000", + "tokens": [ + { + "address": "0x1d17cbcf0d6d143135ae902365d2e5e2a16538d4", + "precision": "1", + "rate": "1000000000000000000" + }, + { + "address": "0x3355df6d4c9c3035724fd0e3914de96a5a83aaf4", + "precision": "1", + "rate": "1000000000000000000" + }, + { + "address": "0x493257fd37edb34451f62edf8d2a0c418852ba4c", + "precision": "1", + "rate": "1000000000000000000" + } + ] + } +] diff --git a/pkg/valueobject/exchange.go b/pkg/valueobject/exchange.go index 909bead02..fc9a92c81 100644 --- a/pkg/valueobject/exchange.go +++ b/pkg/valueobject/exchange.go @@ -70,6 +70,7 @@ var ( ExchangeCurve Exchange = "curve" ExchangeEllipsis Exchange = "ellipsis" ExchangePancakeStable Exchange = "pancake-stable" + ExchangeZkSwapStable Exchange = "zkswap-stable" ExchangeCurveStablePlain Exchange = "curve-stable-plain" ExchangeCurveStableNg Exchange = "curve-stable-ng" @@ -157,6 +158,7 @@ var ( ExchangeRamsesV2 Exchange = "ramses-v2" ExchangePharaohV2 Exchange = "pharaoh-v2" ExchangeDackieV3 Exchange = "dackie-v3" + ExchangeZkSwapV3 Exchange = "zkswap-v3" ExchangeHoriza Exchange = "horiza" ExchangeBaseSwapV3 Exchange = "baseswap-v3" ExchangeArbiDexV3 Exchange = "arbidex-v3" @@ -446,6 +448,7 @@ var AMMSourceSet = map[Exchange]struct{}{ ExchangeCurveTwoCryptoNg: {}, ExchangeEllipsis: {}, ExchangePancakeStable: {}, + ExchangeZkSwapStable: {}, ExchangeUniSwapV3: {}, ExchangeKyberswapElastic: {}, ExchangeBalancer: {}, @@ -509,6 +512,7 @@ var AMMSourceSet = map[Exchange]struct{}{ ExchangeSushiSwapV3: {}, ExchangeRamsesV2: {}, ExchangeDackieV3: {}, + ExchangeZkSwapV3: {}, ExchangeHoriza: {}, ExchangeBaseSwapV3: {}, ExchangeArbiDexV3: {}, From 7f519d3040bbf628d4cc1aad891e0cdba740d1be Mon Sep 17 00:00:00 2001 From: Phu Ngo <12547020+NgoKimPhu@users.noreply.github.com> Date: Wed, 11 Dec 2024 02:04:01 +0700 Subject: [PATCH 3/4] fix: safe convert nil big.Int to "0" instead of "" --- pkg/source/curve/constant.go | 1 - pkg/source/curve/helper.go | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/source/curve/constant.go b/pkg/source/curve/constant.go index 437cb96ca..dd5cea17b 100644 --- a/pkg/source/curve/constant.go +++ b/pkg/source/curve/constant.go @@ -108,6 +108,5 @@ var weth9 = map[int]string{ var ( zeroBI = big.NewInt(0) - emptyString = "" zero int64 = 0 ) diff --git a/pkg/source/curve/helper.go b/pkg/source/curve/helper.go index 32d2ebe03..582fceae3 100644 --- a/pkg/source/curve/helper.go +++ b/pkg/source/curve/helper.go @@ -98,7 +98,7 @@ func convertToEtherAddress(address string, chain int) string { func safeCastBigIntToString(num *big.Int) string { if num == nil { - return emptyString + return zeroString } return num.String() From baf55e596f50c9cbf204a745eb69d4b9da42a657 Mon Sep 17 00:00:00 2001 From: tien7668 <33758175+tien7668@users.noreply.github.com> Date: Wed, 11 Dec 2024 09:51:28 +0700 Subject: [PATCH 4/4] avoid alloc uint256 too much (#641) --- pkg/liquidity-source/syncswapv2/aqua/math.go | 228 ++++++++++-------- .../syncswapv2/aqua/math_test.go | 170 +++++++++++++ .../syncswapv2/stable/math.go | 18 +- .../syncswapv2/stable/math_test.go | 64 +++++ 4 files changed, 363 insertions(+), 117 deletions(-) create mode 100644 pkg/liquidity-source/syncswapv2/aqua/math_test.go create mode 100644 pkg/liquidity-source/syncswapv2/stable/math_test.go diff --git a/pkg/liquidity-source/syncswapv2/aqua/math.go b/pkg/liquidity-source/syncswapv2/aqua/math.go index c345e0cb3..8b6e8a398 100644 --- a/pkg/liquidity-source/syncswapv2/aqua/math.go +++ b/pkg/liquidity-source/syncswapv2/aqua/math.go @@ -139,58 +139,60 @@ func newtonD(ANN *uint256.Int, gamma *uint256.Int, xUnsorted []*uint256.Int) (*u } else { _g1k0 = new(uint256.Int).Add(new(uint256.Int).Sub(K0, _g1k0), constant.One) } - var mul1 = new(uint256.Int).Div( - new(uint256.Int).Mul( - new(uint256.Int).Mul( - new(uint256.Int).Div( - new(uint256.Int).Mul( - new(uint256.Int).Div(new(uint256.Int).Mul(constant.BONE, D), gamma), _g1k0, - ), gamma, - ), - _g1k0, - ), - AMultiplier, - ), ANN, - ) - var mul2 = new(uint256.Int).Div( - new(uint256.Int).Mul( - new(uint256.Int).Mul( - new(uint256.Int).Mul(constant.Two, constant.BONE), nCoinsBi, - ), K0, - ), _g1k0, - ) - var negFprime = new(uint256.Int).Sub( - new(uint256.Int).Add( - new(uint256.Int).Add(S, new(uint256.Int).Div(new(uint256.Int).Mul(S, mul2), constant.BONE)), - new(uint256.Int).Div(new(uint256.Int).Mul(mul1, nCoinsBi), K0), - ), - new(uint256.Int).Div(new(uint256.Int).Mul(mul2, D), constant.BONE), + // var mul1 = new(uint256.Int).Div( + // new(uint256.Int).Mul( + // new(uint256.Int).Mul( + // new(uint256.Int).Div( + // new(uint256.Int).Mul( + // new(uint256.Int).Div(new(uint256.Int).Mul(constant.BONE, D), gamma), _g1k0, + // ), gamma, + // ), + // _g1k0, + // ), + // AMultiplier, + // ), ANN, + // ) + var mul1 = new(uint256.Int) + mul1.Mul(constant.BONE, D).Div(mul1, gamma).Mul(mul1, _g1k0).Div(mul1, gamma).Mul(mul1, _g1k0).Mul(mul1, AMultiplier).Div(mul1, ANN) + // var mul2 = new(uint256.Int).Div( + // new(uint256.Int).Mul( + // new(uint256.Int).Mul( + // new(uint256.Int).Mul(constant.Two, constant.BONE), nCoinsBi, + // ), K0, + // ), _g1k0, + // ) + var mul2 = new(uint256.Int) + mul2.Mul(constant.Two, constant.BONE).Mul(mul2, nCoinsBi).Mul(mul2, K0).Div(mul2, _g1k0) + // var negFprime = new(uint256.Int).Sub( + // new(uint256.Int).Add( + // new(uint256.Int).Add(S, new(uint256.Int).Div(new(uint256.Int).Mul(S, mul2), constant.BONE)), + // new(uint256.Int).Div(new(uint256.Int).Mul(mul1, nCoinsBi), K0), + // ), + // new(uint256.Int).Div(new(uint256.Int).Mul(mul2, D), constant.BONE), + // ) + var negFprime = new(uint256.Int) + negFprime.Mul(S, mul2).Div(negFprime, constant.BONE).Add(S, negFprime).Add( + new(uint256.Int).Set(negFprime), + negFprime.Mul(mul1, nCoinsBi).Div(negFprime, K0), + ).Sub( + new(uint256.Int).Set(negFprime), + negFprime.Mul(mul2, D).Div(negFprime, constant.BONE), ) - var DPlus = new(uint256.Int).Div(new(uint256.Int).Mul(D, new(uint256.Int).Add(negFprime, S)), negFprime) - var DMinus = new(uint256.Int).Div(new(uint256.Int).Mul(D, D), negFprime) + // var DPlus = new(uint256.Int).Div(new(uint256.Int).Mul(D, new(uint256.Int).Add(negFprime, S)), negFprime) + var DPlus = new(uint256.Int) + DPlus.Add(negFprime, S).Mul(D, DPlus).Div(DPlus, negFprime) + // var DMinus = new(uint256.Int).Div(new(uint256.Int).Mul(D, D), negFprime) + var DMinus = new(uint256.Int) + DMinus.Mul(D, D).Div(DMinus, negFprime) if constant.BONE.Cmp(K0) > 0 { - DMinus = new(uint256.Int).Add( - DMinus, - new(uint256.Int).Div( - new(uint256.Int).Mul( - new(uint256.Int).Div( - new(uint256.Int).Mul(D, new(uint256.Int).Div(mul1, negFprime)), constant.BONE, - ), new(uint256.Int).Sub(constant.BONE, K0), - ), - K0, - ), + DMinus.Add(new( + uint256.Int).Set(DMinus), + DMinus.Div(mul1, negFprime).Mul(D, DMinus).Div(DMinus, constant.BONE).Mul(DMinus, new(uint256.Int).Sub(constant.BONE, K0)).Div(DMinus, K0), ) } else { - DMinus = new(uint256.Int).Sub( - DMinus, - new(uint256.Int).Div( - new(uint256.Int).Mul( - new(uint256.Int).Div( - new(uint256.Int).Mul(D, new(uint256.Int).Div(mul1, negFprime)), constant.BONE, - ), new(uint256.Int).Sub(K0, constant.BONE), - ), - K0, - ), + DMinus.Add(new( + uint256.Int).Set(DMinus), + DMinus.Div(mul1, negFprime).Mul(D, DMinus).Div(DMinus, constant.BONE).Mul(DMinus, new(uint256.Int).Sub(K0, constant.BONE)).Div(DMinus, K0), ) } if DPlus.Cmp(DMinus) > 0 { @@ -267,24 +269,28 @@ func newtonY(ann *uint256.Int, gamma *uint256.Int, x []*uint256.Int, D *uint256. } else { _g1k0 = new(uint256.Int).Add(new(uint256.Int).Sub(K0, _g1k0), constant.One) } - var mul1 = new(uint256.Int).Div( - new(uint256.Int).Mul( - new(uint256.Int).Div( - new(uint256.Int).Mul( - new(uint256.Int).Div(new(uint256.Int).Mul(constant.BONE, D), gamma), - _g1k0, - ), gamma, - ), - new(uint256.Int).Mul(_g1k0, AMultiplier), - ), ann, - ) - var mul2 = new(uint256.Int).Add( - new(uint256.Int).Div( - new(uint256.Int).Mul( - new(uint256.Int).Mul(constant.Two, constant.BONE), K0, - ), _g1k0, - ), constant.BONE, - ) + // var mul1 = new(uint256.Int).Div( + // new(uint256.Int).Mul( + // new(uint256.Int).Div( + // new(uint256.Int).Mul( + // new(uint256.Int).Div(new(uint256.Int).Mul(constant.BONE, D), gamma), + // _g1k0, + // ), gamma, + // ), + // new(uint256.Int).Mul(_g1k0, AMultiplier), + // ), ann, + // ) + var mul1 = new(uint256.Int) + mul1.Mul(constant.BONE, D).Div(mul1, gamma).Mul(mul1, _g1k0).Div(mul1, gamma).Mul(mul1, _g1k0).Mul(mul1, AMultiplier).Div(mul1, ann) + // var mul2 = new(uint256.Int).Add( + // new(uint256.Int).Div( + // new(uint256.Int).Mul( + // new(uint256.Int).Mul(constant.Two, constant.BONE), K0, + // ), _g1k0, + // ), constant.BONE, + // ) + var mul2 = new(uint256.Int) + mul2.Mul(constant.Two, constant.BONE).Mul(mul2, K0).Div(mul2, _g1k0).Add(mul2, constant.BONE) var yfprime = new(uint256.Int).Add( new(uint256.Int).Add(new(uint256.Int).Mul(constant.BONE, y), new(uint256.Int).Mul(S, mul2)), mul1, ) @@ -685,50 +691,58 @@ func getCryptoFee(minFee, maxFee, gamma, xp0, xp1 *uint256.Int) *uint256.Int { // gamma.add(ETHER).sub(ETHER.mul(4).mul(xp0).div(f).mul(xp1).div(f)) // ); - f = new(uint256.Int).Div( - new(uint256.Int).Mul( - gamma, - constant.BONE, - ), - new(uint256.Int).Sub( - new(uint256.Int).Add( - gamma, - constant.BONE, - ), - new(uint256.Int).Div( - new(uint256.Int).Mul( - new(uint256.Int).Div( - new(uint256.Int).Mul( - new(uint256.Int).Mul( - constant.BONE, - constant.Four, - ), - xp0, - ), - f, - ), - xp1, - ), - f, - ), - ), + // f = new(uint256.Int).Div( + // new(uint256.Int).Mul( + // gamma, + // constant.BONE, + // ), + // new(uint256.Int).Sub( + // new(uint256.Int).Add( + // gamma, + // constant.BONE, + // ), + // new(uint256.Int).Div( + // new(uint256.Int).Mul( + // new(uint256.Int).Div( + // new(uint256.Int).Mul( + // new(uint256.Int).Mul( + // constant.BONE, + // constant.Four, + // ), + // xp0, + // ), + // f, + // ), + // xp1, + // ), + // f, + // ), + // ), + // ) + f1 := new(uint256.Int).Set(f) + f = f.Mul(constant.BONE, constant.Four).Mul(f, xp0).Div(f, f1).Mul(f, xp1).Div(f, f1).Sub( + new(uint256.Int).Add(gamma, constant.BONE), f, + ).Div( + new(uint256.Int).Mul(gamma, constant.BONE), f, ) // const fee = minFee.mul(f).add(maxFee.mul(ETHER.sub(f))).div(ETHER); - fee := new(uint256.Int).Div( - new(uint256.Int).Add( - new(uint256.Int).Mul( - minFee, f, - ), - new(uint256.Int).Mul( - maxFee, - new(uint256.Int).Sub( - constant.BONE, f, - ), - ), - ), - constant.BONE, - ) + // fee := new(uint256.Int).Div( + // new(uint256.Int).Add( + // new(uint256.Int).Mul( + // minFee, f, + // ), + // new(uint256.Int).Mul( + // maxFee, + // new(uint256.Int).Sub( + // constant.BONE, f, + // ), + // ), + // ), + // constant.BONE, + // ) + var fee = new(uint256.Int) + fee.Sub(constant.BONE, f).Mul(maxFee, fee).Add(fee, new(uint256.Int).Mul(minFee, f)).Div(fee, constant.BONE) return fee } diff --git a/pkg/liquidity-source/syncswapv2/aqua/math_test.go b/pkg/liquidity-source/syncswapv2/aqua/math_test.go new file mode 100644 index 000000000..eea952450 --- /dev/null +++ b/pkg/liquidity-source/syncswapv2/aqua/math_test.go @@ -0,0 +1,170 @@ +package syncswapv2aqua + +import ( + "testing" + + constant "github.com/KyberNetwork/kyberswap-dex-lib/pkg/util/big256" + "github.com/holiman/uint256" + "github.com/stretchr/testify/assert" +) + +func TestUint256Refactor(t *testing.T) { + func(D, gamma, _g1k0, ANN, AMultiplier *uint256.Int) { + var mul1 = new(uint256.Int) + assert.Equal(t, new(uint256.Int).Div( + new(uint256.Int).Mul( + new(uint256.Int).Mul( + new(uint256.Int).Div( + new(uint256.Int).Mul( + new(uint256.Int).Div(new(uint256.Int).Mul(constant.BONE, D), gamma), _g1k0, + ), gamma, + ), + _g1k0, + ), + AMultiplier, + ), ANN, + ), mul1.Mul(constant.BONE, D).Div(mul1, gamma).Mul(mul1, _g1k0).Div(mul1, gamma).Mul(mul1, _g1k0).Mul(mul1, AMultiplier).Div(mul1, ANN), "fail") + }(uint256.NewInt(2), uint256.NewInt(3), uint256.NewInt(4), uint256.NewInt(5), uint256.NewInt(6)) + + func(nCoinsBi, K0, _g1k0 *uint256.Int) { + var mul2 = new(uint256.Int) + assert.Equal(t, new(uint256.Int).Div( + new(uint256.Int).Mul( + new(uint256.Int).Mul( + new(uint256.Int).Mul(constant.Two, constant.BONE), nCoinsBi, + ), K0, + ), _g1k0, + ), mul2.Mul(constant.Two, constant.BONE).Mul(mul2, nCoinsBi).Mul(mul2, K0).Div(mul2, _g1k0), "fail") + }(uint256.NewInt(2), uint256.NewInt(3), uint256.NewInt(4)) + + func(S, mul2, mul1, nCoinsBi, K0, D *uint256.Int) { + var negFprime = new(uint256.Int) + assert.Equal(t, new(uint256.Int).Sub( + new(uint256.Int).Add( + new(uint256.Int).Add(S, new(uint256.Int).Div(new(uint256.Int).Mul(S, mul2), constant.BONE)), + new(uint256.Int).Div(new(uint256.Int).Mul(mul1, nCoinsBi), K0), + ), + new(uint256.Int).Div(new(uint256.Int).Mul(mul2, D), constant.BONE), + ), negFprime.Mul(S, mul2).Div(negFprime, constant.BONE).Add(S, negFprime).Add( + new(uint256.Int).Set(negFprime), + negFprime.Mul(mul1, nCoinsBi).Div(negFprime, K0), + ).Sub( + new(uint256.Int).Set(negFprime), + negFprime.Mul(mul2, D).Div(negFprime, constant.BONE), + ), "fail") + }(uint256.NewInt(2), uint256.NewInt(3), uint256.NewInt(4), uint256.NewInt(5), uint256.NewInt(6), uint256.NewInt(7)) + + func(D, negFprime, S *uint256.Int) { + var DPlus = new(uint256.Int) + assert.Equal(t, new(uint256.Int).Div(new(uint256.Int).Mul(D, new(uint256.Int).Add(negFprime, S)), negFprime), + DPlus.Add(negFprime, S).Mul(D, DPlus).Div(DPlus, negFprime), "fail") + }(uint256.NewInt(2), uint256.NewInt(3), uint256.NewInt(4)) + + func(D, negFprime *uint256.Int) { + var DMinus = new(uint256.Int) + assert.Equal(t, new(uint256.Int).Div(new(uint256.Int).Mul(D, D), negFprime), + DMinus.Mul(D, D).Div(DMinus, negFprime), "fail") + }(uint256.NewInt(2), uint256.NewInt(3)) + + func(D, mul1, negFprime, K0, DMinus *uint256.Int) { + assert.Equal(t, new(uint256.Int).Add( + DMinus, + new(uint256.Int).Div( + new(uint256.Int).Mul( + new(uint256.Int).Div( + new(uint256.Int).Mul(D, new(uint256.Int).Div(mul1, negFprime)), constant.BONE, + ), new(uint256.Int).Sub(constant.BONE, K0), + ), + K0, + ), + ), DMinus.Add(new( + uint256.Int).Set(DMinus), + DMinus.Div(mul1, negFprime).Mul(D, DMinus).Div(DMinus, constant.BONE).Mul(DMinus, new(uint256.Int).Sub(constant.BONE, K0)).Div(DMinus, K0), + ), "fail") + }(uint256.NewInt(2), uint256.NewInt(3), uint256.NewInt(4), uint256.NewInt(5), uint256.NewInt(6)) + + func(D, mul1, negFprime, K0, DMinus *uint256.Int) { + assert.Equal(t, new(uint256.Int).Sub( + DMinus, + new(uint256.Int).Div( + new(uint256.Int).Mul( + new(uint256.Int).Div( + new(uint256.Int).Mul(D, new(uint256.Int).Div(mul1, negFprime)), constant.BONE, + ), new(uint256.Int).Sub(K0, constant.BONE), + ), + K0, + ), + ), DMinus.Add(new( + uint256.Int).Set(DMinus), + DMinus.Div(mul1, negFprime).Mul(D, DMinus).Div(DMinus, constant.BONE).Mul(DMinus, new(uint256.Int).Sub(K0, constant.BONE)).Div(DMinus, K0), + ), "fail") + }(uint256.NewInt(2), uint256.NewInt(3), uint256.NewInt(4), uint256.NewInt(5), uint256.NewInt(6)) + + func(K0, _g1k0 *uint256.Int) { + var mul2 = new(uint256.Int) + assert.Equal(t, new(uint256.Int).Add( + new(uint256.Int).Div( + new(uint256.Int).Mul( + new(uint256.Int).Mul(constant.Two, constant.BONE), K0, + ), _g1k0, + ), constant.BONE, + ), mul2.Mul(constant.Two, constant.BONE).Mul(mul2, K0).Div(mul2, _g1k0).Add(mul2, constant.BONE), "fail") + }(uint256.NewInt(2), uint256.NewInt(3)) + + func(gamma, ETHER, xp0, xp1, f *uint256.Int) { + // f = gamma.mul(ETHER).div( + // gamma.add(ETHER).sub(ETHER.mul(4).mul(xp0).div(f).mul(xp1).div(f)) + // ); + f1 := new(uint256.Int).Set(f) + assert.Equal(t, new(uint256.Int).Div( + new(uint256.Int).Mul( + gamma, + constant.BONE, + ), + new(uint256.Int).Sub( + new(uint256.Int).Add( + gamma, + constant.BONE, + ), + new(uint256.Int).Div( + new(uint256.Int).Mul( + new(uint256.Int).Div( + new(uint256.Int).Mul( + new(uint256.Int).Mul( + constant.BONE, + constant.Four, + ), + xp0, + ), + f, + ), + xp1, + ), + f, + ), + ), + ), f.Mul(constant.BONE, constant.Four).Mul(f, xp0).Div(f, f1).Mul(f, xp1).Div(f, f1).Sub( + new(uint256.Int).Add(gamma, constant.BONE), f, + ).Div( + new(uint256.Int).Mul(gamma, constant.BONE), f, + ), "fail") + }(uint256.NewInt(2), uint256.NewInt(3), uint256.NewInt(4), uint256.NewInt(5), uint256.NewInt(6)) + + func(minFee, maxFee, f *uint256.Int) { + var fee = new(uint256.Int) + assert.Equal(t, new(uint256.Int).Div( + new(uint256.Int).Add( + new(uint256.Int).Mul( + minFee, f, + ), + new(uint256.Int).Mul( + maxFee, + new(uint256.Int).Sub( + constant.BONE, f, + ), + ), + ), + constant.BONE, + ), fee.Sub(constant.BONE, f).Mul(maxFee, fee).Add(fee, new(uint256.Int).Mul(minFee, f)).Div(fee, constant.BONE), "fail") + }(uint256.NewInt(2), uint256.NewInt(3), uint256.NewInt(4)) +} diff --git a/pkg/liquidity-source/syncswapv2/stable/math.go b/pkg/liquidity-source/syncswapv2/stable/math.go index e6797e0dd..6c67ad2ba 100644 --- a/pkg/liquidity-source/syncswapv2/stable/math.go +++ b/pkg/liquidity-source/syncswapv2/stable/math.go @@ -56,7 +56,7 @@ func _getAmountIn( // amountIn = MAX_FEE * (x - adjustedReserveIn) / (MAX_FEE - swapFee) + 1; // amountIn /= tokenInPrecisionMultiplier; amountIn := new(uint256.Int) - amountIn.Set(x).Sub(amountIn, adjustedReserveIn).Mul(amountIn, MaxFee).Div( + amountIn.Sub(x, adjustedReserveIn).Mul(amountIn, MaxFee).Div( amountIn, new(uint256.Int).Sub(MaxFee, swapFee), ).Add(amountIn, constant.One).Div(amountIn, tokenInPrecisionMultiplier) @@ -126,18 +126,16 @@ func computeDFromAdjustedBalances(xp0, xp1 *uint256.Int, A *uint256.Int) *uint25 //d = (((2000 * s) + 2 * dP) * d) / ((2000 - 1) * d + 3 * dP); num := new(uint256.Int) den := new(uint256.Int) - d = num.Div( - num.Mul( - num.Add( - num.Set(A).Mul(num, s), - new(uint256.Int).Mul(constant.Two, dp), - ), d), - den.Add( - den.Mul(den.Set(A).Sub(den, constant.One), d), + d = num.Mul(A, s).Add( + num, + new(uint256.Int).Mul(constant.Two, dp), + ).Mul(num, d).Div( + num, + den.Sub(A, constant.One).Mul(den, d).Add( + den, new(uint256.Int).Mul(constant.Three, dp), ), ) - if within1(d, prevD) { break } diff --git a/pkg/liquidity-source/syncswapv2/stable/math_test.go b/pkg/liquidity-source/syncswapv2/stable/math_test.go new file mode 100644 index 000000000..20140f9d6 --- /dev/null +++ b/pkg/liquidity-source/syncswapv2/stable/math_test.go @@ -0,0 +1,64 @@ +package syncswapv2stable + +import ( + "testing" + + constant "github.com/KyberNetwork/kyberswap-dex-lib/pkg/util/big256" + "github.com/holiman/uint256" + "github.com/stretchr/testify/assert" +) + +func TestUint256Refactor(t *testing.T) { + func(A, s, dp, d *uint256.Int) { + num := new(uint256.Int) + den := new(uint256.Int) + assert.Equal(t, new(uint256.Int).Div( + new(uint256.Int).Mul( + new(uint256.Int).Add( + new(uint256.Int).Mul(A, s), + new(uint256.Int).Mul(uint256.NewInt(2), dp), + ), d), + new(uint256.Int).Add( + new(uint256.Int).Mul(new(uint256.Int).Sub(A, uint256.NewInt(1)), d), + new(uint256.Int).Mul(uint256.NewInt(3), dp), + ), + ), num.Mul(A, s).Add( + num, + new(uint256.Int).Mul(constant.Two, dp), + ).Mul(num, d).Div( + num, + den.Sub(A, constant.One).Mul(den, d).Add( + den, + new(uint256.Int).Mul(constant.Three, dp), + ), + ), "fail") + }(uint256.NewInt(2), uint256.NewInt(3), uint256.NewInt(4), uint256.NewInt(5)) + + func(x, adjustedReserveIn, MaxFee, swapFee, tokenInPrecisionMultiplier *uint256.Int) { + amountIn := new(uint256.Int) + assert.Equal(t, new(uint256.Int).Div(new(uint256.Int).Add( + new(uint256.Int).Div( + new(uint256.Int).Mul( + MaxFee, + new(uint256.Int).Sub(x, adjustedReserveIn), + ), + new(uint256.Int).Sub(MaxFee, swapFee), + ), + uint256.NewInt(1), + ), tokenInPrecisionMultiplier), + amountIn.Sub(x, adjustedReserveIn).Mul(amountIn, MaxFee).Div( + amountIn, + new(uint256.Int).Sub(MaxFee, swapFee), + ).Add(amountIn, constant.One).Div(amountIn, tokenInPrecisionMultiplier), "fail") + }(uint256.NewInt(2), uint256.NewInt(3), uint256.NewInt(4), uint256.NewInt(5), uint256.NewInt(6)) + + func(d, xp0, xp1 *uint256.Int) { + var dp = new(uint256.Int) + assert.Equal(t, new(uint256.Int).Div( + new(uint256.Int).Div( + new(uint256.Int).Mul( + new(uint256.Int).Div( + new(uint256.Int).Mul(d, d), xp0), d), xp1), uint256.NewInt(4)), + dp.Set(d).Mul(dp, d).Div(dp, xp0).Mul(dp, d).Div(dp, xp1).Div(dp, constant.Four), "fail") + }(uint256.NewInt(2), uint256.NewInt(3), uint256.NewInt(4)) +}