You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
gas_budget.py (PR #14) enforces budgets in the client middleware — the agent sends a tx, the middleware checks the rolling hour/day spend, refuses to broadcast if over. This works in the happy path but has two failure modes:
Out-of-band txs. Anything that bypasses switchboard middleware (a directly-signed RPC call, a different SDK, a buggy plugin) escapes the budget.
Multi-process race. Two switchboard processes for the same agent each check the budget independently, both pass, both broadcast, agent is rugged.
We need the budget enforced at the chain side so the agent's epoch cap is the chain's invariant, not the client's.
Proposed Approach
Promote the budget to a runtime-level hint surfaced to the block builder:
AgentBudget.sol at a well-known address. Stores per-agent (epoch, hourly_cap, daily_cap, hourly_spent, daily_spent, last_reset_block). Updated by AgentEscrow.release and x402_middleware settlement events (these are the only authoritative tx-cost emitters).
Block-builder hint: the builder consults AgentBudget for each tx in the mempool tagged with agent_id. If the tx would push spent over cap, defer to next epoch (or reject if --strict-budget flag set). This is a hint, not consensus — it does not invalidate the tx, it just lets validator policies enforce caps.
switchboard/budget_client.py: thin wrapper that reads AgentBudget state and short-circuits client-side before sending — keeps middleware behavior for legacy callers.
Problem
gas_budget.py(PR #14) enforces budgets in the client middleware — the agent sends a tx, the middleware checks the rolling hour/day spend, refuses to broadcast if over. This works in the happy path but has two failure modes:We need the budget enforced at the chain side so the agent's epoch cap is the chain's invariant, not the client's.
Proposed Approach
Promote the budget to a runtime-level hint surfaced to the block builder:
AgentBudget.solat a well-known address. Stores per-agent(epoch, hourly_cap, daily_cap, hourly_spent, daily_spent, last_reset_block). Updated byAgentEscrow.releaseandx402_middlewaresettlement events (these are the only authoritative tx-cost emitters).AgentBudgetfor each tx in the mempool tagged withagent_id. If the tx would push spent over cap, defer to next epoch (or reject if--strict-budgetflag set). This is a hint, not consensus — it does not invalidate the tx, it just lets validator policies enforce caps.switchboard/budget_client.py: thin wrapper that readsAgentBudgetstate and short-circuits client-side before sending — keeps middleware behavior for legacy callers.waiveEpoch(agentId, newCap)for emergency drain — see issue Security audit: gas-budget waive/cap escalation paths #84 (gas-budget waiver audit) for the security review.Acceptance Criteria
AgentBudget.soldeployed incontracts/with epoch reset logicgas_budget.pyupdated to read on-chain state as authoritativedocs/block-builder-integration.mdfor validator operatorsAgentBudgetvia settlement eventsReferences