Treasury sweep with approval
Template: treasury-sweep-approval ยท category: treasury ยท risk: money_moving
A cron reads a hot treasury wallet's ERC20 balance; above a threshold the
sweep to cold storage is prepared, simulated and parked behind a human
approval (rflow approvals ls, rflow approve <id>). Runnable sibling:
examples/treasury-ops.
When to use it
- keep hot-wallet balances low without a human doing the transfer by hand
- any recurring send where a person must stay in the loop
Generate it
rflow new --template treasury-sweep-approval
# or into an existing project (needs a signer; adds the `treasury` relayer):
rflow add workflow treasury-sweep-approvalInputs
| key | type | default |
|---|---|---|
project_name | string | treasury-ops |
network / chain_id / rpc_env / rpc_url | network / chain_id / env_var / string | ethereum / 1 / ETH_RPC / a public RPC |
token_address / token_decimals | address / int | USDC mainnet / 6 |
cold_storage | address | zero placeholder โ replace it |
min_sweep_amount | token_amount | 1000 |
sweep_cron | cron | 0 * * * * (hourly) |
approval_timeout | duration | 1h |
gas_max_price | string | 100 gwei |
Required env vars
DATABASE_URL, the RPC env var, RAW_DANGEROUS_MNEMONIC. rflow new fills
.env with a freshly generated DEV-ONLY mnemonic โ swap in a production
signer before real funds ride on this config.
Safety defaults (all generated)
- pre-flight simulation +
assert_sim: ["${{ sim.ok }}"] - gas cap:
limit_from_simulation+max_price - post-approval re-simulation โ approve re-prepares + re-simulates, so a
wallet drained during the wait reverts and dead-letters instead of firing
stale (no
recheck: expressions only see the journaled balance read, which cannot change while the run is parked) - approval gate
via: [cli],on_timeout: fail confirmations: 12on the network,wait_for: confirmedconcurrency.on_conflict: skipโ one sweep in flight at a timeon_failure: dead_letter
Production checklist
- replace the
cold_storageplaceholder with the real address - replace the raw dev mnemonic with a production signer
- add a second approval route (
via: [telegram: ops, cli]) - dry-run it first:
rflow test treasury-sweep-approval --cron-at <tick>