Skip to content

Commit 176eddf

Browse files
authored
Merge branch 'main' into refactor-delegates
2 parents 725b7b4 + 8034593 commit 176eddf

File tree

158 files changed

+4863
-2429
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

158 files changed

+4863
-2429
lines changed

Diff for: contract/p/gnoswap/gnsmath/bit_math.gno

+14-13
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
11
package gnsmath
22

33
import (
4+
"gno.land/p/gnoswap/consts"
45
u256 "gno.land/p/gnoswap/uint256"
56
)
67

78
var (
89
msbShifts = []bitShift{
9-
{u256.MustFromDecimal(Q128), 128}, // 2^128
10-
{u256.MustFromDecimal(Q64), 64}, // 2^64
11-
{u256.NewUint(0x100000000), 32}, // 2^32
12-
{u256.NewUint(0x10000), 16}, // 2^16
13-
{u256.NewUint(0x100), 8}, // 2^8
14-
{u256.NewUint(0x10), 4}, // 2^4
15-
{u256.NewUint(0x4), 2}, // 2^2
16-
{u256.NewUint(0x2), 1}, // 2^1
10+
{u256.MustFromDecimal(consts.Q128), 128}, // 2^128
11+
{u256.MustFromDecimal(consts.Q64), 64}, // 2^64
12+
{u256.NewUint(0x100000000), 32}, // 2^32
13+
{u256.NewUint(0x10000), 16}, // 2^16
14+
{u256.NewUint(0x100), 8}, // 2^8
15+
{u256.NewUint(0x10), 4}, // 2^4
16+
{u256.NewUint(0x4), 2}, // 2^2
17+
{u256.NewUint(0x2), 1}, // 2^1
1718
}
1819

1920
lsbShifts = []bitShift{
20-
{u256.MustFromDecimal(MAX_UINT128), 128},
21-
{u256.MustFromDecimal(MAX_UINT64), 64},
22-
{u256.MustFromDecimal(MAX_UINT32), 32},
23-
{u256.MustFromDecimal(MAX_UINT16), 16},
24-
{u256.MustFromDecimal(MAX_UINT8), 8},
21+
{u256.MustFromDecimal(consts.MAX_UINT128), 128},
22+
{u256.MustFromDecimal(consts.MAX_UINT64), 64},
23+
{u256.MustFromDecimal(consts.MAX_UINT32), 32},
24+
{u256.MustFromDecimal(consts.MAX_UINT16), 16},
25+
{u256.MustFromDecimal(consts.MAX_UINT8), 8},
2526
{u256.NewUint(0xf), 4},
2627
{u256.NewUint(0x3), 2},
2728
{u256.NewUint(0x1), 1},

Diff for: contract/p/gnoswap/gnsmath/consts.gno

-16
This file was deleted.

Diff for: contract/p/gnoswap/gnsmath/sqrt_price_math.gno

+46-27
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package gnsmath
22

33
import (
4+
"gno.land/p/gnoswap/consts"
45
i256 "gno.land/p/gnoswap/int256"
56
u256 "gno.land/p/gnoswap/uint256"
67
)
@@ -11,47 +12,60 @@ const (
1112
)
1213

1314
var (
14-
q96 = u256.MustFromDecimal(Q96)
15-
max160 = u256.MustFromDecimal(MAX_UINT160)
15+
q96 = u256.MustFromDecimal(consts.Q96)
16+
max160 = u256.MustFromDecimal(consts.MAX_UINT160)
1617
)
1718

1819
// getNextPriceAmount0Add calculates the next sqrt price when we are adding token0.
1920
// Preserves the rounding-up logic. No in-place mutation of input arguments.
2021
func getNextPriceAmount0Add(
21-
sqrtPX96, liquidity, amount *u256.Uint,
22+
currentSqrtPriceX96, liquidity, amountToAdd *u256.Uint,
2223
) *u256.Uint {
23-
numerator1 := new(u256.Uint).Lsh(liquidity, Q96_RESOLUTION)
24-
product := new(u256.Uint).Mul(amount, sqrtPX96)
25-
26-
// overflow check
27-
if new(u256.Uint).Div(product, amount).Eq(sqrtPX96) {
28-
denominator := new(u256.Uint).Add(numerator1, product)
29-
if denominator.Gte(numerator1) {
30-
return u256.MulDivRoundingUp(numerator1, sqrtPX96, denominator)
24+
// Shift liquidity left by Q96 bits to increase precision
25+
liquidityShifted := new(u256.Uint).Lsh(liquidity, Q96_RESOLUTION)
26+
// Multiply the amount to add by the current square root price
27+
amountTimesSqrtPrice := new(u256.Uint).Mul(amountToAdd, currentSqrtPriceX96)
28+
29+
// Overflow check: Ensure (amountTimesSqrtPrice / amountToAdd) == currentSqrtPriceX96
30+
if new(u256.Uint).Div(amountTimesSqrtPrice, amountToAdd).Eq(currentSqrtPriceX96) {
31+
// Compute denominator: liquidityShifted + (amountToAdd * currentSqrtPriceX96)
32+
denominator := new(u256.Uint).Add(liquidityShifted, amountTimesSqrtPrice)
33+
if denominator.Gte(liquidityShifted) {
34+
return u256.MulDivRoundingUp(liquidityShifted, currentSqrtPriceX96, denominator)
3135
}
3236
}
3337

34-
divValue := new(u256.Uint).Div(numerator1, sqrtPX96)
35-
addValue := new(u256.Uint).Add(divValue, amount)
38+
// Alternative computation path: (liquidityShifted / currentSqrtPriceX96) + amountToAdd
39+
divValue := new(u256.Uint).Div(liquidityShifted, currentSqrtPriceX96)
40+
addValue := new(u256.Uint).Add(divValue, amountToAdd)
3641

37-
return u256.DivRoundingUp(numerator1, addValue)
42+
// Compute the next square root price using division rounding up
43+
return u256.DivRoundingUp(liquidityShifted, addValue)
3844
}
3945

4046
// getNextPriceAmount0Remove calculates the next sqrt price when we are removing token0.
4147
// Preserves the rounding-up logic. No in-place mutation of input arguments.
4248
func getNextPriceAmount0Remove(
43-
sqrtPX96, liquidity, amount *u256.Uint,
49+
currentSqrtPriceX96, liquidity, amountToRemove *u256.Uint,
4450
) *u256.Uint {
45-
numerator1 := new(u256.Uint).Lsh(liquidity, Q96_RESOLUTION)
46-
product := new(u256.Uint).Mul(amount, sqrtPX96)
51+
// Shift liquidity left by Q96 bits to increase precision
52+
liquidityShifted := new(u256.Uint).Lsh(liquidity, Q96_RESOLUTION)
53+
54+
// Multiply the amount to remove by the current square root price
55+
amountTimesSqrtPrice := new(u256.Uint).Mul(amountToRemove, currentSqrtPriceX96)
4756

4857
// Conditions must hold: product/amount == sqrtPX96 and numerator1 > product
49-
if !new(u256.Uint).Div(product, amount).Eq(sqrtPX96) || !numerator1.Gt(product) {
58+
if !new(u256.Uint).Div(amountTimesSqrtPrice, amountToRemove).Eq(currentSqrtPriceX96) ||
59+
!liquidityShifted.Gt(amountTimesSqrtPrice) {
5060
panic(errInvalidPoolSqrtPrice)
5161
}
5262

53-
denominator := new(u256.Uint).Sub(numerator1, product)
54-
nextSqrtPrice := u256.MulDivRoundingUp(numerator1, sqrtPX96, denominator)
63+
// Compute denominator: liquidityShifted - (amountToRemove * currentSqrtPriceX96)
64+
denominator := new(u256.Uint).Sub(liquidityShifted, amountTimesSqrtPrice)
65+
// Calculate next square root price: (liquidityShifted * currentSqrtPriceX96) / denominator (with rounding up)
66+
nextSqrtPrice := u256.MulDivRoundingUp(liquidityShifted, currentSqrtPriceX96, denominator)
67+
68+
// Check for overflow
5569
if nextSqrtPrice.Gt(max160) {
5670
panic(errNextSqrtPriceOverflow)
5771
}
@@ -95,11 +109,9 @@ func getNextSqrtPriceFromAmount0RoundingUp(
95109
if add {
96110
return getNextPriceAmount0Add(sqrtPX96, liquidity, amount)
97111
}
98-
99112
return getNextPriceAmount0Remove(sqrtPX96, liquidity, amount)
100113
}
101114

102-
103115
// getNextPriceAmount1Add calculates the next sqrt price when adding token1.
104116
// Preserves rounding-down logic for the final result.
105117
func getNextPriceAmount1Add(
@@ -172,9 +184,16 @@ func getNextPriceAmount1Remove(
172184
// - The function uses high-precision math (MulDiv and DivRoundingUp) to handle division and prevent precision loss.
173185
// - The function validates input conditions and panics if the state is invalid.
174186
func getNextSqrtPriceFromAmount1RoundingDown(
175-
sqrtPX96, liquidity, amount *u256.Uint,
187+
sqrtPX96,
188+
liquidity,
189+
amount *u256.Uint,
176190
add bool,
177191
) *u256.Uint {
192+
// Shortcut: if no amount, return original price
193+
if amount.IsZero() {
194+
return sqrtPX96
195+
}
196+
178197
if add {
179198
return getNextPriceAmount1Add(sqrtPX96, liquidity, amount)
180199
}
@@ -367,7 +386,7 @@ func GetAmount0DeltaStr(
367386
) string {
368387
if liquidity.IsNeg() {
369388
u := getAmount0DeltaHelper(sqrtRatioAX96, sqrtRatioBX96, liquidity.Abs(), false)
370-
if u.Gt(u256.MustFromDecimal(MAX_INT256)) {
389+
if u.Gt(u256.MustFromDecimal(consts.MAX_INT256)) {
371390
// if u > (2**255 - 1), cannot cast to int256
372391
panic(errAmount0DeltaOverflow)
373392
}
@@ -376,7 +395,7 @@ func GetAmount0DeltaStr(
376395
}
377396

378397
u := getAmount0DeltaHelper(sqrtRatioAX96, sqrtRatioBX96, liquidity.Abs(), true)
379-
if u.Gt(u256.MustFromDecimal(MAX_INT256)) {
398+
if u.Gt(u256.MustFromDecimal(consts.MAX_INT256)) {
380399
// if u > (2**255 - 1), cannot cast to int256
381400
panic(errAmount0DeltaOverflow)
382401
}
@@ -410,7 +429,7 @@ func GetAmount1DeltaStr(
410429
) string {
411430
if liquidity.IsNeg() {
412431
u := getAmount1DeltaHelper(sqrtRatioAX96, sqrtRatioBX96, liquidity.Abs(), false)
413-
if u.Gt(u256.MustFromDecimal(MAX_INT256)) {
432+
if u.Gt(u256.MustFromDecimal(consts.MAX_INT256)) {
414433
// if u > (2**255 - 1), cannot cast to int256
415434
panic(errAmount1DeltaOverflow)
416435
}
@@ -419,7 +438,7 @@ func GetAmount1DeltaStr(
419438
}
420439

421440
u := getAmount1DeltaHelper(sqrtRatioAX96, sqrtRatioBX96, liquidity.Abs(), true)
422-
if u.Gt(u256.MustFromDecimal(MAX_INT256)) {
441+
if u.Gt(u256.MustFromDecimal(consts.MAX_INT256)) {
423442
// if u > (2**255 - 1), cannot cast to int256
424443
panic(errAmount1DeltaOverflow)
425444
}

Diff for: contract/p/gnoswap/gnsmath/sqrt_price_math_test.gno

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55

66
"gno.land/p/demo/uassert"
77

8+
"gno.land/p/gnoswap/consts"
89
i256 "gno.land/p/gnoswap/int256"
910
u256 "gno.land/p/gnoswap/uint256"
1011
)
@@ -422,15 +423,15 @@ func TestSqrtPriceMathGetNextSqrtPriceFromOutput(t *testing.T) {
422423
name: "reverts if amountOut is impossible in zero for one direction",
423424
sqrtPriceX96: encodePriceSqrt("1", "1"),
424425
liquidity: u256.NewUint(1),
425-
amountOut: u256.MustFromDecimal(MAX_UINT256),
426+
amountOut: u256.MustFromDecimal(consts.MAX_UINT256),
426427
zeroForOne: true,
427428
shouldPanic: true,
428429
},
429430
{
430431
name: "reverts if amountOut is impossible in one for zero direction",
431432
sqrtPriceX96: encodePriceSqrt("1", "1"),
432433
liquidity: u256.NewUint(1),
433-
amountOut: u256.MustFromDecimal(MAX_UINT256),
434+
amountOut: u256.MustFromDecimal(consts.MAX_UINT256),
434435
zeroForOne: false,
435436
shouldPanic: true,
436437
},

Diff for: contract/p/gnoswap/int256/conversion_test.gno

+1-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ func TestSet(t *testing.T) {
142142

143143
got := z.ToString()
144144
if got != tc.want {
145-
t.Errorf("Set(%s) = %s, want %s", tc.x, got, tc.want)
145+
t.Errorf("set(%s) = %s, want %s", tc.x, got, tc.want)
146146
}
147147
}
148148
}

Diff for: contract/p/gnoswap/int256/gno.mod

-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
module gno.land/p/gnoswap/int256
22

3-
require gno.land/p/gnoswap/uint256 v0.0.0-latest

Diff for: contract/p/gnoswap/uint256/gno.mod

-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
module gno.land/p/gnoswap/uint256
22

3-
require gno.land/p/demo/ufmt v0.0.0-latest

Diff for: contract/r/gnoswap/common/errors.gno

+10-10
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@ import (
77
)
88

99
var (
10-
errNoPermission = errors.New("[GNOSWAP-COMMON-001] caller has no permission")
11-
errHalted = errors.New("[GNOSWAP-COMMON-002] halted")
12-
errOutOfRange = errors.New("[GNOSWAP-COMMON-003] value out of range")
13-
errNotRegistered = errors.New("[GNOSWAP-COMMON-004] token is not registered")
14-
errInvalidAddr = errors.New("[GNOSWAP-COMMON-005] invalid address")
15-
errOverflow = errors.New("[GNOSWAP-COMMON-006] overflow")
16-
errInvalidTokenId = errors.New("[GNOSWAP-COMMON-007] invalid tokenId")
17-
errInvalidInput = errors.New("[GNOSWAP-COMMON-008] invalid input data")
18-
errOverFlow = errors.New("[GNOSWAP-COMMON-009] overflow")
19-
errIdenticalTicks = errors.New("[GNOSWAP-COMMON-010] identical ticks")
10+
errNoPermission = errors.New("[GNOSWAP-COMMON-001] caller has no permission")
11+
errHalted = errors.New("[GNOSWAP-COMMON-002] halted")
12+
errOutOfRange = errors.New("[GNOSWAP-COMMON-003] value out of range")
13+
errNotRegistered = errors.New("[GNOSWAP-COMMON-004] token is not registered")
14+
errInvalidAddr = errors.New("[GNOSWAP-COMMON-005] invalid address")
15+
errOverflow = errors.New("[GNOSWAP-COMMON-006] overflow")
16+
errInvalidPositionId = errors.New("[GNOSWAP-COMMON-007] invalid positionId")
17+
errInvalidInput = errors.New("[GNOSWAP-COMMON-008] invalid input data")
18+
errOverFlow = errors.New("[GNOSWAP-COMMON-009] overflow")
19+
errIdenticalTicks = errors.New("[GNOSWAP-COMMON-010] identical ticks")
2020
)
2121

2222
// newErrorWithDetail appends additional context or details to an existing error message.

Diff for: contract/r/gnoswap/common/grc721_position_id.gno

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package common
2+
3+
import (
4+
"strconv"
5+
6+
"gno.land/p/demo/ufmt"
7+
8+
"gno.land/p/demo/grc/grc721"
9+
)
10+
11+
// PositionIdFrom converts positionId to grc721.TokenID type
12+
// NOTE: input parameter positionId can be string, int, uint64, or grc721.TokenID
13+
// if positionId is nil or not supported, it will panic
14+
// if input type is not supported, it will panic
15+
// input: positionId interface{}
16+
// output: grc721.TokenID
17+
func PositionIdFrom(positionId interface{}) grc721.TokenID {
18+
if positionId == nil {
19+
panic(newErrorWithDetail(
20+
errInvalidPositionId,
21+
"can not be nil",
22+
))
23+
}
24+
25+
switch positionId.(type) {
26+
case string:
27+
return grc721.TokenID(positionId.(string))
28+
case int:
29+
return grc721.TokenID(strconv.Itoa(positionId.(int)))
30+
case uint64:
31+
return grc721.TokenID(strconv.Itoa(int(positionId.(uint64))))
32+
case grc721.TokenID:
33+
return positionId.(grc721.TokenID)
34+
default:
35+
estimatedType := ufmt.Sprintf("%T", positionId)
36+
panic(newErrorWithDetail(
37+
errInvalidPositionId,
38+
ufmt.Sprintf("unsupported positionId type: %s", estimatedType),
39+
))
40+
}
41+
}

Diff for: contract/r/gnoswap/common/grc721_token_id_test.gno renamed to contract/r/gnoswap/common/grc721_position_id_test.gno

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"gno.land/p/demo/grc/grc721"
77
)
88

9-
func TestTokenIdFrom(t *testing.T) {
9+
func TestPositionIdFrom(t *testing.T) {
1010
tests := []struct {
1111
name string
1212
input interface{}
@@ -50,14 +50,14 @@ func TestTokenIdFrom(t *testing.T) {
5050
if tt.wantPanic {
5151
defer func() {
5252
if r := recover(); r == nil {
53-
t.Errorf("TokenIdFrom() should have panicked")
53+
t.Errorf("PositionIdFrom() should have panicked")
5454
}
5555
}()
5656
}
5757

58-
got := TokenIdFrom(tt.input)
58+
got := PositionIdFrom(tt.input)
5959
if got != tt.want {
60-
t.Errorf("TokenIdFrom() = %v, want %v", got, tt.want)
60+
t.Errorf("PositionIdFrom() = %v, want %v", got, tt.want)
6161
}
6262
})
6363
}

Diff for: contract/r/gnoswap/common/grc721_token_id.gno

-41
This file was deleted.

0 commit comments

Comments
 (0)