$npx -y skills add Uniswap/uniswap-ai --skill dca-botThis skill should be used when the user wants to "dca into" a token, "buy X every day", set up a "recurring buy", "dollar cost average" into an asset, "schedule a buy", or "auto-buy on a dip". Buys a fixed amount into a token on a schedule, optionally only when a condition holds
| 1 | # DCA Bot |
| 2 | |
| 3 | Dollar-cost-average a fixed amount into a token on a schedule on the operator's target chain, optionally gated on a price condition such as "only buy when ETH is below a threshold". |
| 4 | |
| 5 | > **Runtime Compatibility:** This skill uses `AskUserQuestion` for interactive prompts (mode selection, per-transaction confirmation). If `AskUserQuestion` is not available in your runtime, collect the same parameters and confirmations through natural language conversation instead. |
| 6 | |
| 7 | ## Overview |
| 8 | |
| 9 | This is a thin strategy layer. It owns cadence, idempotency, the optional condition check, and guardrails. It does NOT own execution. Every quote, approval, swap, and signature is delegated to `swap-integration` and `viem-integration`. The skill never builds quote, approval, swap, or signing logic itself. |
| 10 | |
| 11 | The skill does not run a scheduler. The host agent's scheduler (a cron entry or the runtime's wake mechanism) invokes the skill on a cadence. Each invocation is a single, self-contained run that reads state, decides whether to act, optionally acts, and writes state. |
| 12 | |
| 13 | ## Prerequisites |
| 14 | |
| 15 | - **swap-integration** (uniswap-trading): the only execution path. All swaps go through its Trading API flow (`check_approval` then `quote` then `swap`, then sign and broadcast). Do not reimplement any of it. |
| 16 | - **viem-integration** (uniswap-viem): accounts, clients, signing, transaction broadcast, and receipt waiting. |
| 17 | |
| 18 | Read these plugin references before acting and treat them as ground truth: |
| 19 | |
| 20 | - selected target-chain template: chainId, chain name, contract addresses, tradable token source, funding constraints, market-data availability, and template-specific caveats. For the reference Robinhood Chain template, see `../../references/robinhood-chain.md`. |
| 21 | - `../../references/execution-model.md`: the Trading API requirement, execution modes, restrictions, and disclaimer rules. |
| 22 | - `../../references/strategy-state.md`: the shared state file and scheduler pattern. |
| 23 | |
| 24 | ## Template inputs |
| 25 | |
| 26 | The selected target-chain template must provide: |
| 27 | |
| 28 | - chain id, chain name, native gas token, and RPC / read path. |
| 29 | - deployed Uniswap router, Permit2, and quoter / state-reader addresses needed by delegated execution. |
| 30 | - tradable token resolution rules, including any token list or allowlist source. |
| 31 | - funding constraints and market-data availability. |
| 32 | - transfer-restriction caveats and market-hours guidance. |
| 33 | |
| 34 | ## Workflow |
| 35 | |
| 36 | ### Step 1: Read state |
| 37 | |
| 38 | Read the bot's JSON state file (see [State](#state)). If it does not exist, treat this as the first run. |
| 39 | |
| 40 | ### Step 2: Check cadence and idempotency |
| 41 | |
| 42 | Compute the current period from the configured cadence (for example the UTC day for a daily DCA). If the state file shows a successful buy already recorded for the current period, skip and exit. This makes repeated wakes within one period safe (no double buys). |
| 43 | |
| 44 | ### Step 3: Resolve token and amount |
| 45 | |
| 46 | Resolve the target token to an address by reading the selected target-chain template and its token source. Resolve the fixed buy amount from config. Validate both before use (see [Input validation](#input-validation)). Do not maintain a local token registry; reuse the template-provided token list or resolver. |
| 47 | |
| 48 | ### Step 4: Collect guardrails |
| 49 | |
| 50 | Read the configured guardrails. If the per-run spend cap or per-period spend cap is missing, ask the operator for those caps using `AskUserQuestion` (or natural language if unavailable); include the funding token or denomination used for comparison. If either cap remains unset, do not enter `autonomous` mode. In `confirm` mode, proceed only with the per-transaction confirmation gate and report that autonomous mode remains unavailable. |
| 51 | |
| 52 | ### Step 5: Optional condition check |
| 53 | |
| 54 | If a condition is configured (for example "only when the last daily candle is red"), evaluate it before buying: |
| 55 | |
| 56 | - Fetch the price needed for the condition from Uniswap: the Trading API `/quote` (via `swap-integration`). Do not use venue-specific APIs or non-Uniswap price feeds for execution data; see `../../references/execution-model.md` (Data and pricing). If the condition needs market data Uniswap does not expose, treat that data source as unavailable rather than adding an external dependency. |
| 57 | - Evaluate the predicate (for example `price < 3000 USDC`). |
| 58 | - If the condition is not met, record |