Skip to content

Commit 3ec0f72

Browse files
authored
Fix ReClamm simulator to match the contract (#3)
* Fix current margins * Fix current swap * Fix compute price ratio * Remove unused parameter when recomputing virtual balances * Fix price ratio update * Fix math to compute virtual balances * Fix simulation after price range update
1 parent 7d8a556 commit 3ec0f72

File tree

2 files changed

+277
-117
lines changed

2 files changed

+277
-117
lines changed

client/src/pool-types/reclamm/ReClamm.tsx

Lines changed: 99 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
calculateBalancesAfterSwapIn,
2424
recalculateVirtualBalances,
2525
calculateInvariant,
26+
computePriceRatioFromBalances,
2627
} from './ReClammMath';
2728
import { MIN_SWAP, NETWORKS } from './constants';
2829

@@ -170,7 +171,7 @@ export default function ReClamm() {
170171
});
171172
}, [realTimeBalanceA, realTimeBalanceB, realTimeVirtualBalances]);
172173

173-
const lowerMargin = useMemo(() => {
174+
const realTimeLowerMargin = useMemo(() => {
174175
return calculateLowerMargin({
175176
margin: margin,
176177
invariant: realTimeInvariant,
@@ -179,7 +180,7 @@ export default function ReClamm() {
179180
});
180181
}, [margin, realTimeVirtualBalances, realTimeInvariant]);
181182

182-
const higherMargin = useMemo(() => {
183+
const realTimeUpperMargin = useMemo(() => {
183184
return calculateUpperMargin({
184185
margin: margin,
185186
invariant: realTimeInvariant,
@@ -188,6 +189,24 @@ export default function ReClamm() {
188189
});
189190
}, [margin, realTimeVirtualBalances, realTimeInvariant]);
190191

192+
const currentLowerMargin = useMemo(() => {
193+
return calculateLowerMargin({
194+
margin: margin,
195+
invariant: currentInvariant,
196+
virtualBalanceA: currentVirtualBalances.virtualBalanceA,
197+
virtualBalanceB: currentVirtualBalances.virtualBalanceB,
198+
});
199+
}, [margin, currentVirtualBalances, currentInvariant]);
200+
201+
const currentUpperMargin = useMemo(() => {
202+
return calculateUpperMargin({
203+
margin: margin,
204+
invariant: currentInvariant,
205+
virtualBalanceA: currentVirtualBalances.virtualBalanceA,
206+
virtualBalanceB: currentVirtualBalances.virtualBalanceB,
207+
});
208+
}, [margin, currentVirtualBalances, currentInvariant]);
209+
191210
const calculatedSwapAmountOut = useMemo(() => {
192211
const amountOut = calculateOutGivenIn({
193212
balanceA: realTimeBalanceA,
@@ -324,7 +343,6 @@ export default function ReClamm() {
324343
balanceB: realTimeBalanceB,
325344
oldVirtualBalanceA: realTimeVirtualBalances.virtualBalanceA,
326345
oldVirtualBalanceB: realTimeVirtualBalances.virtualBalanceB,
327-
currentPriceRatio: priceRatio,
328346
poolParams: {
329347
margin: margin,
330348
priceShiftDailyRate: priceShiftDailyRate,
@@ -421,9 +439,23 @@ export default function ReClamm() {
421439
return;
422440
}
423441

442+
updateRealTimeVirtualBalances(realTimeBalanceA, realTimeBalanceB);
443+
updateCurrentVirtualBalances(
444+
currentBalanceA,
445+
currentBalanceB,
446+
currentVirtualBalances.virtualBalanceA,
447+
currentVirtualBalances.virtualBalanceB
448+
);
449+
424450
setEndTimeError('');
425451
setTargetPriceRatioError('');
426-
setStartPriceRatio(priceRatio);
452+
const currentPriceRatio = computePriceRatioFromBalances({
453+
balanceA: currentBalanceA,
454+
balanceB: currentBalanceB,
455+
virtualBalanceA: currentVirtualBalances.virtualBalanceA,
456+
virtualBalanceB: currentVirtualBalances.virtualBalanceB,
457+
});
458+
setStartPriceRatio(currentPriceRatio);
427459
setTargetPriceRatio(inputTargetPriceRatio);
428460
setStartTime(simulationSeconds);
429461
setEndTime(inputEndTime);
@@ -434,6 +466,36 @@ export default function ReClamm() {
434466
handleCurrentSwap();
435467
};
436468

469+
const updateRealTimeVirtualBalances = (
470+
balanceA: number,
471+
balanceB: number
472+
) => {
473+
const { newVirtualBalances: virtualBalancesAfterSwap } =
474+
recalculateVirtualBalances({
475+
balanceA,
476+
balanceB,
477+
oldVirtualBalanceA: realTimeVirtualBalances.virtualBalanceA,
478+
oldVirtualBalanceB: realTimeVirtualBalances.virtualBalanceB,
479+
poolParams: {
480+
margin: margin,
481+
priceShiftDailyRate: priceShiftDailyRate,
482+
},
483+
updateQ0Params: {
484+
startTime: startTime,
485+
endTime: endTime,
486+
startPriceRatio: startPriceRatio,
487+
targetPriceRatio: targetPriceRatio,
488+
},
489+
simulationParams: {
490+
simulationSeconds: simulationSeconds,
491+
simulationSecondsPerBlock: simulationSecondsPerBlock,
492+
secondsSinceLastInteraction: simulationSeconds - lastSwapTime,
493+
},
494+
});
495+
496+
setRealTimeVirtualBalances(virtualBalancesAfterSwap);
497+
};
498+
437499
const handleRealTimeSwap = () => {
438500
const feeAmount = swapAmountIn * (lpFeePercent / 100);
439501
let newBalanceA = realTimeBalanceA;
@@ -457,13 +519,21 @@ export default function ReClamm() {
457519
setRealTimeBalanceA(result.newBalanceA);
458520
setRealTimeBalanceB(result.newBalanceB);
459521

522+
updateRealTimeVirtualBalances(result.newBalanceA, result.newBalanceB);
523+
};
524+
525+
const updateCurrentVirtualBalances = (
526+
balanceA: number,
527+
balanceB: number,
528+
virtualBalanceA: number,
529+
virtualBalanceB: number
530+
) => {
460531
const { newVirtualBalances: virtualBalancesAfterSwap } =
461532
recalculateVirtualBalances({
462-
balanceA: result.newBalanceA,
463-
balanceB: result.newBalanceB,
464-
oldVirtualBalanceA: realTimeVirtualBalances.virtualBalanceA,
465-
oldVirtualBalanceB: realTimeVirtualBalances.virtualBalanceB,
466-
currentPriceRatio: priceRatio,
533+
balanceA,
534+
balanceB,
535+
oldVirtualBalanceA: virtualBalanceA,
536+
oldVirtualBalanceB: virtualBalanceB,
467537
poolParams: {
468538
margin: margin,
469539
priceShiftDailyRate: priceShiftDailyRate,
@@ -481,7 +551,16 @@ export default function ReClamm() {
481551
},
482552
});
483553

484-
setRealTimeVirtualBalances(virtualBalancesAfterSwap);
554+
setCurrentVirtualBalances(virtualBalancesAfterSwap);
555+
556+
setCurrentInvariant(
557+
calculateInvariant({
558+
balanceA,
559+
balanceB,
560+
virtualBalanceA: virtualBalancesAfterSwap.virtualBalanceA,
561+
virtualBalanceB: virtualBalancesAfterSwap.virtualBalanceB,
562+
})
563+
);
485564
};
486565

487566
const handleCurrentSwap = () => {
@@ -490,7 +569,6 @@ export default function ReClamm() {
490569
balanceB: currentBalanceB,
491570
oldVirtualBalanceA: currentVirtualBalances.virtualBalanceA,
492571
oldVirtualBalanceB: currentVirtualBalances.virtualBalanceB,
493-
currentPriceRatio: priceRatio,
494572
poolParams: {
495573
margin: margin,
496574
priceShiftDailyRate: priceShiftDailyRate,
@@ -507,6 +585,7 @@ export default function ReClamm() {
507585
secondsSinceLastInteraction: simulationSeconds - lastSwapTime,
508586
},
509587
});
588+
510589
setLastSwapTime(simulationSeconds);
511590
setCurrentVirtualBalances(newVirtualBalances);
512591

@@ -532,39 +611,11 @@ export default function ReClamm() {
532611
setCurrentBalanceA(result.newBalanceA);
533612
setCurrentBalanceB(result.newBalanceB);
534613

535-
const { newVirtualBalances: virtualBalancesAfterSwap } =
536-
recalculateVirtualBalances({
537-
balanceA: result.newBalanceA,
538-
balanceB: result.newBalanceB,
539-
oldVirtualBalanceA: currentVirtualBalances.virtualBalanceA,
540-
oldVirtualBalanceB: currentVirtualBalances.virtualBalanceB,
541-
currentPriceRatio: priceRatio,
542-
poolParams: {
543-
margin: margin,
544-
priceShiftDailyRate: priceShiftDailyRate,
545-
},
546-
updateQ0Params: {
547-
startTime: startTime,
548-
endTime: endTime,
549-
startPriceRatio: startPriceRatio,
550-
targetPriceRatio: targetPriceRatio,
551-
},
552-
simulationParams: {
553-
simulationSeconds: simulationSeconds,
554-
simulationSecondsPerBlock: simulationSecondsPerBlock,
555-
secondsSinceLastInteraction: simulationSeconds - lastSwapTime,
556-
},
557-
});
558-
559-
setCurrentVirtualBalances(virtualBalancesAfterSwap);
560-
561-
setCurrentInvariant(
562-
calculateInvariant({
563-
balanceA: result.newBalanceA,
564-
balanceB: result.newBalanceB,
565-
virtualBalanceA: virtualBalancesAfterSwap.virtualBalanceA,
566-
virtualBalanceB: virtualBalancesAfterSwap.virtualBalanceB,
567-
})
614+
updateCurrentVirtualBalances(
615+
result.newBalanceA,
616+
result.newBalanceB,
617+
newVirtualBalances.virtualBalanceA,
618+
newVirtualBalances.virtualBalanceB
568619
);
569620
};
570621

@@ -1050,7 +1101,7 @@ export default function ReClamm() {
10501101
</Typography>
10511102
<Typography style={{ color: 'blue' }}>
10521103
{toFixedDecimals(
1053-
currentInvariant / Math.pow(higherMargin, 2)
1104+
currentInvariant / Math.pow(currentUpperMargin, 2)
10541105
)}
10551106
</Typography>
10561107
</div>
@@ -1077,7 +1128,7 @@ export default function ReClamm() {
10771128
</Typography>
10781129
<Typography style={{ color: 'blue' }}>
10791130
{toFixedDecimals(
1080-
currentInvariant / Math.pow(lowerMargin, 2)
1131+
currentInvariant / Math.pow(currentLowerMargin, 2)
10811132
)}
10821133
</Typography>
10831134
</div>
@@ -1177,7 +1228,7 @@ export default function ReClamm() {
11771228
</Typography>
11781229
<Typography style={{ color: 'blue' }}>
11791230
{toFixedDecimals(
1180-
realTimeInvariant / Math.pow(higherMargin, 2)
1231+
realTimeInvariant / Math.pow(realTimeUpperMargin, 2)
11811232
)}
11821233
</Typography>
11831234
</div>
@@ -1204,7 +1255,7 @@ export default function ReClamm() {
12041255
</Typography>
12051256
<Typography style={{ color: 'blue' }}>
12061257
{toFixedDecimals(
1207-
realTimeInvariant / Math.pow(lowerMargin, 2)
1258+
realTimeInvariant / Math.pow(realTimeLowerMargin, 2)
12081259
)}
12091260
</Typography>
12101261
</div>

0 commit comments

Comments
 (0)