@@ -5,14 +5,34 @@ import (
5
5
u256 "gno.land/p/gnoswap/uint256"
6
6
)
7
7
8
+ // SwapMathComputeSwapStepStr computes the next sqrt price, amount in, amount out, and fee amount
9
+ // Computes the result of swapping some amount in, or amount out, given the parameters of the swap
10
+ // The fee, plus the amount in, will never exceed the amount remaining if the swap's `amountSpecified` is positive
11
+ //
12
+ // input:
13
+ // - sqrtRatioCurrentX96: the current sqrt price of the pool
14
+ // - sqrtRatioTargetX96: The price that cannot be exceeded, from which the direction of the swap is inferred
15
+ // - liquidity: The usable liquidity of the pool
16
+ // - amountRemaining: How much input or output amount is remaining to be swapped in/out
17
+ // - feePips: The fee taken from the input amount, expressed in hundredths of a bip
18
+ //
19
+ // output:
20
+ // - sqrtRatioNextX96: The price after swapping the amount in/out, not to exceed the price target
21
+ // - amountIn: The amount to be swapped in, of either token0 or token1, based on the direction of the swap
22
+ // - amountOut: The amount to be received, of either token0 or token1, based on the direction of the swap
23
+ // - feeAmount: The amount of input that will be taken as a fee
8
24
func SwapMathComputeSwapStepStr(
9
- sqrtRatioCurrentX96 *u256.Uint, // uint160
10
- sqrtRatioTargetX96 *u256.Uint, // uint160
11
- liquidity *u256.Uint, // uint128
12
- amountRemaining *i256.Int, // int256
25
+ sqrtRatioCurrentX96 *u256.Uint,
26
+ sqrtRatioTargetX96 *u256.Uint,
27
+ liquidity *u256.Uint,
28
+ amountRemaining *i256.Int,
13
29
feePips uint64,
14
- ) (string, string, string, string) { // (sqrtRatioNextX96, amountIn, amountOut, feeAmount *u256.Uint)
15
- isToken1Expensive := sqrtRatioCurrentX96.Gte(sqrtRatioTargetX96)
30
+ ) (string, string, string, string) {
31
+ if sqrtRatioCurrentX96 == nil || sqrtRatioTargetX96 == nil || liquidity == nil || amountRemaining == nil {
32
+ panic("SwapMathComputeSwapStepStr: invalid input")
33
+ }
34
+
35
+ zeroForOne := sqrtRatioCurrentX96.Gte(sqrtRatioTargetX96)
16
36
17
37
// POSTIVIE == EXACT_IN => Estimated AmountOut
18
38
// NEGATIVE == EXACT_OUT => Estimated AmountIn
@@ -25,75 +45,94 @@ func SwapMathComputeSwapStepStr(
25
45
26
46
if exactIn {
27
47
amountRemainingLessFee := u256.MulDiv(amountRemaining.Abs(), u256.NewUint(1000000-feePips), u256.NewUint(1000000))
28
-
29
- if isToken1Expensive {
30
- amountIn = sqrtPriceMathGetAmount0DeltaHelper(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, true)
48
+ if zeroForOne {
49
+ amountIn = sqrtPriceMathGetAmount0DeltaHelper(
50
+ sqrtRatioTargetX96.Clone(),
51
+ sqrtRatioCurrentX96.Clone(),
52
+ liquidity.Clone(),
53
+ true)
31
54
} else {
32
- amountIn = sqrtPriceMathGetAmount1DeltaHelper(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, true)
55
+ amountIn = sqrtPriceMathGetAmount1DeltaHelper(
56
+ sqrtRatioCurrentX96.Clone(),
57
+ sqrtRatioTargetX96.Clone(),
58
+ liquidity.Clone(),
59
+ true)
33
60
}
34
61
35
62
if amountRemainingLessFee.Gte(amountIn) {
36
- sqrtRatioNextX96 = sqrtRatioTargetX96
63
+ sqrtRatioNextX96 = sqrtRatioTargetX96.Clone()
37
64
} else {
38
65
sqrtRatioNextX96 = sqrtPriceMathGetNextSqrtPriceFromInput(
39
- sqrtRatioCurrentX96,
40
- liquidity,
41
- amountRemainingLessFee,
42
- isToken1Expensive ,
66
+ sqrtRatioCurrentX96.Clone() ,
67
+ liquidity.Clone() ,
68
+ amountRemainingLessFee.Clone() ,
69
+ zeroForOne ,
43
70
)
44
71
}
45
-
46
72
} else {
47
- if isToken1Expensive {
48
- amountOut = sqrtPriceMathGetAmount1DeltaHelper(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, false)
73
+ if zeroForOne {
74
+ amountOut = sqrtPriceMathGetAmount1DeltaHelper(
75
+ sqrtRatioTargetX96.Clone(),
76
+ sqrtRatioCurrentX96.Clone(),
77
+ liquidity.Clone(),
78
+ false)
49
79
} else {
50
- amountOut = sqrtPriceMathGetAmount0DeltaHelper(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, false)
80
+ amountOut = sqrtPriceMathGetAmount0DeltaHelper(
81
+ sqrtRatioCurrentX96.Clone(),
82
+ sqrtRatioTargetX96.Clone(),
83
+ liquidity.Clone(),
84
+ false)
51
85
}
52
86
53
87
if amountRemaining.Abs().Gte(amountOut) {
54
- sqrtRatioNextX96 = sqrtRatioTargetX96
88
+ sqrtRatioNextX96 = sqrtRatioTargetX96.Clone()
55
89
} else {
56
90
sqrtRatioNextX96 = sqrtPriceMathGetNextSqrtPriceFromOutput(
57
- sqrtRatioCurrentX96,
58
- liquidity,
91
+ sqrtRatioCurrentX96.Clone() ,
92
+ liquidity.Clone() ,
59
93
amountRemaining.Abs(),
60
- isToken1Expensive ,
94
+ zeroForOne ,
61
95
)
62
96
}
63
97
}
64
98
65
- max := sqrtRatioTargetX96.Eq(sqrtRatioNextX96)
99
+ isMax := sqrtRatioTargetX96.Eq(sqrtRatioNextX96)
66
100
67
- if isToken1Expensive {
68
- if max && exactIn {
69
- amountIn = amountIn
70
- } else {
71
- amountIn = sqrtPriceMathGetAmount0DeltaHelper(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, true)
101
+ if zeroForOne {
102
+ if !(isMax && exactIn) {
103
+ amountIn = sqrtPriceMathGetAmount0DeltaHelper(
104
+ sqrtRatioNextX96.Clone(),
105
+ sqrtRatioCurrentX96.Clone(),
106
+ liquidity.Clone(),
107
+ true)
72
108
}
73
-
74
- if max && !exactIn {
75
- amountOut = amountOut
76
- } else {
77
- amountOut = sqrtPriceMathGetAmount1DeltaHelper(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, false)
109
+ if !(isMax && !exactIn) {
110
+ amountOut = sqrtPriceMathGetAmount1DeltaHelper(
111
+ sqrtRatioNextX96.Clone(),
112
+ sqrtRatioCurrentX96.Clone(),
113
+ liquidity.Clone(),
114
+ false)
78
115
}
79
116
} else {
80
- if max && exactIn {
81
- amountIn = amountIn
82
- } else {
83
- amountIn = sqrtPriceMathGetAmount1DeltaHelper(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, true)
117
+ if !(isMax && exactIn) {
118
+ amountIn = sqrtPriceMathGetAmount1DeltaHelper(
119
+ sqrtRatioCurrentX96.Clone(),
120
+ sqrtRatioNextX96.Clone(),
121
+ liquidity.Clone(),
122
+ true)
84
123
}
85
-
86
- if max && !exactIn {
87
- amountOut = amountOut
88
- } else {
89
- amountOut = sqrtPriceMathGetAmount0DeltaHelper(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, false)
124
+ if !(isMax && !exactIn) {
125
+ amountOut = sqrtPriceMathGetAmount0DeltaHelper(
126
+ sqrtRatioCurrentX96.Clone(),
127
+ sqrtRatioNextX96.Clone(),
128
+ liquidity.Clone(),
129
+ false)
90
130
}
91
131
}
92
132
93
133
if !exactIn && amountOut.Gt(amountRemaining.Abs()) {
94
134
amountOut = amountRemaining.Abs()
95
135
}
96
-
97
136
if exactIn && !(sqrtRatioNextX96.Eq(sqrtRatioTargetX96)) {
98
137
feeAmount = new(u256.Uint).Sub(amountRemaining.Abs(), amountIn)
99
138
} else {
0 commit comments