A decentralized Ethereum-based prediction market using AI agents, Pyth Oracle, and PYUSD.
Fatecast is a decentralized social prediction market platform built on Ethereum that enables users to bet on future events using cryptocurrency. It’s a sophisticated Web3 application that combines smart contracts, AI automation, and real-world data feeds.
What It Does
At its core, Fatecast allows users to:
• Create prediction markets for YES/NO questions about future events (e.g., “Will BTC reach $100,000 by November 1, 2025?”)
• Place bets using PYUSD (PayPal USD stablecoin) on their predictions
• Automatically resolve events using real-world data from Pyth Oracle
• Claim winnings when their predictions are correct
Key Components
Smart Contract (Solidity) - Handles bets, funds, and event resolution on Ethereum
ASI Agent (TypeScript) - AI bot that automatically creates and resolves prediction events
Frontend (Next.js) - Web interface for users to browse and bet
Pyth Oracle - Provides real-world crypto price data for trustless resolution
Farcaster Integration - Social sharing features
Use Cases
Crypto Price Predictions: Bet on whether Bitcoin, Ethereum, or Solana will reach certain price targets
Time-based Events: Create markets with specific deadlines for resolution
Decentralized Decision Markets: Leverage crowd wisdom for predictions
Social Betting: Share predictions via Farcaster with the community
Core Architecture
I. Smart Contract Layer (Solidity) The heart of Fatecast is the PredictionMarket.sol contract built with Foundry and Solidity 0.8.20. Key technical decisions:
Technology Stack:
Contract Design Pattern:
struct Event {
    uint256 id;
    string question;
    bytes32 pythFeedId;        // Links to Pyth oracle
    int64 targetPrice;          // Price threshold for resolution
    uint256 deadline;
    uint256 totalYes;           // Pool tracking
    uint256 totalNo;
    uint256 totalPool;
    bool resolved;
    bool outcome;
    address creator;
    uint256 createdAt;
}
Clever Implementation Details:
Dual Authorization Pattern: The contract uses onlyOwnerOrAgent modifier, allowing both the contract owner and an authorized ASI agent to create events - enabling trustless automation while maintaining emergency admin control.
Oracle Integration: The _getPythPrice() function uses low-level staticcall to fetch prices from Pyth, with manual assembly for data extraction:
(bool success, bytes memory data) = pythOracle.staticcall(
    abi.encodeWithSignature("getPrice(bytes32)", feedId)
);
// Assembly parsing for MockPyth compatibility
assembly {
    price := mload(add(data, 32))
}
Active Event Tracking: Uses a dynamic array activeEventIds[] that's pruned on resolution to optimize gas for event queries - a pragmatic approach to on-chain data management.
Proportional Payout System: Winners receive (userBet / winningPool) * totalPool, ensuring fair distribution without requiring complex AMM mathematics.
II. ASI Agent Backend (TypeScript/Node.js) The automation layer is built with TypeScript and ethers.js v6, featuring a sophisticated event lifecycle manager:
Architecture Pattern:
asi-agent/
├── src/
│   ├── index.ts           # Main orchestrator with cron scheduling
│   ├── eventCreator.ts    # Event generation logic
│   ├── eventResolver.ts   # Resolution monitoring
│   └── utils/
│       ├── contracts.ts   # Contract instances & ABIs
│       ├── pyth.ts       # Pyth API integration
│       └── logger.ts     # Winston logging setup
Notable Technical Implementations:
export async function fetchPythPrice(feedId: string): Promise<PythPrice | null> {
  const url = `${config.pythHermesUrl}/api/latest_price_feeds?ids[]=${feedId}`;
  const response = await axios.get<PythPrice[]>(url);
  // Price formatting with exponential notation
  const price = parseInt(priceData.price.price);
  const expo = priceData.price.expo;
  return price * Math.pow(10, expo);
}
for (let i = 0; i < maxRetries; i++) {
  try {
    const priceData = await fetchPythPrice(feedId);
    if (priceData) return formatPythPrice(priceData);
  } catch (error) {
    await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
  }
}
cron.schedule(cronSchedule, async () => {
  await createPredictionEvent();
});
startResolutionMonitor(config.eventResolutionInterval);
let eventsCreatedToday = 0;
let lastResetDate = new Date().toDateString();
// Resets automatically on date change
Frontend (Next.js 16 + React 19)
III. Modern React stack with Web3 integration:
Integration Highlights:
Particularly Hacky/Notable Solutions
Mock vs. Real Pyth Oracle Compatibility The contract's _getPythPrice() function uses assembly to handle both MockPyth (for testing) and real Pyth oracle responses - a pragmatic hack avoiding complex interface implementations.
Int64 Price Conversion Pyth uses int64 with 8 decimal precision, requiring careful conversion:
export function toPythInt64(price: number): bigint {
  return BigInt(Math.floor(price * 1e8));
}
function _removeFromActiveEvents(uint256 eventId) internal {
    for (uint256 i = 0; i < activeEventIds.length; i++) {
        if (activeEventIds[i] == eventId) {
            activeEventIds[i] = activeEventIds[activeEventIds.length - 1];
            activeEventIds.pop();
            break;
        }
    }
}
PYUSD Integration on Sepolia Uses PayPal's PYUSD stablecoin on Sepolia testnet (0x...) with ERC20 standard interface - innovative choice for a stablecoin prediction market.
Deployment Artifacts as Configuration The agent reads deployment addresses from JSON files rather than hardcoding:
const deploymentFile = vm.readFile("deployments/deployment-11155111.json");
const marketAddress = vm.parseJsonAddress(deploymentFile, ".contracts.PredictionMarket");

