Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ export class SpotTradeProcessor {
.balance.iadd(s.fillBA)
.isub(s.feeA);

// virtual balances
if (
accountA.getBalance(tokenA).weightAMM.gt(new BN(0)) &&
accountA.getBalance(tokenB).weightAMM.gt(new BN(0))
) {
accountA.getBalance(tokenA).weightAMM.isub(s.fillSA);
accountA.getBalance(tokenB).weightAMM.iadd(s.fillBA);
}

const tradeHistoryA = accountA.getBalance(tokenA).getStorage(storageIdA);
if (tradeHistoryA.storageID !== storageIdA) {
tradeHistoryA.data = new BN(0);
Expand All @@ -116,6 +125,15 @@ export class SpotTradeProcessor {
.balance.iadd(s.fillBB)
.isub(s.feeB);

// virtual balances
if (
accountB.getBalance(tokenA).weightAMM.gt(new BN(0)) &&
accountB.getBalance(tokenB).weightAMM.gt(new BN(0))
) {
accountB.getBalance(tokenB).weightAMM.isub(s.fillBA);
accountB.getBalance(tokenA).weightAMM.iadd(s.fillSA);
}

const tradeHistoryB = accountB.getBalance(tokenB).getStorage(storageIdB);
if (tradeHistoryB.storageID !== storageIdB) {
tradeHistoryB.data = new BN(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ enum TxVariable
TXV_BALANCE_A_S_WEIGHTAMM,

TXV_BALANCE_A_B_BALANCE,
TXV_BALANCE_A_B_WEIGHTAMM,

TXV_ACCOUNT_A_ADDRESS,
TXV_ACCOUNT_A_OWNER,
Expand All @@ -194,8 +195,10 @@ enum TxVariable

TXV_BALANCE_B_S_ADDRESS,
TXV_BALANCE_B_S_BALANCE,
TXV_BALANCE_B_S_WEIGHTAMM,

TXV_BALANCE_B_B_BALANCE,
TXV_BALANCE_B_B_WEIGHTAMM,

TXV_ACCOUNT_B_ADDRESS,
TXV_ACCOUNT_B_OWNER,
Expand Down Expand Up @@ -245,6 +248,7 @@ class BaseTransactionCircuit : public GadgetT
uOutputs[TXV_BALANCE_A_S_WEIGHTAMM] = state.accountA.balanceS.weightAMM;

uOutputs[TXV_BALANCE_A_B_BALANCE] = state.accountA.balanceB.balance;
uOutputs[TXV_BALANCE_A_B_WEIGHTAMM] = state.accountA.balanceB.weightAMM;

aOutputs[TXV_ACCOUNT_A_ADDRESS] =
flatten({VariableArrayT(1, state.constants._1), VariableArrayT(NUM_BITS_ACCOUNT - 1, state.constants._0)});
Expand All @@ -260,8 +264,10 @@ class BaseTransactionCircuit : public GadgetT

aOutputs[TXV_BALANCE_B_S_ADDRESS] = VariableArrayT(NUM_BITS_TOKEN, state.constants._0);
uOutputs[TXV_BALANCE_B_S_BALANCE] = state.accountB.balanceS.balance;
uOutputs[TXV_BALANCE_B_S_WEIGHTAMM] = state.accountB.balanceS.weightAMM;

uOutputs[TXV_BALANCE_B_B_BALANCE] = state.accountB.balanceB.balance;
uOutputs[TXV_BALANCE_B_B_WEIGHTAMM] = state.accountB.balanceB.weightAMM;

aOutputs[TXV_ACCOUNT_B_ADDRESS] =
flatten({VariableArrayT(1, state.constants._1), VariableArrayT(NUM_BITS_ACCOUNT - 1, state.constants._0)});
Expand Down
80 changes: 72 additions & 8 deletions packages/loopring_v3/circuit/Circuits/SpotTradeCircuit.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ class SpotTradeCircuit : public BaseTransactionCircuit
DynamicBalanceGadget balanceA_O;
DynamicBalanceGadget balanceB_O;

DynamicBalanceGadget vbalanceS_A;
DynamicBalanceGadget vbalanceB_A;
DynamicBalanceGadget vbalanceS_B;
DynamicBalanceGadget vbalanceB_B;

// Order fills
FloatGadget fillS_A;
FloatGadget fillS_B;
Expand Down Expand Up @@ -59,6 +64,16 @@ class SpotTradeCircuit : public BaseTransactionCircuit
TransferGadget protocolFeeA_from_balanceAO_to_balanceAP;
TransferGadget protocolFeeB_from_balanceBO_to_balanceBP;

/* Virtual Token Transfers */
TernaryGadget vfills_S_A;
TernaryGadget vfills_B_A;
TernaryGadget vfills_S_B;
TernaryGadget vfills_B_B;
SubGadget update_vbalanceS_A;
AddGadget update_vbalanceB_A;
SubGadget update_vbalanceS_B;
AddGadget update_vbalanceB_B;

// AMM validation
ValidateAMMGadget validateAMM;

Expand All @@ -82,6 +97,12 @@ class SpotTradeCircuit : public BaseTransactionCircuit
balanceA_O(pb, state.oper.balanceA, FMT(prefix, ".balanceA_O")),
balanceB_O(pb, state.oper.balanceB, FMT(prefix, ".balanceB_O")),

// Virtual balances
vbalanceS_A(pb, state.accountA.balanceS.weightAMM, FMT(prefix, ".vbalanceS_A")),
vbalanceB_A(pb, state.accountA.balanceB.weightAMM, FMT(prefix, ".vbalanceB_A")),
vbalanceS_B(pb, state.accountB.balanceS.weightAMM, FMT(prefix, ".vbalanceS_B")),
vbalanceB_B(pb, state.accountB.balanceB.weightAMM, FMT(prefix, ".vbalanceB_B")),

// Order fills
fillS_A(pb, state.constants, Float24Encoding, FMT(prefix, ".fillS_A")),
fillS_B(pb, state.constants, Float24Encoding, FMT(prefix, ".fillS_B")),
Expand Down Expand Up @@ -175,28 +196,35 @@ class SpotTradeCircuit : public BaseTransactionCircuit
feeCalculatorB.getProtocolFee(),
FMT(prefix, ".protocolFeeB_from_balanceBO_to_balanceBP")),

/* Virtual balance updates (for AMMs only) */
vfills_S_A(pb, orderA.amm.packed, fillS_A.value(), state.constants._0, FMT(prefix, ".vfills_S_A")),
vfills_B_A(pb, orderA.amm.packed, fillS_B.value(), state.constants._0, FMT(prefix, ".vfills_B_A")),
vfills_S_B(pb, orderB.amm.packed, fillS_B.value(), state.constants._0, FMT(prefix, ".vfills_S_B")),
vfills_B_B(pb, orderB.amm.packed, fillS_A.value(), state.constants._0, FMT(prefix, ".vfills_B_B")),
update_vbalanceS_A(pb, state.accountA.balanceS.weightAMM, vfills_S_A.result(), NUM_BITS_AMOUNT, FMT(prefix, ".update_vbalanceS_A")),
update_vbalanceB_A(pb, state.accountA.balanceB.weightAMM, vfills_B_A.result(), NUM_BITS_AMOUNT, FMT(prefix, ".update_vbalanceB_A")),
update_vbalanceS_B(pb, state.accountB.balanceS.weightAMM, vfills_S_B.result(), NUM_BITS_AMOUNT, FMT(prefix, ".update_vbalanceS_B")),
update_vbalanceB_B(pb, state.accountB.balanceB.weightAMM, vfills_B_B.result(), NUM_BITS_AMOUNT, FMT(prefix, ".update_vbalanceB_B")),

validateAMM(
pb,
state.constants,
isSpotTradeTx.result(),
{orderA.amm.packed,
orderA.feeBips.packed,
fillS_A.value(),
state.accountA.balanceS.balance,
state.accountA.balanceB.balance,
balanceS_A.balance(),
balanceB_A.balance(),
state.accountA.balanceS.weightAMM,
state.accountA.balanceB.weightAMM,
update_vbalanceS_A.result(),
update_vbalanceB_A.result(),
state.accountA.account.feeBipsAMM},
{orderB.amm.packed,
orderB.feeBips.packed,
fillS_B.value(),
state.accountB.balanceS.balance,
state.accountB.balanceB.balance,
balanceS_B.balance(),
balanceB_B.balance(),
state.accountB.balanceS.weightAMM,
state.accountB.balanceB.weightAMM,
update_vbalanceS_B.result(),
update_vbalanceB_B.result(),
state.accountB.account.feeBipsAMM},
FMT(prefix, ".validateAMM"))
{
Expand All @@ -210,6 +238,8 @@ class SpotTradeCircuit : public BaseTransactionCircuit
setOutput(TXV_STORAGE_A_STORAGEID, orderA.storageID.packed);
setOutput(TXV_BALANCE_A_S_BALANCE, balanceS_A.balance());
setOutput(TXV_BALANCE_A_B_BALANCE, balanceB_A.balance());
setOutput(TXV_BALANCE_A_S_WEIGHTAMM, update_vbalanceS_A.result());
setOutput(TXV_BALANCE_A_B_WEIGHTAMM, update_vbalanceB_A.result());
setArrayOutput(TXV_ACCOUNT_A_ADDRESS, orderA.accountID.bits);

// Update account B
Expand All @@ -218,6 +248,8 @@ class SpotTradeCircuit : public BaseTransactionCircuit
setOutput(TXV_STORAGE_B_STORAGEID, orderB.storageID.packed);
setOutput(TXV_BALANCE_B_S_BALANCE, balanceS_B.balance());
setOutput(TXV_BALANCE_B_B_BALANCE, balanceB_B.balance());
setOutput(TXV_BALANCE_B_S_WEIGHTAMM, update_vbalanceS_B.result());
setOutput(TXV_BALANCE_B_B_WEIGHTAMM, update_vbalanceB_B.result());
setArrayOutput(TXV_ACCOUNT_B_ADDRESS, orderB.accountID.bits);

// Update balances of the protocol fee pool
Expand Down Expand Up @@ -252,6 +284,12 @@ class SpotTradeCircuit : public BaseTransactionCircuit
balanceA_O.generate_r1cs_witness();
balanceB_O.generate_r1cs_witness();

// Virtual balances
vbalanceS_A.generate_r1cs_witness();
vbalanceB_A.generate_r1cs_witness();
vbalanceS_B.generate_r1cs_witness();
vbalanceB_B.generate_r1cs_witness();

// Order fills
fillS_A.generate_r1cs_witness(spotTrade.fillS_A);
fillS_B.generate_r1cs_witness(spotTrade.fillS_B);
Expand Down Expand Up @@ -279,6 +317,16 @@ class SpotTradeCircuit : public BaseTransactionCircuit
protocolFeeA_from_balanceAO_to_balanceAP.generate_r1cs_witness();
protocolFeeB_from_balanceBO_to_balanceBP.generate_r1cs_witness();

/* Virtual Token Transfers */
vfills_S_A.generate_r1cs_witness();
vfills_B_A.generate_r1cs_witness();
vfills_S_B.generate_r1cs_witness();
vfills_B_B.generate_r1cs_witness();
update_vbalanceS_A.generate_r1cs_witness();
update_vbalanceB_A.generate_r1cs_witness();
update_vbalanceS_B.generate_r1cs_witness();
update_vbalanceB_B.generate_r1cs_witness();

// AMM validation
validateAMM.generate_r1cs_witness();
}
Expand All @@ -299,6 +347,12 @@ class SpotTradeCircuit : public BaseTransactionCircuit
balanceA_O.generate_r1cs_constraints();
balanceB_O.generate_r1cs_constraints();

// Virtual balances
vbalanceS_A.generate_r1cs_constraints();
vbalanceB_A.generate_r1cs_constraints();
vbalanceS_B.generate_r1cs_constraints();
vbalanceB_B.generate_r1cs_constraints();

// Order fills
fillS_A.generate_r1cs_constraints();
fillS_B.generate_r1cs_constraints();
Expand Down Expand Up @@ -326,6 +380,16 @@ class SpotTradeCircuit : public BaseTransactionCircuit
protocolFeeA_from_balanceAO_to_balanceAP.generate_r1cs_constraints();
protocolFeeB_from_balanceBO_to_balanceBP.generate_r1cs_constraints();

/* Virtual Token Transfers */
vfills_S_A.generate_r1cs_constraints();
vfills_B_A.generate_r1cs_constraints();
vfills_S_B.generate_r1cs_constraints();
vfills_B_B.generate_r1cs_constraints();
update_vbalanceS_A.generate_r1cs_constraints();
update_vbalanceB_A.generate_r1cs_constraints();
update_vbalanceS_B.generate_r1cs_constraints();
update_vbalanceB_B.generate_r1cs_constraints();

// AMM validation
validateAMM.generate_r1cs_constraints();
}
Expand Down
6 changes: 3 additions & 3 deletions packages/loopring_v3/circuit/Circuits/UniversalCircuit.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ class TransactionGadget : public GadgetT
tx.getArrayOutput(TXV_BALANCE_B_S_ADDRESS),
{state.accountA.balanceB.balance, state.accountA.balanceB.weightAMM, state.accountA.balanceB.storageRoot},
{tx.getOutput(TXV_BALANCE_A_B_BALANCE),
state.accountA.balanceB.weightAMM,
tx.getOutput(TXV_BALANCE_A_B_WEIGHTAMM),
state.accountA.balanceB.storageRoot},
FMT(prefix, ".updateBalanceB_A")),
updateAccount_A(
Expand Down Expand Up @@ -321,15 +321,15 @@ class TransactionGadget : public GadgetT
state.accountB.account.balancesRoot,
tx.getArrayOutput(TXV_BALANCE_B_S_ADDRESS),
{state.accountB.balanceS.balance, state.accountB.balanceS.weightAMM, state.accountB.balanceS.storageRoot},
{tx.getOutput(TXV_BALANCE_B_S_BALANCE), state.accountB.balanceS.weightAMM, updateStorage_B.result()},
{tx.getOutput(TXV_BALANCE_B_S_BALANCE), tx.getOutput(TXV_BALANCE_B_S_WEIGHTAMM), updateStorage_B.result()},
FMT(prefix, ".updateBalanceS_B")),
updateBalanceB_B(
pb,
updateBalanceS_B.result(),
tx.getArrayOutput(TXV_BALANCE_A_S_ADDRESS),
{state.accountB.balanceB.balance, state.accountB.balanceB.weightAMM, state.accountB.balanceB.storageRoot},
{tx.getOutput(TXV_BALANCE_B_B_BALANCE),
state.accountB.balanceB.weightAMM,
tx.getOutput(TXV_BALANCE_B_B_WEIGHTAMM),
state.accountB.balanceB.storageRoot},
FMT(prefix, ".updateBalanceB_B")),
updateAccount_B(
Expand Down
3 changes: 2 additions & 1 deletion packages/loopring_v3/circuit/Gadgets/AccountGadgets.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ class UpdateBalanceGadget : public GadgetT
}
};

// Calculcates the state of a user's open position
// Calculcates the state of a user's balance
class DynamicBalanceGadget : public DynamicVariableGadget
{
public:
Expand Down Expand Up @@ -335,6 +335,7 @@ class DynamicBalanceGadget : public DynamicVariableGadget
}
};


} // namespace Loopring

#endif
Loading