@@ -32,6 +32,11 @@ class SpotTradeCircuit : public BaseTransactionCircuit
3232    DynamicBalanceGadget balanceA_O;
3333    DynamicBalanceGadget balanceB_O;
3434
35+     DynamicBalanceGadget vbalanceS_A;
36+     DynamicBalanceGadget vbalanceB_A;
37+     DynamicBalanceGadget vbalanceS_B;
38+     DynamicBalanceGadget vbalanceB_B;
39+ 
3540    //  Order fills
3641    FloatGadget fillS_A;
3742    FloatGadget fillS_B;
@@ -59,6 +64,16 @@ class SpotTradeCircuit : public BaseTransactionCircuit
5964    TransferGadget protocolFeeA_from_balanceAO_to_balanceAP;
6065    TransferGadget protocolFeeB_from_balanceBO_to_balanceBP;
6166
67+     /*  Virtual Token Transfers */ 
68+     TernaryGadget vfills_S_A;
69+     TernaryGadget vfills_B_A;
70+     TernaryGadget vfills_S_B;
71+     TernaryGadget vfills_B_B;
72+     SubGadget update_vbalanceS_A;
73+     AddGadget update_vbalanceB_A;
74+     SubGadget update_vbalanceS_B;
75+     AddGadget update_vbalanceB_B;
76+ 
6277    //  AMM validation
6378    ValidateAMMGadget validateAMM;
6479
@@ -82,6 +97,12 @@ class SpotTradeCircuit : public BaseTransactionCircuit
8297          balanceA_O(pb, state.oper.balanceA, FMT(prefix, " .balanceA_O" 
8398          balanceB_O(pb, state.oper.balanceB, FMT(prefix, " .balanceB_O" 
8499
100+           //  Virtual balances
101+           vbalanceS_A(pb, state.accountA.balanceS.weightAMM, FMT(prefix, " .vbalanceS_A" 
102+           vbalanceB_A(pb, state.accountA.balanceB.weightAMM, FMT(prefix, " .vbalanceB_A" 
103+           vbalanceS_B(pb, state.accountB.balanceS.weightAMM, FMT(prefix, " .vbalanceS_B" 
104+           vbalanceB_B(pb, state.accountB.balanceB.weightAMM, FMT(prefix, " .vbalanceB_B" 
105+ 
85106          //  Order fills
86107          fillS_A(pb, state.constants, Float24Encoding, FMT(prefix, " .fillS_A" 
87108          fillS_B(pb, state.constants, Float24Encoding, FMT(prefix, " .fillS_B" 
@@ -175,28 +196,55 @@ class SpotTradeCircuit : public BaseTransactionCircuit
175196            feeCalculatorB.getProtocolFee(),
176197            FMT(prefix, " .protocolFeeB_from_balanceBO_to_balanceBP" 
177198
199+           /*  Virtual balance updates (for AMMs only) */ 
200+           vfills_S_A(pb, orderA.amm.packed, fillS_A.value(), state.constants._0, FMT(prefix, " .vfills_S_A" 
201+           vfills_B_A(pb, orderA.amm.packed, fillS_B.value(), state.constants._0, FMT(prefix, " .vfills_B_A" 
202+           vfills_S_B(pb, orderB.amm.packed, fillS_B.value(), state.constants._0, FMT(prefix, " .vfills_S_B" 
203+           vfills_B_B(pb, orderB.amm.packed, fillS_A.value(), state.constants._0, FMT(prefix, " .vfills_B_B" 
204+           update_vbalanceS_A(
205+             pb,
206+             state.accountA.balanceS.weightAMM,
207+             vfills_S_A.result(),
208+             NUM_BITS_AMOUNT,
209+             FMT(prefix, " .update_vbalanceS_A" 
210+           update_vbalanceB_A(
211+             pb,
212+             state.accountA.balanceB.weightAMM,
213+             vfills_B_A.result(),
214+             NUM_BITS_AMOUNT,
215+             FMT(prefix, " .update_vbalanceB_A" 
216+           update_vbalanceS_B(
217+             pb,
218+             state.accountB.balanceS.weightAMM,
219+             vfills_S_B.result(),
220+             NUM_BITS_AMOUNT,
221+             FMT(prefix, " .update_vbalanceS_B" 
222+           update_vbalanceB_B(
223+             pb,
224+             state.accountB.balanceB.weightAMM,
225+             vfills_B_B.result(),
226+             NUM_BITS_AMOUNT,
227+             FMT(prefix, " .update_vbalanceB_B" 
228+ 
178229          validateAMM(
179230            pb,
180231            state.constants,
232+             isSpotTradeTx.result(),
181233            {orderA.amm .packed ,
182234             orderA.feeBips .packed ,
183235             fillS_A.value (),
184-              state.accountA .balanceS .balance ,
185-              state.accountA .balanceB .balance ,
186-              balanceS_A.balance (),
187-              balanceB_A.balance (),
188236             state.accountA .balanceS .weightAMM ,
189237             state.accountA .balanceB .weightAMM ,
238+              update_vbalanceS_A.result (),
239+              update_vbalanceB_A.result (),
190240             state.accountA .account .feeBipsAMM },
191241            {orderB.amm .packed ,
192242             orderB.feeBips .packed ,
193243             fillS_B.value (),
194-              state.accountB .balanceS .balance ,
195-              state.accountB .balanceB .balance ,
196-              balanceS_B.balance (),
197-              balanceB_B.balance (),
198244             state.accountB .balanceS .weightAMM ,
199245             state.accountB .balanceB .weightAMM ,
246+              update_vbalanceS_B.result (),
247+              update_vbalanceB_B.result (),
200248             state.accountB .account .feeBipsAMM },
201249            FMT (prefix, " .validateAMM" 
202250    {
@@ -210,6 +258,8 @@ class SpotTradeCircuit : public BaseTransactionCircuit
210258        setOutput (TXV_STORAGE_A_STORAGEID, orderA.storageID .packed );
211259        setOutput (TXV_BALANCE_A_S_BALANCE, balanceS_A.balance ());
212260        setOutput (TXV_BALANCE_A_B_BALANCE, balanceB_A.balance ());
261+         setOutput (TXV_BALANCE_A_S_WEIGHTAMM, update_vbalanceS_A.result ());
262+         setOutput (TXV_BALANCE_A_B_WEIGHTAMM, update_vbalanceB_A.result ());
213263        setArrayOutput (TXV_ACCOUNT_A_ADDRESS, orderA.accountID .bits );
214264
215265        //  Update account B
@@ -218,6 +268,8 @@ class SpotTradeCircuit : public BaseTransactionCircuit
218268        setOutput (TXV_STORAGE_B_STORAGEID, orderB.storageID .packed );
219269        setOutput (TXV_BALANCE_B_S_BALANCE, balanceS_B.balance ());
220270        setOutput (TXV_BALANCE_B_B_BALANCE, balanceB_B.balance ());
271+         setOutput (TXV_BALANCE_B_S_WEIGHTAMM, update_vbalanceS_B.result ());
272+         setOutput (TXV_BALANCE_B_B_WEIGHTAMM, update_vbalanceB_B.result ());
221273        setArrayOutput (TXV_ACCOUNT_B_ADDRESS, orderB.accountID .bits );
222274
223275        //  Update balances of the protocol fee pool
@@ -252,6 +304,12 @@ class SpotTradeCircuit : public BaseTransactionCircuit
252304        balanceA_O.generate_r1cs_witness ();
253305        balanceB_O.generate_r1cs_witness ();
254306
307+         //  Virtual balances
308+         vbalanceS_A.generate_r1cs_witness ();
309+         vbalanceB_A.generate_r1cs_witness ();
310+         vbalanceS_B.generate_r1cs_witness ();
311+         vbalanceB_B.generate_r1cs_witness ();
312+ 
255313        //  Order fills
256314        fillS_A.generate_r1cs_witness (spotTrade.fillS_A );
257315        fillS_B.generate_r1cs_witness (spotTrade.fillS_B );
@@ -279,6 +337,16 @@ class SpotTradeCircuit : public BaseTransactionCircuit
279337        protocolFeeA_from_balanceAO_to_balanceAP.generate_r1cs_witness ();
280338        protocolFeeB_from_balanceBO_to_balanceBP.generate_r1cs_witness ();
281339
340+         /*  Virtual Token Transfers */ 
341+         vfills_S_A.generate_r1cs_witness ();
342+         vfills_B_A.generate_r1cs_witness ();
343+         vfills_S_B.generate_r1cs_witness ();
344+         vfills_B_B.generate_r1cs_witness ();
345+         update_vbalanceS_A.generate_r1cs_witness ();
346+         update_vbalanceB_A.generate_r1cs_witness ();
347+         update_vbalanceS_B.generate_r1cs_witness ();
348+         update_vbalanceB_B.generate_r1cs_witness ();
349+ 
282350        //  AMM validation
283351        validateAMM.generate_r1cs_witness ();
284352    }
@@ -299,6 +367,12 @@ class SpotTradeCircuit : public BaseTransactionCircuit
299367        balanceA_O.generate_r1cs_constraints ();
300368        balanceB_O.generate_r1cs_constraints ();
301369
370+         //  Virtual balances
371+         vbalanceS_A.generate_r1cs_constraints ();
372+         vbalanceB_A.generate_r1cs_constraints ();
373+         vbalanceS_B.generate_r1cs_constraints ();
374+         vbalanceB_B.generate_r1cs_constraints ();
375+ 
302376        //  Order fills
303377        fillS_A.generate_r1cs_constraints ();
304378        fillS_B.generate_r1cs_constraints ();
@@ -326,6 +400,16 @@ class SpotTradeCircuit : public BaseTransactionCircuit
326400        protocolFeeA_from_balanceAO_to_balanceAP.generate_r1cs_constraints ();
327401        protocolFeeB_from_balanceBO_to_balanceBP.generate_r1cs_constraints ();
328402
403+         /*  Virtual Token Transfers */ 
404+         vfills_S_A.generate_r1cs_constraints ();
405+         vfills_B_A.generate_r1cs_constraints ();
406+         vfills_S_B.generate_r1cs_constraints ();
407+         vfills_B_B.generate_r1cs_constraints ();
408+         update_vbalanceS_A.generate_r1cs_constraints ();
409+         update_vbalanceB_A.generate_r1cs_constraints ();
410+         update_vbalanceS_B.generate_r1cs_constraints ();
411+         update_vbalanceB_B.generate_r1cs_constraints ();
412+ 
329413        //  AMM validation
330414        validateAMM.generate_r1cs_constraints ();
331415    }
0 commit comments