Summary
parseFillLogs in packages/sdk/src/actions/waitForFillTx.ts reads logs[0] unconditionally at the top of the function body to build blockData. When the caller passes an empty logs array (a valid scenario — no fill logs found yet), the function throws a TypeError (Cannot read properties of undefined) instead of returning undefined. The function's implicit contract — it returns undefined when no matching log is found — is already honored for the non-empty-but-no-match path, but the empty-array path is never reached.
What I observed
packages/sdk/src/actions/waitForFillTx.ts, lines 164–166:
const blockData = {
depositTxHash: logs[0]!.blockHash!, // throws if logs is []
depositTxBlock: logs[0]!.blockNumber!,
};
The blockData object is only used inside the two if (v3_5Log) / if (v3Log) branches that follow. If neither branch is taken (no match), the function falls through and returns undefined implicitly — but only after blockData has already been constructed. An empty array causes a crash before any filtering logic runs.
Impact
Any caller that passes an empty or pre-filtered logs: [] (e.g., a batch receipt with no fill events for the given deposit, or a defensive call site guarding against race conditions) receives an unhandled TypeError rather than the expected undefined. Since the function is exported and used as a utility, callers not wrapped in try/catch will surface this as an unhandled exception. The waitForFillTx path itself propagates the error to the rejection handler at line 142–144, which may silently stall the wait loop.
Suggested fix
Move the blockData construction inside the match branches (or guard with an early return):
export function parseFillLogs(logs: Log[], filter?: ...) {
+ if (logs.length === 0) return undefined;
+
const blockData = {
depositTxHash: logs[0]!.blockHash!,
depositTxBlock: logs[0]!.blockNumber!,
};
// ...rest unchanged
}
Alternatively, defer blockData construction to just before each return block so it only runs when a match exists, avoiding the non-empty-but-wrong-logs edge case as well.
Notes
Related to toolkit Tier-A audit finding #8. The non-null assertions (!) signal the author assumed a non-empty array, but the call-site contract does not enforce that precondition.
Summary
parseFillLogsinpackages/sdk/src/actions/waitForFillTx.tsreadslogs[0]unconditionally at the top of the function body to buildblockData. When the caller passes an emptylogsarray (a valid scenario — no fill logs found yet), the function throws aTypeError(Cannot read properties of undefined) instead of returningundefined. The function's implicit contract — it returnsundefinedwhen no matching log is found — is already honored for the non-empty-but-no-match path, but the empty-array path is never reached.What I observed
packages/sdk/src/actions/waitForFillTx.ts, lines 164–166:The
blockDataobject is only used inside the twoif (v3_5Log)/if (v3Log)branches that follow. If neither branch is taken (no match), the function falls through and returnsundefinedimplicitly — but only afterblockDatahas already been constructed. An empty array causes a crash before any filtering logic runs.Impact
Any caller that passes an empty or pre-filtered
logs: [](e.g., a batch receipt with no fill events for the given deposit, or a defensive call site guarding against race conditions) receives an unhandledTypeErrorrather than the expectedundefined. Since the function is exported and used as a utility, callers not wrapped intry/catchwill surface this as an unhandled exception. ThewaitForFillTxpath itself propagates the error to the rejection handler at line 142–144, which may silently stall the wait loop.Suggested fix
Move the
blockDataconstruction inside the match branches (or guard with an early return):Alternatively, defer
blockDataconstruction to just before eachreturnblock so it only runs when a match exists, avoiding the non-empty-but-wrong-logs edge case as well.Notes
Related to toolkit Tier-A audit finding #8. The non-null assertions (
!) signal the author assumed a non-empty array, but the call-site contract does not enforce that precondition.