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
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@ const successSchema = {
original: {
title: 'Original',
description: 'Original value before the state change',
type: ['string', 'object', 'null'],
type: ['string', 'number', 'boolean', 'object', 'array', 'null'],
},
dirty: {
title: 'Dirty',
description: 'New value after the state change',
type: ['string', 'object', 'null'],
type: ['string', 'number', 'boolean', 'object', 'array', 'null'],
},
raw: {
title: 'Raw Elements',
Expand Down
118 changes: 116 additions & 2 deletions libs/repositories/src/gen/cow/cow-api-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,27 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/v1/debug/simulation": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* Simulate an arbitrary order.
* @description Simulates an arbitrary order specified in the request body and returns the Tenderly simulation request, along with any simulation error if applicable.
*
*/
post: operations["debugSimulationPost"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/debug/simulation/{uid}": {
parameters: {
query?: never;
Expand Down Expand Up @@ -1472,6 +1493,40 @@ export interface components {
/** @description EIP-2930 access list for the transaction. */
access_list?: components["schemas"]["AccessListItem"][];
};
/** @description Request body for simulating an arbitrary order without it being stored in the orderbook.
* */
SimulationRequest: {
/** @description The token being sold. */
sellToken: components["schemas"]["Address"];
/** @description The token being bought. */
buyToken: components["schemas"]["Address"];
/** @description Amount of sell token (hex- or decimal-encoded uint256). Must be greater than zero.
* */
sellAmount: components["schemas"]["TokenAmount"];
/** @description Amount of buy token (hex- or decimal-encoded uint256). */
buyAmount: components["schemas"]["TokenAmount"];
/** @description Whether this is a sell or buy order. */
kind: components["schemas"]["OrderKind"];
/** @description The address of the order owner. */
owner: components["schemas"]["Address"];
/** @description The address that will receive the buy tokens. Defaults to the owner if omitted.
* */
receiver?: components["schemas"]["Address"] | null;
/**
* @description Where the sell token should be drawn from.
* @default erc20
*/
sellTokenBalance: components["schemas"]["SellTokenSource"];
/**
* @description Where the buy token should be transferred to.
* @default erc20
*/
buyTokenBalance: components["schemas"]["BuyTokenDestination"];
/** @description Full app data JSON string. Defaults to `"{}"` if omitted.
* */
appData?: string | null;
blockNumber?: number;
};
/** @description The Tenderly simulation request for an order, along with any simulation error.
* */
OrderSimulation: {
Expand Down Expand Up @@ -2437,10 +2492,68 @@ export interface operations {
};
};
};
debugSimulation: {
debugSimulationPost: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["SimulationRequest"];
};
};
responses: {
/** @description Simulation request returned. */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["OrderSimulation"];
};
};
/** @description Invalid JSON body, or `appData` is not valid JSON.
* */
400: {
headers: {
[name: string]: unknown;
};
content?: never;
};
/** @description Order simulation endpoint is not enabled. */
405: {
headers: {
[name: string]: unknown;
};
content?: never;
};
/** @description Request body failed schema validation: missing required field, wrong field type, zero `sellAmount`, or unrecognised `kind` value.
* */
422: {
headers: {
[name: string]: unknown;
};
content?: never;
};
/** @description Internal error. */
500: {
headers: {
[name: string]: unknown;
};
content?: never;
};
};
};
debugSimulation: {
parameters: {
query?: {
/** @description Block number to simulate the order at. If not specified, the simulation uses the latest block.
* */
block_number?: number;
};
header?: never;
path: {
uid: components["schemas"]["UID"];
};
Expand All @@ -2457,7 +2570,8 @@ export interface operations {
"application/json": components["schemas"]["OrderSimulation"];
};
};
/** @description Invalid order UID. */
/** @description Malformed path parameter (invalid order UID format) or invalid `block_number` query parameter.
* */
400: {
headers: {
[name: string]: unknown;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -578,8 +578,8 @@ interface LogRaw {
export interface StateDiff {
address: string;
soltype: SoltypeElement | null;
original: string | Record<string, any> | null;
dirty: string | Record<string, any> | null;
original: string | number | boolean | Record<string, any> | unknown[] | null;
dirty: string | number | boolean | Record<string, any> | unknown[] | null;
Comment on lines +581 to +582
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Falsy state values will be dropped after this type widening

Line 581 and Line 582 now allow 0/false, but downstream merge logic still uses truthiness (|| and if (diff?.original && diff?.dirty) in libs/repositories/src/utils/buildStateDiff.ts), which will coerce valid values to null or skip processing.

Proposed fix in libs/repositories/src/utils/buildStateDiff.ts
-        original: diff.original || null,
-        dirty: diff.dirty || null,
+        original: diff.original ?? null,
+        dirty: diff.dirty ?? null,
-  if (diff?.soltype && diff?.original && diff?.dirty) {
+  if (
+    diff?.soltype != null &&
+    diff?.original != null &&
+    diff?.dirty != null
+  ) {
     return processRegularDiff(accumulatedStateDiff, diff);
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@libs/repositories/src/repos/SimulationRepository/tenderlyTypes.ts` around
lines 581 - 582, The widened types in tenderlyTypes (properties diff.original
and diff.dirty now allow 0/false) break downstream logic in buildStateDiff.ts
that uses truthy checks and ||; update the merge/guard logic in
libs/repositories/src/utils/buildStateDiff.ts to use explicit null/undefined
checks (e.g., diff.original !== undefined && diff.original !== null) and replace
usages of the || operator with nullish coalescing or explicit checks so valid
falsy values (0, false, empty string) are preserved when computing/merging
state; ensure any conditional like if (diff?.original && diff?.dirty) is changed
to test for non-null/undefined values instead.

raw?: RawElement[];
}

Expand Down
Loading