@@ -22,27 +22,33 @@ library AclAmmMath {
22
22
uint256 [] memory balancesScaled18 ,
23
23
uint256 [] memory lastVirtualBalances ,
24
24
uint256 c ,
25
- uint256 sqrtQ0 ,
26
25
uint256 lastTimestamp ,
27
26
uint256 centerednessMargin ,
28
27
SqrtQ0State memory sqrtQ0State ,
29
28
Rounding rounding
30
29
) internal view returns (uint256 ) {
31
- function (uint256 , uint256 ) pure returns (uint256 ) _mulUpOrDown = rounding == Rounding.ROUND_DOWN
32
- ? FixedPoint.mulDown
33
- : FixedPoint.mulUp;
34
-
35
30
(uint256 [] memory virtualBalances , ) = getVirtualBalances (
36
31
balancesScaled18,
37
32
lastVirtualBalances,
38
33
c,
39
- sqrtQ0,
40
34
lastTimestamp,
41
- centerednessMargin,
42
35
block .timestamp ,
36
+ centerednessMargin,
43
37
sqrtQ0State
44
38
);
45
39
40
+ return computeInvariant (balancesScaled18, virtualBalances, rounding);
41
+ }
42
+
43
+ function computeInvariant (
44
+ uint256 [] memory balancesScaled18 ,
45
+ uint256 [] memory virtualBalances ,
46
+ Rounding rounding
47
+ ) internal pure returns (uint256 ) {
48
+ function (uint256 , uint256 ) pure returns (uint256 ) _mulUpOrDown = rounding == Rounding.ROUND_DOWN
49
+ ? FixedPoint.mulDown
50
+ : FixedPoint.mulUp;
51
+
46
52
return _mulUpOrDown ((balancesScaled18[0 ] + virtualBalances[0 ]), (balancesScaled18[1 ] + virtualBalances[1 ]));
47
53
}
48
54
@@ -93,19 +99,27 @@ library AclAmmMath {
93
99
uint256 [] memory balancesScaled18 ,
94
100
uint256 [] memory lastVirtualBalances ,
95
101
uint256 c ,
96
- uint256 sqrtQ0 ,
97
102
uint256 lastTimestamp ,
103
+ uint256 currentTimestamp ,
98
104
uint256 centerednessMargin ,
99
- uint256 currentTime ,
100
105
SqrtQ0State memory sqrtQ0State //TODO: optimize gas usage
101
106
) internal view returns (uint256 [] memory virtualBalances , bool changed ) {
102
107
// TODO Review rounding
103
108
// TODO: try to find better way to change the virtual balances in storage
104
109
105
- virtualBalances = new uint256 [](balancesScaled18.length );
110
+ virtualBalances = lastVirtualBalances;
111
+
112
+ // Calculate currentSqrtQ0
113
+ uint256 currentSqrtQ0 = calculateSqrtQ0 (
114
+ currentTimestamp,
115
+ sqrtQ0State.startSqrtQ0,
116
+ sqrtQ0State.endSqrtQ0,
117
+ sqrtQ0State.startTime,
118
+ sqrtQ0State.endTime
119
+ );
106
120
107
121
if (isPoolInRange (balancesScaled18, lastVirtualBalances, centerednessMargin) == false ) {
108
- uint256 q0 = sqrtQ0 .mulDown (sqrtQ0 );
122
+ uint256 q0 = currentSqrtQ0 .mulDown (currentSqrtQ0 );
109
123
110
124
if (isAboveCenter (balancesScaled18, lastVirtualBalances)) {
111
125
virtualBalances[1 ] = lastVirtualBalances[1 ].mulDown (
@@ -126,26 +140,35 @@ library AclAmmMath {
126
140
}
127
141
128
142
changed = true ;
129
- } else if (sqrtQ0State.startTime != 0 && currentTime > sqrtQ0State.startTime) {
130
- uint256 rACenter = lastVirtualBalances[0 ].mulDown (sqrtQ0State.startSqrtQ0 - FixedPoint.ONE);
131
- uint256 rBCenter = lastVirtualBalances[1 ].mulDown (sqrtQ0State.startSqrtQ0 - FixedPoint.ONE);
143
+ }
132
144
133
- uint256 currentSqrtQ0 = calculateSqrtQ0 (
134
- currentTime,
145
+ if (
146
+ sqrtQ0State.startTime != 0 &&
147
+ currentTimestamp > sqrtQ0State.startTime &&
148
+ (currentTimestamp < sqrtQ0State.endTime || lastTimestamp < sqrtQ0State.endTime)
149
+ ) {
150
+ uint256 lastSqrtQ0 = calculateSqrtQ0 (
151
+ lastTimestamp,
135
152
sqrtQ0State.startSqrtQ0,
136
153
sqrtQ0State.endSqrtQ0,
137
154
sqrtQ0State.startTime,
138
155
sqrtQ0State.endTime
139
156
);
140
157
158
+ // Ra_center = Va * (lastSqrtQ0 - 1)
159
+ uint256 rACenter = lastVirtualBalances[0 ].mulDown (lastSqrtQ0 - FixedPoint.ONE);
160
+
161
+ // Va = Ra_center / (currentSqrtQ0 - 1)
141
162
virtualBalances[0 ] = rACenter.divDown (currentSqrtQ0 - FixedPoint.ONE);
142
- virtualBalances[1 ] = rBCenter.divDown (currentSqrtQ0 - FixedPoint.ONE);
143
163
144
- if (currentTime >= sqrtQ0State.endTime) {
145
- changed = true ;
146
- }
147
- } else {
148
- virtualBalances = lastVirtualBalances;
164
+ uint256 currentInvariant = computeInvariant (balancesScaled18, lastVirtualBalances, Rounding.ROUND_DOWN);
165
+
166
+ // Vb = currentInvariant / (currentQ0 * Va)
167
+ virtualBalances[1 ] = currentInvariant.divDown (
168
+ currentSqrtQ0.mulDown (currentSqrtQ0).mulDown (virtualBalances[0 ])
169
+ );
170
+
171
+ changed = true ;
149
172
}
150
173
}
151
174
@@ -188,12 +211,13 @@ library AclAmmMath {
188
211
return startSqrtQ0;
189
212
} else if (currentTime >= endTime) {
190
213
return endSqrtQ0;
214
+ } else if (startSqrtQ0 == endSqrtQ0) {
215
+ return endSqrtQ0;
191
216
}
192
217
193
- uint256 numerator = ((endTime - currentTime) * startSqrtQ0) + ((currentTime - startTime) * endSqrtQ0);
194
- uint256 denominator = endTime - startTime;
218
+ uint256 exponent = (currentTime - startTime).divDown (endTime - startTime);
195
219
196
- return numerator / denominator ;
220
+ return startSqrtQ0. mulDown (LogExpMath. pow (endSqrtQ0, exponent)). divDown (LogExpMath. pow (startSqrtQ0, exponent)) ;
197
221
}
198
222
199
223
function isAboveCenter (
0 commit comments