Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
15 changes: 12 additions & 3 deletions src/core/process/round.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { RainSolver } from "..";
import { Pair } from "../../order";
import { Token } from "sushi/currency";
import { iterRandom, Result } from "../../common";
import { SpanStatusCode } from "@opentelemetry/api";
import { PreAssembledSpan, SpanWithContext } from "../../logger";
import { OrderbookVersions, Pair, ZERO_BYTES_32 } from "../../order";
import { ErrorSeverity, errorSnapshot, isTimeout, KnownErrors } from "../../error";
import {
ProcessOrderStatus,
Expand Down Expand Up @@ -181,8 +181,17 @@ export async function processOrderInit(
),
)?.balance ?? orderDetails.buyTokenVaultBalance;

// skip if the output vault is empty
if (orderDetails.sellTokenVaultBalance <= 0n) {
// skip if the output vault is empty for
// non v6 orderbook or non vaultless v6 orderbook
if (
(orderDetails.orderbookVersion !== OrderbookVersions.V6 &&
orderDetails.sellTokenVaultBalance <= 0n) ||
(orderDetails.orderbookVersion === OrderbookVersions.V6 &&
orderDetails.takeOrder.struct.order.validOutputs[
orderDetails.takeOrder.struct.outputIOIndex
].vaultId !== ZERO_BYTES_32 &&
orderDetails.sellTokenVaultBalance <= 0n)
) {
const endTime = performance.now();
const settlement: Settlement = {
pair,
Expand Down
91 changes: 81 additions & 10 deletions src/order/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1188,7 +1188,14 @@ describe("Test OrderManager", () => {
const balance = "0x1234";
const spy = vi.spyOn(common, "normalizeFloat");

const result = orderManager.updateVault(orderbook, owner, token, vaultId, balance);
const result = orderManager.updateVault(
orderbook,
owner,
token,
vaultId,
balance,
OrderbookVersions.V5,
);
expect(result).toBeUndefined();
expect(spy).toHaveBeenCalledWith(balance, token.decimals);

Expand All @@ -1206,7 +1213,7 @@ describe("Test OrderManager", () => {
const vaultId = 123n;
const balance = 1000000000000000000n;

orderManager.updateVault(orderbook, owner, token, vaultId, balance);
orderManager.updateVault(orderbook, owner, token, vaultId, balance, OrderbookVersions.V4);

const orderbookMap = orderManager.ownerTokenVaultMap.get(orderbook);
expect(orderbookMap).toBeDefined();
Expand Down Expand Up @@ -1236,7 +1243,7 @@ describe("Test OrderManager", () => {
const balance = "0xffffffee00000000000000000000000000000000000000000000000000000001";
const spy = vi.spyOn(common, "normalizeFloat");

orderManager.updateVault(orderbook, owner, token, vaultId, balance);
orderManager.updateVault(orderbook, owner, token, vaultId, balance, OrderbookVersions.V5);

expect(spy).toHaveBeenCalledWith(balance, token.decimals);

Expand All @@ -1258,6 +1265,40 @@ describe("Test OrderManager", () => {
spy.mockRestore();
});

it("should set 0 vault balance for vaultless orderbook v6", () => {
const orderbook = "0xorderbook1";
const owner = "0xowner1";
const token = {
address: "0xtoken1",
symbol: "TOKEN1",
decimals: 18,
};
const vaultId = 0n;
const balance = "0xffffffee00000000000000000000000000000000000000000000000000000001"; // ignored
const spy = vi.spyOn(common, "normalizeFloat");

orderManager.updateVault(orderbook, owner, token, vaultId, balance, OrderbookVersions.V6);

expect(spy).not.toHaveBeenCalledWith();

const orderbookMap = orderManager.ownerTokenVaultMap.get(orderbook);
expect(orderbookMap).toBeDefined();

const ownerMap = orderbookMap?.get(owner);
expect(ownerMap).toBeDefined();

const tokenMap = ownerMap?.get(token.address);
expect(tokenMap).toBeDefined();

const vault = tokenMap?.get(vaultId);
expect(vault).toBeDefined();
expect(vault?.id).toBe(vaultId);
expect(vault?.balance).toBe(0n); // skip tracking, always 0
expect(vault?.token).toEqual(token);

spy.mockRestore();
});

it("should update vault correctly when balance is decimal string", () => {
const orderbook = "0xorderbook1";
const owner = "0xowner1";
Expand All @@ -1270,7 +1311,7 @@ describe("Test OrderManager", () => {
const balance = "1000000000000000000";
const spy = vi.spyOn(common, "normalizeFloat");

orderManager.updateVault(orderbook, owner, token, vaultId, balance);
orderManager.updateVault(orderbook, owner, token, vaultId, balance, OrderbookVersions.V4);

expect(spy).not.toHaveBeenCalled();

Expand Down Expand Up @@ -1305,7 +1346,14 @@ describe("Test OrderManager", () => {
const newBalance = 2000000000000000000n;

// First update - create vault
orderManager.updateVault(orderbook, owner, token, vaultId, initialBalance);
orderManager.updateVault(
orderbook,
owner,
token,
vaultId,
initialBalance,
OrderbookVersions.V4,
);

// verify initial state
const vault = orderManager.ownerTokenVaultMap
Expand All @@ -1316,7 +1364,14 @@ describe("Test OrderManager", () => {
expect(vault?.balance).toBe(initialBalance);

// second update - update balance
orderManager.updateVault(orderbook, owner, token, vaultId, newBalance);
orderManager.updateVault(
orderbook,
owner,
token,
vaultId,
newBalance,
OrderbookVersions.V4,
);

// verify updated balance
const updatedVault = orderManager.ownerTokenVaultMap
Expand All @@ -1342,8 +1397,8 @@ describe("Test OrderManager", () => {
const balance1 = 1000000000000000000n;
const balance2 = 2000000000000000000n;

orderManager.updateVault(orderbook, owner, token, vaultId1, balance1);
orderManager.updateVault(orderbook, owner, token, vaultId2, balance2);
orderManager.updateVault(orderbook, owner, token, vaultId1, balance1, OrderbookVersions.V4);
orderManager.updateVault(orderbook, owner, token, vaultId2, balance2, OrderbookVersions.V4);

const tokenMap = orderManager.ownerTokenVaultMap
.get(orderbook)
Expand Down Expand Up @@ -1374,10 +1429,24 @@ describe("Test OrderManager", () => {
const balance2 = 500000000n;

// Add first vault
orderManager.updateVault(orderbook, owner, token1, vaultId1, balance1);
orderManager.updateVault(
orderbook,
owner,
token1,
vaultId1,
balance1,
OrderbookVersions.V4,
);

// Add second vault with different token
orderManager.updateVault(orderbook, owner, token2, vaultId2, balance2);
orderManager.updateVault(
orderbook,
owner,
token2,
vaultId2,
balance2,
OrderbookVersions.V4,
);

// verify both vaults exist
const ownerMap = orderManager.ownerTokenVaultMap.get(orderbook)?.get(owner);
Expand Down Expand Up @@ -1442,6 +1511,7 @@ describe("Test OrderManager", () => {
},
20n, // From validOutputs[1].vaultId
2000n, // sellTokenVaultBalance
OrderbookVersions.V5,
);

// should use inputIOIndex: 0 (first input)
Expand All @@ -1456,6 +1526,7 @@ describe("Test OrderManager", () => {
},
30n, // From validInputs[0].vaultId
1000n, // buyTokenVaultBalance
OrderbookVersions.V5,
);

updateVaultSpy.mockRestore();
Expand Down
17 changes: 13 additions & 4 deletions src/order/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
CounterpartySource,
OrderbooksOwnersProfileMap,
OrderbookOwnerTokenVaultsMap,
OrderbookVersions,
} from "./types";

export * from "./types";
Expand Down Expand Up @@ -229,6 +230,7 @@ export class OrderManager {
},
BigInt(outputVault.vaultId),
pair.sellTokenVaultBalance,
pair.orderbookVersion,
);
this.updateVault(
orderbook,
Expand All @@ -240,6 +242,7 @@ export class OrderManager {
},
BigInt(inputVault.vaultId),
pair.buyTokenVaultBalance,
pair.orderbookVersion,
);
}

Expand All @@ -250,21 +253,27 @@ export class OrderManager {
* @param token - The token details
* @param vaultId - The vault id
* @param balance - The new vault balance
* @param orderbookVersion - Specifies the orderbook version
*/
updateVault(
orderbook: string,
owner: string,
token: TokenDetails,
vaultId: bigint,
balance: string | bigint,
orderbookVersion: OrderbookVersions,
) {
// normalize balance based on vault type
let normalizedBalance: bigint;
if (typeof balance === "string") {
if (balance.startsWith("0x")) {
const normalized = normalizeFloat(balance, token.decimals);
if (normalized.isErr()) return;
normalizedBalance = normalized.value;
if (orderbookVersion === OrderbookVersions.V6 && vaultId === 0n) {
normalizedBalance = 0n;
} else {
const normalized = normalizeFloat(balance, token.decimals);
if (normalized.isErr()) return;
normalizedBalance = normalized.value;
}
} else {
normalizedBalance = BigInt(balance);
}
Expand Down Expand Up @@ -413,7 +422,7 @@ export class OrderManager {
new OrderManagerError(
"Failed to create order pair from args",
OrderManagerErrorType.WasmEncodedError,
pairResult.error,
pairResult.error.readableMsg,
),
);
}
Expand Down
6 changes: 6 additions & 0 deletions src/order/sync.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ describe("Test syncOrders", () => {
},
123n,
"1000000000000000000",
"",
);
expect(mockUpdateVault).toHaveBeenCalledTimes(1);
});
Expand Down Expand Up @@ -129,6 +130,7 @@ describe("Test syncOrders", () => {
},
456n,
"500000000",
"",
);
expect(mockUpdateVault).toHaveBeenCalledTimes(1);
});
Expand Down Expand Up @@ -194,6 +196,7 @@ describe("Test syncOrders", () => {
},
100n,
"2000000000000000000",
"",
);
expect(mockUpdateVault).toHaveBeenNthCalledWith(
2,
Expand All @@ -206,6 +209,7 @@ describe("Test syncOrders", () => {
},
200n,
"1000000000",
"",
);
});

Expand Down Expand Up @@ -270,6 +274,7 @@ describe("Test syncOrders", () => {
},
789n,
"50000000",
"",
);
expect(mockUpdateVault).toHaveBeenNthCalledWith(
2,
Expand All @@ -282,6 +287,7 @@ describe("Test syncOrders", () => {
},
101112n,
"3000000000000000000",
"",
);
});

Expand Down
7 changes: 5 additions & 2 deletions src/order/sync.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { OrderManager } from ".";
import { OrderbookVersions, OrderManager } from ".";
import { errorSnapshot } from "../error";
import { PreAssembledSpan } from "../logger";
import { SgTransaction } from "../subgraph/types";
import { SgTransaction, SubgraphVersions } from "../subgraph/types";
import { applyFilters } from "../subgraph/filter";

/** Syncs orders and vaults to upstream changes since the last fetch */
Expand Down Expand Up @@ -35,6 +35,7 @@ export async function syncOrders(this: OrderManager) {
},
BigInt(event.vault.vaultId),
event.vault.balance,
version === SubgraphVersions.V6 ? OrderbookVersions.V6 : ("" as any),
);
}
if (event.__typename === "Clear" || event.__typename === "TakeOrder") {
Expand All @@ -50,6 +51,7 @@ export async function syncOrders(this: OrderManager) {
},
BigInt(trade.inputVaultBalanceChange.vault.vaultId),
trade.inputVaultBalanceChange.vault.balance,
version === SubgraphVersions.V6 ? OrderbookVersions.V6 : ("" as any),
);
this.updateVault(
trade.outputVaultBalanceChange.orderbook.id,
Expand All @@ -61,6 +63,7 @@ export async function syncOrders(this: OrderManager) {
},
BigInt(trade.outputVaultBalanceChange.vault.vaultId),
trade.outputVaultBalanceChange.vault.balance,
version === SubgraphVersions.V6 ? OrderbookVersions.V6 : ("" as any),
);
});
}
Expand Down
8 changes: 5 additions & 3 deletions src/order/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {
TakeOrdersConfigTypeV5,
} from "./v4";

export const ZERO_BYTES_32 = "0x0000000000000000000000000000000000000000000000000000000000000000";

// Re-export types from v3 and v4
export { OrderV3, OrderProfileV3, PairV3, TakeOrderDetailsV3, TakeOrdersConfigTypeV3, TakeOrderV3 };
export {
Expand Down Expand Up @@ -128,9 +130,9 @@ export type BundledOrders = {
};

export enum OrderbookVersions {
V4,
V5,
V6,
V4 = "v4",
V5 = "v5",
V6 = "v6",
}

export type PairBase = {
Expand Down
Loading
Loading