Skip to content

fix(InventoryClient): Make blocked-rebalance log figures self-consistent#3552

Open
droplet-rl wants to merge 1 commit into
masterfrom
droplet/T90K0AL22-C073ELHSDQ8-1783475639-175289
Open

fix(InventoryClient): Make blocked-rebalance log figures self-consistent#3552
droplet-rl wants to merge 1 commit into
masterfrom
droplet/T90K0AL22-C073ELHSDQ8-1783475639-175289

Conversation

@droplet-rl

Copy link
Copy Markdown
Contributor

Motivation

The transfer blocked lines in the "Executed Inventory rebalances" log mix two points in time, producing self-contradictory output. Example from production (Slack, 2026-07-08):

WETH transfer blocked. Required to send 102.57 but relayer has 908.16 on L1. There is currently 909.73 WETH on Robinhood which is 0.07501% of the total 2,082.72 WETH.

909.73 / 2,082.72 is 43.68%, not 0.07501%, and a 102.57 send being blocked while "relayer has 908.16 on L1" looks nonsensical.

Two causes, both in rebalanceInventoryIfNeeded:

  1. distributionPct came from tokenDistributionPerL1Token, snapshotted at the top of the function, while the chain balance, cumulative total, and pending-transfer figures on the same line are recomputed after approved rebalances have been tracked via trackCrossChainTransfer (which moves L1 balance into the destination chain's pending L1→L2 amount). In the example, ~908 WETH was earmarked to Robinhood earlier in the same run: the live balance read 909.73 while the percentage still reflected the pre-run ~1.56 WETH.
  2. The balance printed was the planning-time L1 balance captured in the rebalance object, not the unallocated balance remaining at decision time (the value the amount.lte(unallocatedBalance) gate actually uses), hiding the real reason for the block.

Changes

  • Compute distributionPct from the same live getBalanceOnChain / getCumulativeBalance reads that are printed alongside it, so the figures on one line are always self-consistent.
  • Record the decision-time unallocated L1 balance on unexecuted rebalances and reword the message accordingly ("relayer had only X unallocated on L1 when the transfer was evaluated").
  • Clarify that the chain balance includes pending inbound transfers.

Same scenario after this change:

WETH transfer blocked. Required to send 102.57 but relayer had only 0.00 unallocated on L1 when the transfer was evaluated. There is currently 909.73 WETH on Robinhood (including pending inbound transfers) which is 43.68% of the total 2,082.72 WETH.

Logging-only change; no behavior change to rebalance planning or execution. No README/AGENTS updates needed since no documented behavior, config, or interface changes.

Verification

  • tsc --noEmit: clean
  • eslint src/clients/InventoryClient.ts: clean
  • npx hardhat test test/InventoryClient.InventoryRebalance.ts: 15 passing

🤖 Generated with Claude Code

The 'transfer blocked' log line printed an allocation percentage from the
distribution snapshot taken at the top of rebalanceInventoryIfNeeded, next to
chain/cumulative balances recomputed after this run's approved rebalances were
tracked via trackCrossChainTransfer. Once a transfer was earmarked, the stale
percentage no longer matched the live figures (e.g. 909.73/2,082.72 WETH
reported as 0.07501% instead of 43.68%).

Compute the percentage from the same live balances printed alongside it, and
report the unallocated L1 balance remaining at decision time rather than the
planning-time balance, which made blocks of tiny transfers look nonsensical
(blocked despite the relayer supposedly holding hundreds of WETH on L1).

Logging-only change; no behavior change to rebalance planning or execution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant