Skip to content

fix: patch 5 medium-severity findings from deep security audit ,Support fractional quantities for crypto spot trading on Delta Exchange ,Fix position book for crypto spot, rmoney FD audit fix and Groww: Optimize master contract and normalize streaming logs#1087

Merged
marketcalls merged 9 commits intomarketcalls:mainfrom
Kalaiviswa:main
Mar 9, 2026

Conversation

@Kalaiviswa
Copy link
Collaborator

@Kalaiviswa Kalaiviswa commented Mar 9, 2026

fix: patch 5 medium-severity findings from deep security audit


Summary by cubic

Fixes five medium-severity security issues. Adds fractional spot trading and spot positions for Delta Exchange, improves Groww master contract import and logs, and resolves RMoney WebSocket file‑descriptor leaks.

  • Bug Fixes

    • Escape % and _ in symbol search (with escape="\\") to prevent broad matches.
    • Hide tracebacks in API errors; keep detailed logs only.
    • Telegram bot guards: rate_limit_per_minute 1–120 (int), broadcast ≤ 4096 chars, priority 1–10 (int), stats days 1–365 (int).
    • Cap apikey to 1–256 chars across schemas; fix MarginCalculatorSchema message.
    • Chart prefs: ≤ 50 keys, key ≤ 50 chars, each value serialized ≤ 1 MB.
    • Delta Exchange spot: allow fractional quantities, include spot holdings from wallet, preserve fractional sizes, set lotsize from product_specs.min_order_size, map spot/move_options, prefer strike_price; reject fractional qty for derivatives; fix margin calc truncation via _order_size().
    • RMoney XTS streaming: fix FD leaks and reconnection using requests.Session, explicit response closes, full client teardown, interruptible reconnect, and closing prior client on re-init.
  • Performance

    • Groww master contract import: vectorized transforms and 10K-batch bulk_insert_mappings with per-batch flush() and single commit() for atomic rollback; cut import from 5+ minutes to ~22 seconds.
    • Streaming logs: move per-tick logs to DEBUG, add INFO summary every 500 ticks, remove emojis and dead code.

Written for commit 75cf1c1. Summary will update on new commits.

Kalaiviswa and others added 2 commits March 5, 2026 14:38
M1: Escape LIKE wildcards in symbol search to prevent broad matching
  - Add _escape_like() helper for % and _ characters in database/symbol.py

M2: Remove traceback disclosure from API error responses
  - Replace traceback.format_exc() with generic messages in log.py, analyzer.py
  - Remove unused traceback import from chart_api.py

M4: Add input validation for Telegram bot endpoints
  - rate_limit_per_minute: int, 1-120 range
  - broadcast message: max 4096 chars
  - notification priority: int, 1-10 range
  - stats days: int, 1-365 range

M5: Add apikey length constraints (max 256) across all 39 schema fields
  - schemas.py, data_schemas.py, account_schema.py

M6: Restrict ChartSchema payload to prevent storage exhaustion
  - Max 50 keys, key max 50 chars, value max 1MB in chart_api.py

Note: M3 (Windows resource limits) and M7 (Redis rate limiting) are
infrastructure-level changes deferred for separate implementation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

3 issues found across 8 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="restx_api/chart_api.py">

<violation number="1" location="restx_api/chart_api.py:86">
P2: The 1MB value-size limit is bypassable because it only validates `str` values; large non-string JSON values are not limited.</violation>
</file>

<file name="restx_api/schemas.py">

<violation number="1" location="restx_api/schemas.py:307">
P3: The custom Length error message is now incorrect: with `max=256` added, overlong API keys will still return "API key is required.".</violation>
</file>

<file name="database/symbol.py">

<violation number="1" location="database/symbol.py:88">
P2: The new wildcard escaping is incomplete: `safe_term` adds backslashes, but `.ilike()` calls do not pass `escape="\\"`, so literal `%`/`_` searches can fail or behave inconsistently across databases.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Kalaiviswa and others added 2 commits March 9, 2026 14:49
- Replace slow df.apply() and iterrows() with vectorized pandas operations
- Use bulk_insert_mappings with 10K batch inserts instead of ORM object loop
- Master contract download reduced from 5+ minutes to ~22 seconds
- Normalize all per-tick WebSocket logging from INFO to DEBUG
- Add periodic summary logging (1 info line per 500 ticks)
- Remove emojis from log messages and ~150 lines of dead code

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- chart_api: Validate serialized size for all value types, not just strings
- symbol.py: Add escape="\\" to all ilike() calls so wildcard escaping works
- schemas: Fix incorrect error message on MarginCalculatorSchema apikey field

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Kalaiviswa Kalaiviswa changed the title fix: patch 5 medium-severity findings from deep security audit fix: patch 5 medium-severity findings from deep security audit and Groww: Optimize master contract download and normalize streaming logs Mar 9, 2026
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 8 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="broker/groww/database/master_contract_db.py">

<violation number="1" location="broker/groww/database/master_contract_db.py:78">
P1: Per-batch `commit()` inside the loop means a mid-way failure leaves the database with partial data. Earlier batches are already committed and cannot be rolled back, yet `delete_symtoken_table()` already wiped the previous data. Move the `commit()` after the loop to keep the entire insert atomic, or wrap the whole operation (delete + insert) in a single transaction.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Kalaiviswa and others added 2 commits March 9, 2026 15:22
Use flush() per batch and single commit() after loop so all batches
can be rolled back if any fails mid-way.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Crypto spot instruments (BTC_INR, ETH_INR, SOL_INR, XRP_INR) require fractional
order sizes (e.g. 0.0001 BTC). Schema quantity fields changed from Int to Float
to allow fractional values through API validation. Delta Exchange transform layer
uses instrument type lookup to send float for spot and int for derivatives.
Also adds spot/move_options to contract type map and uses min_order_size for lotsize.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

5 issues found across 4 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="restx_api/schemas.py">

<violation number="1" location="restx_api/schemas.py:12">
P1: Changing order quantity from integer to float allows fractional quantities that can be rejected downstream by broker order APIs.</violation>

<violation number="2" location="restx_api/schemas.py:148">
P1: Using float for split size/quantity can create fractional child orders and precision errors in split-order generation.</violation>
</file>

<file name="broker/deltaexchange/api/order_api.py">

<violation number="1" location="broker/deltaexchange/api/order_api.py:409">
P1: Using float for smart-order position arithmetic can produce precision drift that gets truncated by downstream `int(qty)` conversion, leading to wrong contract size orders.</violation>
</file>

<file name="broker/deltaexchange/mapping/transform_data.py">

<violation number="1" location="broker/deltaexchange/mapping/transform_data.py:20">
P1: Non-spot quantity conversion silently truncates fractional contracts instead of rejecting invalid sizes.</violation>
</file>

<file name="broker/deltaexchange/database/master_contract_db.py">

<violation number="1" location="broker/deltaexchange/database/master_contract_db.py:463">
P1: `lotsize` is now produced as float but the DB model keeps `lotsize` as `Integer`; fractional spot sizes risk truncation/coercion.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

exchange = data.get("exchange")
product = data.get("product")
position_size = int(data.get("position_size", "0"))
position_size = float(data.get("position_size", "0"))
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 9, 2026

Choose a reason for hiding this comment

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

P1: Using float for smart-order position arithmetic can produce precision drift that gets truncated by downstream int(qty) conversion, leading to wrong contract size orders.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At broker/deltaexchange/api/order_api.py, line 409:

<comment>Using float for smart-order position arithmetic can produce precision drift that gets truncated by downstream `int(qty)` conversion, leading to wrong contract size orders.</comment>

<file context>
@@ -406,22 +406,22 @@ def place_smartorder_api(data, auth):
     exchange = data.get("exchange")
     product = data.get("product")
-    position_size = int(data.get("position_size", "0"))
+    position_size = float(data.get("position_size", "0"))
 
-    current_position = int(
</file context>
Fix with Cubic

# Lot size: use min_order_size from product_specs (important for spot
# instruments where fractional quantities are allowed, e.g. 0.0001 BTC)
try:
lotsize = float(product_specs.get("min_order_size") or 1)
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 9, 2026

Choose a reason for hiding this comment

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

P1: lotsize is now produced as float but the DB model keeps lotsize as Integer; fractional spot sizes risk truncation/coercion.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At broker/deltaexchange/database/master_contract_db.py, line 463:

<comment>`lotsize` is now produced as float but the DB model keeps `lotsize` as `Integer`; fractional spot sizes risk truncation/coercion.</comment>

<file context>
@@ -437,16 +439,30 @@ def process_delta_products(products):
+        # Lot size: use min_order_size from product_specs (important for spot
+        # instruments where fractional quantities are allowed, e.g. 0.0001 BTC)
+        try:
+            lotsize = float(product_specs.get("min_order_size") or 1)
+        except (ValueError, TypeError):
+            lotsize = 1.0
</file context>
Fix with Cubic

- Spot positions now fetched from wallet/balances (not in /positions/margined)
- float() instead of int() for position size to support fractional spot qty
- Reject fractional quantities for derivatives with clear error (not silent truncation)
- Revert splitsize to Int (split orders don't need fractional sizes)
- Position formatter preserves fractional quantities instead of int() casting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Kalaiviswa Kalaiviswa changed the title fix: patch 5 medium-severity findings from deep security audit and Groww: Optimize master contract download and normalize streaming logs fix: patch 5 medium-severity findings from deep security audit ,Support fractional quantities for crypto spot trading on Delta Exchange ,Fix position book for crypto spot and Groww: Optimize master contract download and normalize streaming logs Mar 9, 2026
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 5 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="broker/deltaexchange/api/order_api.py">

<violation number="1" location="broker/deltaexchange/api/order_api.py:272">
P2: Fractional spot quantities are added to positions, but downstream close-all logic truncates size to int, causing sub-1 spot positions to be silently skipped.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

positions.append({
"product_id": asset.get("asset_id", ""),
"product_symbol": spot_symbol,
"size": size,
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 9, 2026

Choose a reason for hiding this comment

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

P2: Fractional spot quantities are added to positions, but downstream close-all logic truncates size to int, causing sub-1 spot positions to be silently skipped.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At broker/deltaexchange/api/order_api.py, line 272:

<comment>Fractional spot quantities are added to positions, but downstream close-all logic truncates size to int, causing sub-1 spot positions to be silently skipped.</comment>

<file context>
@@ -228,20 +228,61 @@ def get_trade_book(auth):
+                positions.append({
+                    "product_id": asset.get("asset_id", ""),
+                    "product_symbol": spot_symbol,
+                    "size": size,
+                    "entry_price": "0",  # Wallet doesn't track entry price
+                    "realized_pnl": "0",
</file context>
Fix with Cubic

Kalaiviswa and others added 2 commits March 9, 2026 16:53
…ulation

int() in margin_data.py silently truncated sub-1 spot quantities (e.g. 0.0001 BTC)
to 0, causing them to be skipped. Use _order_size() to preserve fractional spot
sizes while keeping integer enforcement for derivatives.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add requests.Session for HTTP connection pooling instead of bare requests calls
- Close all HTTP responses explicitly via try/finally to prevent FD leaks
- Add close() method for full teardown of Socket.IO client + HTTP session
- Force-kill Engine.IO transport on disconnect/reconnect to release FDs and threads
- Use threading.Event for interruptible reconnect sleep so disconnect() returns instantly
- Close previous ws_client on re-initialize to prevent orphaned resources

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Kalaiviswa Kalaiviswa changed the title fix: patch 5 medium-severity findings from deep security audit ,Support fractional quantities for crypto spot trading on Delta Exchange ,Fix position book for crypto spot and Groww: Optimize master contract download and normalize streaming logs fix: patch 5 medium-severity findings from deep security audit ,Support fractional quantities for crypto spot trading on Delta Exchange ,Fix position book for crypto spot, rmoney FD audit fix and Groww: Optimize master contract and normalize streaming logs Mar 9, 2026
@marketcalls marketcalls merged commit 88aea5e into marketcalls:main Mar 9, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants