Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/collinsville22/Sable/llms.txt

Use this file to discover all available pages before exploring further.

DCA (Dollar-Cost Averaging)

Automated recurring BTC purchases with an intelligent Mayer Multiple strategy that adjusts buy amounts based on whether BTC is historically undervalued or overvalued.

Overview

Sable’s DCA contract enables on-chain recurring BTC purchases with two modes:
  1. Standard DCA: Fixed amount per order (traditional DCA)
  2. Smart DCA: Mayer Multiple adjusted amounts (buy more when cheap, less when expensive)

How It Works

1

Create Order

User selects parameters:
  • Sell token: USDC, USDT, ETH, or STRK
  • Amount per order: e.g., 10 USDC
  • Frequency: Daily, Weekly, Bi-weekly, or Monthly
  • Number of orders: 1-365
  • Strategy: Standard or Smart (Mayer Multiple)
const order = {
  sellToken: "USDC",
  amountPerOrder: "10",
  frequency: "weekly",
  totalOrders: 12,
  smart: true  // Enable Mayer Multiple
}
2

Deposit Funds

For Standard DCA:
Deposit = amountPerOrder × totalOrders
Example: 10 USDC × 12 orders = 120 USDC
For Smart DCA:
Deposit = amountPerOrder × totalOrders × 1.5
Example: 10 USDC × 12 orders × 1.5 = 180 USDC
Smart DCA requires 1.5x deposit to cover worst-case (all orders at max 1.5x multiplier). Unused funds are refunded on completion.
3

Keeper Execution

Off-chain keeper bot monitors orders and triggers execution when due:
  1. Checks if block.timestamp >= nextExecution
  2. For Smart DCA, queries Pragma Oracle for Mayer Multiple
  3. Calculates adjusted buy amount
  4. Fetches AVNU swap quote
  5. Executes on-chain swap
  6. WBTC sent directly to user’s wallet
4

Completion or Cancel

  • Completion: After all orders execute, unused funds (Smart DCA) are refunded
  • Cancel Anytime: User can cancel active order and receive all unspent funds immediately

Smart DCA — Mayer Multiple Strategy

What is the Mayer Multiple?

The Mayer Multiple is the ratio of BTC’s current price to its 200-day moving average:
Mayer Multiple = Current BTC Price / 200-day Moving Average
When the multiple is low, BTC is historically cheap — buy more. When high, it’s overheated — buy less.

Multiplier Table

Mayer MultipleMarket SignalBuy MultiplierExample (10 USDC base)
< 0.8Deeply undervalued1.5x15 USDC
0.8 – 1.0Undervalued1.25x12.50 USDC
1.0 – 1.5Fair value1.0x10 USDC
1.5 – 2.0Overvalued0.75x7.50 USDC
> 2.0Extremely overvalued0.5x5 USDC

Backtested Performance

Historical backtests show Smart DCA outperforms standard DCA by 50-60% over 4-year cycles by:
  • Accumulating more BTC during bear markets (MM < 0.8)
  • Reducing exposure during bubble periods (MM > 2.0)

1.5x Deposit Buffer Explained

Smart DCA deposits amount × orders × 1.5 upfront to cover worst-case scenario:
Example: 10 USDC × 4 orders × 1.5 = 60 USDC deposited

Execution:
  Order 1: MM=0.76 → 15 USDC spent (1.5x)   | Running: 15/60
  Order 2: MM=1.12 → 10 USDC spent (1.0x)    | Running: 25/60
  Order 3: MM=0.95 → 12.50 USDC spent (1.25x)| Running: 37.50/60
  Order 4: MM=1.80 → 7.50 USDC spent (0.75x) | Running: 45/60
  ──────────────────────────────────────────────────
  Total spent: 45 USDC    Refunded: 15 USDC
If the market stays fair value (MM ≈ 1.0), you’ll receive ~33% of your deposit back as a refund.

DCA Contract Flow

┌──────────┐     approve + create_order      ┌─────────────┐
│   User   │ ──────────────────────────► │ DCA Contract │
│          │                                  │              │
│          │     cancel_order (refunds)       │  Orders[]    │
│          │ ◄────────────────────────── │  Executions[]│
└──────────┘                                  └──────┬───────┘

                   execute_order(routes)               │
┌──────────┐ ──────────────────────────────────────┘
│  Keeper  │          │
│   Bot    │          ▼
│          │    ┌─────────────┐    ┌──────────────┐
│(off-chain│    │ Pragma      │    │ AVNU Router  │
│ cron job)│    │ Oracle      │    │ (DEX swap)   │
└──────────┘    │ (BTC/TWAP)  │    │              │
                └─────────────┘    └──────────────┘

Order Creation

Standard DCA

let order = DcaOrder {
    user: caller_address,
    sell_token: USDC_ADDRESS,
    amount_per_order: 10_000_000,  // 10 USDC (6 decimals)
    frequency: WEEKLY,              // 604800 seconds
    total_orders: 12,
    executed_orders: 0,
    smart: false,
    deposited: 120_000_000,         // 120 USDC
    spent: 0,
    btc_received: 0,
    next_execution: block.timestamp + WEEKLY,
    active: true
};

dca_contract.create_order(order);

Smart DCA

let order = DcaOrder {
    // ... same as above ...
    smart: true,
    deposited: 180_000_000,         // 180 USDC (1.5x buffer)
};

dca_contract.create_order(order);

Keeper Bot Architecture

The keeper bot runs off-chain and triggers order execution:
// scripts/dca_keeper.mjs

while (true) {
  // 1. Fetch all active orders
  const orders = await dcaContract.get_active_orders();
  
  // 2. Check which orders are due
  const dueOrders = orders.filter(o => 
    Date.now() >= o.nextExecution
  );
  
  for (const order of dueOrders) {
    // 3. Calculate buy amount
    let amount = order.amountPerOrder;
    
    if (order.smart) {
      // Query Pragma for Mayer Multiple
      const btcPrice = await pragma.get_spot_price("BTC/USD");
      const twap200d = await pragma.get_twap("BTC/USD", 200);
      const mm = btcPrice / twap200d;
      
      // Apply multiplier
      if (mm < 0.8) amount *= 1.5;
      else if (mm < 1.0) amount *= 1.25;
      else if (mm > 2.0) amount *= 0.5;
      else if (mm > 1.5) amount *= 0.75;
    }
    
    // 4. Get AVNU swap quote
    const quote = await avnu.getQuote({
      sellToken: order.sellToken,
      buyToken: WBTC,
      amount: amount
    });
    
    // 5. Execute order on-chain
    await dcaContract.execute_order(
      order.id,
      quote.routes,
      amount
    );
  }
  
  await sleep(60_000); // Check every minute
}

Order Execution

When a keeper triggers execution:
  1. Verify Timing: Contract checks block.timestamp >= nextExecution
  2. Verify Funds: Ensure sufficient deposited - spent balance
  3. Execute Swap: Call AVNU router with provided routes
  4. Transfer WBTC: Send purchased WBTC directly to user
  5. Update State:
    • Increment executedOrders
    • Update spent amount
    • Update btcReceived
    • Set nextExecution to current time + frequency
  6. Auto-Complete: If executedOrders == totalOrders, mark inactive and refund remaining

Cancel Order

Users can cancel active orders anytime:
dca_contract.cancel_order(order_id);
Refund Calculation:
refund = deposited - spent
Example:
  • Deposited: 180 USDC
  • Executed: 3/12 orders (45 USDC spent)
  • Refund: 135 USDC

Supported Sell Tokens

TokenAddressDecimals
USDC0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a86
USDT0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb86
ETH0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc718
STRK0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d18
All tokens are swapped to WBTC via AVNU DEX aggregator, which routes through Ekubo, Jediswap, and other DEXes for best rates.

Frequency Options

FrequencySecondsDescription
Daily86,400Execute once per day
Weekly604,800Execute once per week
Bi-weekly1,209,600Execute once per 2 weeks
Monthly2,592,000Execute once per 30 days

DCA Contract

Address: 0x0730f5de50171590132ff9238859d7eccbfa8359393f52083b3b88b397955e56 Key Functions:
// Create new DCA order
fn create_order(
    sell_token: ContractAddress,
    amount_per_order: u256,
    frequency: u64,
    total_orders: u32,
    smart: bool
) -> u256;

// Execute due order (keeper only)
fn execute_order(
    order_id: u256,
    routes: Array<Route>,
    amount: u256
);

// Cancel order (user only)
fn cancel_order(order_id: u256);

// View functions
fn get_order(order_id: u256) -> DcaOrder;
fn get_user_orders(user: ContractAddress) -> Array<u256>;
fn get_active_orders() -> Array<DcaOrder>;

Example Order Lifecycle

Order Created:
  Sell: USDC
  Amount: 10 USDC/order
  Frequency: Weekly
  Total: 12 orders
  Smart: true
  Deposited: 180 USDC

Week 1: MM=0.75 → Buy 15 USDC (1.5x) → 0.00015 WBTC received
Week 2: MM=0.92 → Buy 12.5 USDC (1.25x) → 0.00013 WBTC received
Week 3: MM=1.10 → Buy 10 USDC (1.0x) → 0.000105 WBTC received
Week 4: MM=1.35 → Buy 10 USDC (1.0x) → 0.000098 WBTC received

Total spent: 47.5 USDC
Total BTC: 0.000503 WBTC
Remaining: 132.5 USDC

Risk Factors

  • Swap slippage: High volatility can cause unfavorable execution prices
  • Price volatility: BTC price can change between order creation and execution
  • DEX liquidity: Low liquidity may prevent large orders from executing
  • Oracle risk: Pragma oracle outage could delay Smart DCA execution
  • Keeper availability: If keeper bot goes offline, orders won’t execute on time

Next Steps

Create Your First DCA Order

Set up automated BTC purchases

Understanding Mayer Multiple

Learn the strategy behind Smart DCA

DCA Contract Reference

Technical documentation and ABIs

Run Your Own Keeper Bot

Deploy a keeper bot for order execution