Deployed contracts
Base mainnet addresses, ownership, oracle routes, automation, and external dependencies for third-party review.
DCA Onchain is available on Base mainnet. Contract source is visible on Basescan. The protocol uses per-user strategy accounts, pooled scheduled execution, Uniswap V3 routing for all currently supported assets, Chainlink-based oracle floors, Aave V3 for optional idle USDC yield, and a 2-of-3 Safe for protocol administration.
Base mainnet contracts
These are the live protocol contracts. The account implementation is cloned for each user strategy; the other contracts are shared protocol components.
| Contract | Address | What to review |
|---|---|---|
| DCAFactory | 0x88728a549adaB8E03Aab0a5E58FeBe52Ba9a7B32 | Creates strategy accounts, stores fees, treasury, minimums, and yield-adapter approvals. |
| BatchExecutor | 0xbd4BdAA613AAB5290dbF37B3D4ed466dd89c892b | Runs pooled scheduled buys, enforces asset allowlist and oracle floor, distributes output. |
| SwapRouter | 0x1039205486f30888833589FEED1B3890F223887e | Routes swaps from BatchExecutor to the configured adapter for each asset. |
| UniswapV3Adapter | 0xCB5A0A414dC3dB57C58E28fc481aC24b3b8b47A2 | Executes all currently active Base mainnet swaps through Uniswap V3. |
| AerodromeAdapter | 0x6f155CC4354E9639F6cBAF60c69D35969F73D460 | Deployed for venue flexibility, currently not used by active routes. |
| OracleDispatcher | 0xEE4184f807A1e34E2Fd765970735A69BAB3A72DA | Routes each asset to its underlying price oracle. |
| ChainlinkPriceOracle | 0x5c04aa032005cD248aAf5a54800c8Aac2D456c8B | Direct oracle floor for WETH and cbBTC. |
| ComposedPriceOracle | 0xA23b4d7d213c61aeB3ABC7730218919D562D551D | Market-feed composition for cbETH and wstETH. |
| UserStrategyAccount implementation | 0x0FbA3e44f469Db732E73a4913734112AEB67C156 | Implementation used by each per-user strategy clone. |
Roles
| Role | Address | Power |
|---|---|---|
| Protocol owner | 0xf381f18F372B431c523cE26Abcd0BE17d6Ea26D1 | 2-of-3 Safe. Controls configuration, pausing, fees within hard caps, oracle routes, asset allowlist, executor address, and adapter settings. |
| Treasury | 0x13855b7394C550757C4C0540f96741e95F85dE42 | 2-of-3 Safe. Receives protocol fees. |
| Executor | 0x2cb1105266634e0432d62CD1e757a057c9A0c78f | GitHub Actions bot wallet. Can trigger scheduled batches only; cannot withdraw user funds or change strategy settings. |
All admin-bearing contracts are owned by the protocol owner Safe. User strategy accounts are not owned by the protocol; each account stores its own user owner and only that user can withdraw.
Supported assets
| Asset | Token address | Swap route | Oracle route |
|---|---|---|---|
| WETH | 0x4200000000000000000000000000000000000006 | Uniswap V3 direct from USDC | ETH/USD direct feed |
| wstETH | 0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452 | Uniswap V3 through WETH | wstETH/ETH market feed times ETH/USD |
| cbBTC | 0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf | Uniswap V3 direct from USDC | cbBTC/USD direct feed |
| cbETH | 0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22 | Uniswap V3 through WETH | cbETH/ETH market feed times ETH/USD |
Oracle feeds
The executor submits a minimum output for each batch, but the contract also enforces an independent on-chain oracle floor. For composed assets, the base leg must be a market feed, not an exchange-rate feed.
| Feed | Address | Used for |
|---|---|---|
| ETH/USD | 0x71041dddad3595F9CEd3DcCFBe3D1F4b0a16Bb70 | WETH direct pricing and quote leg for composed assets. |
| cbBTC/USD | 0x07DA0E54543a844a80ABE69c8A12F22B3aA59f9D | cbBTC direct pricing. |
| wstETH/ETH market | 0x43a5C292A453A3bF3606fa856197f09D7B74251a | wstETH composed pricing. |
| cbETH/ETH market | 0x806b4Ac04501c29769051e42783cF04dCE41440b | cbETH composed pricing. |
| Base sequencer uptime | 0xBCF85224fc0756B9Fa45aA7892530B47e10b6433 | Blocks oracle quotes while the L2 sequencer is down or in its recovery window. |
Current oracle parameters: 200 bps oracle haircut, 3600 second direct-feed staleness, 90000 second composed-base staleness, 3600 second quote-leg staleness, and 3600 second sequencer grace.
External dependencies
| Dependency | Address | Purpose |
|---|---|---|
| USDC | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 | Deposit asset. |
| Aave V3 Pool | 0xA238Dd80C259a72e81d7e4664a9801593F98d1c5 | Optional idle USDC yield. |
| Aave aUSDC | 0x4e65fE4DbA92790696d040ac24Aa414708F5c0AB | Receipt token held by yield adapters. |
| Uniswap V3 Router | 0x2626664c2603336E57B271c5C0b26F421741e481 | Swap execution. |
| Uniswap V3 QuoterV2 | 0x222cA98F00eD15B1faE10B61c277703a194cf5d2 | Executor quote source before submitting a batch. |
| Aerodrome Router | 0xcF77a3Ba9A5CA399B7c97c74d54e5b1Beb874E43 | Available for adapter support, not currently active. |
Fees and controls
Fees are stored in DCAFactory and apply globally. If the protocol owner changes a fee, the new value applies to existing strategies going forward, within hard on-chain caps.
| Fee | Current | Hard cap | Charged when |
|---|---|---|---|
| Execution fee | 15 bps (0.15%) | 100 bps (1%) | On purchased output during each completed batch. |
| Yield fee | 1500 bps (15%) | 3000 bps (30%) | Only on positive Aave yield when a user withdraws. |
| Referrer share | 3000 bps (30%) | 5000 bps (50%) | Share of the protocol's execution fee paid to the referrer, if the strategy has one. |
Example: if the execution fee is 1.50 USDC worth of the purchased asset and referrer share is 30%, the referrer receives 0.45 and the treasury receives 1.05. The user still pays 1.50 total; the referrer share only splits that fee.
The owner can pause new strategy creation and batch execution, change supported assets, switch the executor, adjust oracle routes, and update fees within caps. The owner cannot withdraw from user strategy accounts.
Automation and monitoring
GitHub Actions runs the executor three times a day (00:05, 08:05, and 16:05 UTC) as a single scheduled job: the daily tier fires every run, and the weekly, biweekly, and monthly tiers self-gate by date. The executor groups due accounts by target asset, skips any due account that is under-funded (it waits for a deposit rather than reverting the whole batch), reads live Uniswap routes, obtains a QuoterV2 quote, and submits a batch with a quote-based minimum output. If quoting fails, the batch is skipped rather than submitted with a weak minimum. Each batch is dry-run with a zero-gas eth_call before broadcast, so a batch that would revert deterministically is skipped without spending gas, while a batch that only loses a transient in-block price race is retried within the run with a fresh quote and escalating slippage up to a cap. The independent on-chain oracle floor remains the non-bypassable backstop on every attempt.
Monitoring covers executor gas, workflow heartbeat, oracle health, composed-oracle divergence, pending-withdrawal events, repeated skipped accounts, and batch failures. If automation is unavailable, scheduled buys can be delayed, but user withdrawals remain available.
Reviewer checklist
- Confirm the contract source for each protocol address is visible on Basescan.
- Read
owner()on DCAFactory, BatchExecutor, SwapRouter, OracleDispatcher, ChainlinkPriceOracle, and ComposedPriceOracle. Each should point to the owner Safe above. - Read
treasury(),executionFeeBps(),yieldFeeBps(), andreferrerShareBps()on DCAFactory. - Read
executor(),priceOracle(), and the whitelisted assets on BatchExecutor. - Review each SwapRouter adapter mapping and each Uniswap adapter route for the supported assets.
- Review each OracleDispatcher route and the underlying Chainlink or composed feed configuration.
- Review user withdrawal paths in UserStrategyAccount. Withdrawals are user-only and remain available even if protocol execution is paused.