KeeperHub / KeeperHub/keeperhub

api: /api/execute/transfer ignores ?simulate=true — the request executes

Open
#1,959 2 comments 0 reactions 0 assignees View on GitHub
accepted confirmed
Dominant language
TypeScript
Stars
24
Forks
93
Avg merge
1d 8h
Merged PRs (30d)
266

Description

## Summary

`POST /api/execute/transfer?simulate=true` does not simulate — it **executes** the transfer and returns a confirmed `transactionHash`. A caller that wants a dry-run of a transfer has no safe path on this endpoint.

Verified live on Sepolia (2026-08-07): sending the query param produced a real, sponsored, confirmed transfer (tx 0x973f686e…84f8, Blockscout status 1). No `simulate`/dry-run flag exists in the transfer body either (probed `{"simulate":true}`, `{"dryRun":true}`, `{"preview":true}` — all executed).

## Why this bites

Policy/guardrail layers (like ours — Ballast) want to simulate before broadcast for *every* action type. `/api/execute/contract-call` supports `"simulate": true` and returns `{status:"simulated", gasEstimate, wouldRevert}`, so contract calls are safe to gate. Transfers are the one primitive where a caller cannot preview before executing — and for an agent with a wallet, a transfer is the highest-risk action.

## Repro

1. `POST /api/execute/transfer?simulate=true` with `{chainId:11155111, recipientAddress, amount}`
2. Observe a real `executionId` + `transactionHash` + `status: completed` — money moved.

## Expected

Either (a) a `simulate: true` body flag that returns `{status:"simulated", wouldRevert, gasEstimate, from, to, amount}` without broadcasting, mirroring contract-call; or (b) a documented `/api/execute/transfer/simulate` path; or (c) explicit rejection of `?simulate=true` (400 `unsupported_param`) instead of silently executing.

Related: #1840 (retry semantics for execute_contract_call) — same caller profile: agents that must verify before they act.

Contributor guide

Open the contributing guide

Research direction

Start by tracing the POST /api/execute/transfer endpoint and compare its handling with POST /api/execute/contract-call, which the issue identifies as supporting simulation. Done means the transfer endpoint no longer broadcasts when simulation is requested, returns the agreed simulation result, and preserves safe behavior for unsupported parameters.

Written by the indexing model from the issue text.

Assessment

Tech stack
blockchain, typescript
Domain
api, blockchain, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.