DCA.fun Pig LogoDCA.fun

Smart Contracts

Technical reference for DCA.fun smart contracts

Smart Contracts

Complete reference for all DCA.fun protocol contracts.

Core Contracts

DcaDotFun.sol

Main protocol contract managing orders:

contract DcaDotFun is DotFun, IDcaDotFun, ReentrancyGuard {
    // Order Management
    function createOrder(OrderArgs calldata args, bytes[] calldata reports) external;
    function cancelOrders(uint256[] calldata orderIds) external;
    function fillOrder(bytes calldata data, address recipient) external;

    // Queries
    function getOrders(uint256[] calldata ids) external view returns (Order[] memory);
    function quote(uint256 id, bytes[] calldata reports) external returns (bytes memory, OrderValidation memory);
    function getOrderTokens(uint256[] calldata ids) external view returns (OrderTokens[] memory);
}

Key Functions

createOrder

function createOrder(
    OrderArgs calldata args,
    bytes[] calldata reports
) external returns (uint256 orderId)

Creates a new DCA order with the specified parameters.

Parameters:

  • args: Order configuration (see OrderArgs struct below)
  • reports: Chainlink price reports for token validation

fillOrder

function fillOrder(
    bytes calldata data,
    address recipient
) external

Executes an order fill using encoded quote data.

Parameters:

  • data: Encoded quote data from the API
  • recipient: Address to receive profit

DcaVault.sol

Isolated vault for each order:

contract DcaVault is Initializable, Ownable, IDcaVault {
    // State variables
    uint256 public orderId;
    uint256 public yieldSplit;
    uint256 public escrow;
    uint256 public totalFills;
    uint256 public spendAmount;
    address public funContract;
    address public feeCollector;
    address public recipient;
    address public tokenIn;
    address public aTokenIn;
    address public tokenOut;
    address public aTokenOut;
    address public pool;
    bool public isCancelled;

    // Protocol Functions
    function fillOrder(address recipient, uint256 amount, uint256 escrow) external;
    function cancelOrder(uint256 repeats) external;

    // Owner Functions
    function withdrawErc20(address token) external;
    function withdrawNative() external;
}

DcaVaultFactory.sol

Deploys vault clones:

contract DcaVaultFactory {
    address public implementation;
    address public aavePool;
    mapping(uint256 => address) public vaults;

    function createVault(
        uint256 id,
        address orderCreator,
        address recipient,
        address tokenIn,
        address tokenOut,
        uint256 spendAmount,
        uint256 yieldSplit,
        address feeCollector,
        bool stakeAssetIn,
        bool stakeAssetOut
    ) external returns (address vault);
}

Data Structures

OrderArgs Struct

struct OrderArgs {
    address recipient;      // Who receives output tokens
    address tokenIn;        // Input token address
    address tokenOut;       // Output token address
    uint256 spendAmount;    // Amount per execution
    uint256 repeats;        // Number of executions
    uint256 freqInterval;   // Time between executions
    uint256 scalingInterval; // Dutch auction duration
    uint256 slippage;       // Max price deviation (basis points)
    uint256 firstExecution; // Delay before first execution
    bool stakeAssetIn;      // Stake input in Aave
    bool stakeAssetOut;     // Stake output in Aave
}

Order Struct

struct Order {
    address creator;      // Order creator
    uint16 slippage;      // Slippage tolerance
    bool stakeAssetIn;    // Stake input flag
    bool stakeAssetOut;   // Stake output flag
    address recipient;    // Output recipient
    address tokenIn;      // Input token
    address tokenOut;     // Output token
    uint256 spendAmount;  // Amount per fill
    uint256 repeats;      // Remaining executions
    uint256 freqInterval; // Execution frequency
    uint256 scalingInterval; // Auction duration
    uint256 lastRun;      // Last execution time
    uint256 protocolFee;  // Fee at creation
    address vault;        // Vault address
}

OrderValidation Struct

struct OrderValidation {
    uint256 scalingFactor;
    uint256 effectiveSlippage;
    uint256 fillableAmount;
    uint256 amountOfTokenOut;
    uint256 inAmount;
    uint256 minOutAmount;
    bool valid;
}

Key Interfaces

IFillOrderCallback

For advanced filling strategies:

interface IFillOrderCallback {
    function fillOrderCallback(
        address tokenOut,
        uint256 amountOfTokenOut,
        address initiator
    ) external returns (bool);
}

IDcaDotFun

Main protocol interface:

interface IDcaDotFun {
    // Order creation
    function createOrder(OrderArgs calldata args, bytes[] calldata reports) external;
    function createOrderNative(OrderArgs calldata args, bytes[] calldata reports) external payable;

    // Order management
    function cancelOrders(uint256[] calldata orderIds) external;

    // Order execution
    function fillOrder(bytes calldata data, address recipient) external;
    function fillOrder(bytes calldata data, address callback, address initiator, address recipient) external;

    // Queries
    function getOrders(uint256[] calldata ids) external view returns (Order[] memory);
    function quote(uint256 id, bytes[] calldata reports) external returns (bytes memory, OrderValidation memory);
    function getOrderTokens(uint256[] calldata ids) external view returns (OrderTokens[] memory);

    // Token management
    function getTokenProps(address token) external view returns (TokenProps memory);
    function setTokenProps(address token, bytes32 priceFeed, bool isStakable) external;
}

Events

Monitor protocol activity with these events:

event CreateOrder(
    uint256 indexed orderId,
    address indexed creator,
    address recipient,
    address tokenIn,
    address tokenOut,
    uint256 spendAmount,
    uint256 repeats,
    uint256 freqInterval,
    uint256 scalingInterval,
    uint256 slippage,
    uint256 firstExecution,
    bool stakeAssetIn,
    bool stakeAssetOut
);

event FillOrder(
    uint256 indexed orderId,
    address caller,
    address recipient,
    uint256 fillAmount,
    uint256 amountOfTokenOut,
    uint256 protocolFee,
    uint256 tokenInPrice,
    uint256 tokenOutPrice
);

event CancelOrder(
    uint256 orderId,
    address vault
);

event SetTokenProps(
    address indexed token,
    bytes32 feed,
    uint8 tokenDecimals,
    bool isActive,
    bool isStakable
);

Error Codes

Common errors and their meanings:

// Order Errors
error OrderDoesNotExist();          // Invalid order ID
error OrderNotActive();             // Order completed or cancelled
error NotOrderCreator();            // Only creator can cancel
error PriorToOrderExecution();      // Too early to fill

// Token Errors
error TokenNotActive();             // Token not supported
error TokenNotStakable();           // Token can't be staked
error No FeedID on Order();         // Missing price feed

// Parameter Errors
error InvalidSlippage();            // Slippage out of bounds
error InvalidFrequencyInterval();   // Frequency too low
error InvalidScalingInterval();     // Scaling interval too high
error InvalidFirstExecution();      // First execution in past

// Execution Errors
error InvalidPriceReports();        // Bad oracle data
error FeedTooStale();              // Price data too old
error TimestampTolerance();        // Feed timestamp mismatch
error MinimumExecutionValue();     // Order too small

// Permission Errors
error CreateOrderPaused();         // Creation paused
error FillOrderPaused();          // Filling paused
error Paused();                   // Protocol paused

Contract Addresses

Base Mainnet

ContractAddress
DcaDotFunComing Soon
DcaVaultFactoryComing Soon
VerifierDotFunComing Soon

Base Sepolia

ContractAddress
DcaDotFun0x41177B8b91F59e29B088d78a9D7DdD8ce99E8998
DcaVaultFactoryTBD
VerifierDotFunTBD

Monad Testnet

ContractAddress
DcaDotFun0xB2D1FA47E6F4Cb3c973f06EA2130078BD4D63c39
DcaVaultFactoryTBD
VerifierDotFunTBD

Security Features

Access Control

  • DEFAULT_ADMIN_ROLE: Full protocol control
  • PAUSER_ROLE: Emergency pause functions
  • Order creators can only cancel their own orders
  • Vaults are owned by order creators

Reentrancy Protection

All external functions that transfer tokens use reentrancy guards:

modifier nonReentrant() {
    _guardCounter += 1;
    uint256 localCounter = _guardCounter;
    _;
    require(localCounter == _guardCounter);
}

Price Feed Validation

  • Chainlink Data Streams verification
  • Freshness checks on price data
  • Tolerance limits for feed timestamps

Pause Mechanism

modifier whenOrderCreateNotPaused() {
    if (isCreateOrderPaused) revert CreateOrderPaused();
    _;
}

modifier whenOrderFillNotPaused() {
    if (isFillOrderPaused) revert FillOrderPaused();
    _;
}

Integration Examples

Creating an Order

// 1. Approve tokens
IERC20(tokenIn).approve(dcaDotFun, totalAmount);

// 2. Prepare order arguments
OrderArgs memory args = OrderArgs({
    recipient: msg.sender,
    tokenIn: USDC,
    tokenOut: WETH,
    spendAmount: 100e6, // 100 USDC
    repeats: 52, // Weekly for a year
    freqInterval: 7 days,
    scalingInterval: 1 days,
    slippage: 100, // 1%
    firstExecution: 0,
    stakeAssetIn: true,
    stakeAssetOut: false
});

// 3. Create order
uint256 orderId = dcaDotFun.createOrder(args, priceReports);

Filling an Order

// 1. Get quote from API
bytes memory encodedData = getQuoteFromAPI(orderId);

// 2. Fill order
dcaDotFun.fillOrder(encodedData, msg.sender);

Using Callbacks

contract MyFiller is IFillOrderCallback {
    function fillWithCallback(bytes calldata encodedData) external {
        dcaDotFun.fillOrder(
            encodedData,
            address(this), // callback
            msg.sender,     // initiator
            msg.sender      // recipient
        );
    }

    function fillOrderCallback(
        address tokenOut,
        uint256 amountOfTokenOut,
        address initiator
    ) external returns (bool) {
        // Custom logic here
        // 1. Receive tokenIn from protocol
        // 2. Execute swap on DEX
        // 3. Approve tokenOut to protocol
        return true;
    }
}

Gas Optimization

The protocol uses several techniques to minimize gas costs:

  1. Clone Pattern: Vaults deployed as minimal proxies
  2. Packed Storage: Order struct optimized for storage
  3. Immutable Variables: Common addresses in bytecode
  4. Batch Operations: Cancel multiple orders at once

Gas Costs (Estimated)

OperationGas Cost
Create Order~300,000
Fill Order~150,000
Cancel Order~100,000

Audits

  • Audit Report #1: Coming Soon
  • Audit Report #2: Coming Soon

Source Code

The complete DCA.fun smart contract source code is publicly available on GitHub:

🔗 github.com/DCADOTFUN/dcaDotFun-contracts

The repository includes:

  • Complete Solidity source code for all contracts
  • Comprehensive test suite with Foundry
  • Deployment scripts and configurations
  • Development environment setup
  • API documentation and examples

You can also view verified contracts on block explorers: