Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
LABS
Guides

How to Architect for Conditional and Time-Based Intents

A technical guide on designing systems to process user intents that execute when specific on-chain or off-chain conditions are met or at predetermined times.
Chainscore © 2026
introduction
ARCHITECTURE GUIDE

Introduction to Conditional and Time-Based Intents

Learn how to design smart contracts and dApps that execute actions automatically based on specific conditions or time schedules.

Conditional and time-based intents are programmable logic statements that define when and under what circumstances a blockchain transaction should be executed. Unlike a standard transaction sent by a user, an intent is a declaration of a desired outcome (e.g., "swap 1 ETH for USDC if the price is above $3,500"). The execution is then delegated to a network of specialized actors, often called solvers or fillers, who compete to fulfill the condition at the best possible terms. This shifts the user's role from an active executor to a declarative specifier of goals.

Architecting for these intents requires a clear separation between the intent expression layer and the execution layer. The expression layer, typically a smart contract or a signed off-chain message, defines the logic using predicates. Common condition types include: price thresholds (e.g., using Chainlink oracles), time locks (e.g., block.timestamp > 1740000000), state changes (e.g., a specific NFT being listed), and multi-party approvals. The execution layer, often a separate network or keeper system, continuously monitors the blockchain state for matching conditions and submits the fulfilling transaction.

A core architectural challenge is managing intent lifecycle and revocation. Since an intent may not be fulfilled immediately, the system must handle user cancellation, expiration, and fund escrow securely. A common pattern is for users to sign an intent message and approve token spending to a dedicated intent contract. This contract holds the logic to validate the fulfillment conditions and release funds only when they are met. Projects like Anoma, CowSwap, and UniswapX employ variations of this escrow-based architecture for their intent-centric systems.

For developers, implementing a basic time-based intent is straightforward. The following Solidity snippet shows a contract that allows a user to schedule a token transfer for a future block timestamp:

solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

contract TimeLockTransfer {
    mapping(address => mapping(address => ScheduledTransfer)) public schedules;

    struct ScheduledTransfer {
        uint256 amount;
        uint256 executeAfter;
        bool executed;
    }

    function scheduleTransfer(address token, uint256 amount, uint256 delay) external {
        IERC20(token).transferFrom(msg.sender, address(this), amount);
        schedules[msg.sender][token] = ScheduledTransfer({
            amount: amount,
            executeAfter: block.timestamp + delay,
            executed: false
        });
    }

    function executeScheduledTransfer(address token) external {
        ScheduledTransfer storage st = schedules[msg.sender][token];
        require(block.timestamp >= st.executeAfter, "Time lock not expired");
        require(!st.executed, "Already executed");
        st.executed = true;
        IERC20(token).transfer(msg.sender, st.amount);
    }
}

This contract escrows tokens and only releases them after the specified time has passed, demonstrating the core principle of conditional execution.

When designing more complex conditional logic, especially for DeFi, integrating decentralized oracles is critical. For a limit order intent ("sell if price >= X"), your contract must trust an oracle like Chainlink Data Feeds to provide the current market price. The execution function would include a check: require(chainlinkFeed.latestAnswer() >= targetPrice, "Condition not met"). It's vital to architect for oracle latency and potential manipulation, often by using time-weighted average prices (TWAPs) or requiring multiple confirmations before execution.

The future of intent-based architecture points towards cross-chain conditional execution. With protocols like Axelar and Chainlink CCIP, an intent can specify conditions across multiple blockchains (e.g., "bridge funds from Ethereum to Arbitrum once gas fees on Arbitrum fall below 0.05 gwei"). This requires a messaging layer that can verify remote conditions and trigger actions on a destination chain. As this space evolves, standardization of intent schemas (e.g., via EIPs) will be key for interoperability between different solvers and execution networks.

prerequisites
PREREQUISITES AND CORE CONCEPTS

How to Architect for Conditional and Time-Based Intents

Intent-based architectures enable users to declare desired outcomes, not manual steps. This guide covers the core concepts for designing systems that execute intents based on conditions and time.

An intent is a declarative statement of a user's desired outcome, such as "swap 1 ETH for the best possible price across DEXs within 5 minutes." Architecting for conditional and time-based intents requires a shift from transaction-based to outcome-based thinking. The core components are the user, who signs an intent, a solver network (like SUAVE or Anoma), which competes to fulfill it, and an execution environment that enforces the declared constraints. This separation of declaration and execution is fundamental to intent-centric design.

Conditional intents add logical predicates that must be true for execution. These are expressed as if-then statements within the intent's parameters. Common conditions include: - Oracle-based: "If the ETH price on Chainlink is above $3,500, then..." - On-chain state: "If my account's USDC balance exceeds 1,000, then..." - Cross-chain: "If a specific transaction is confirmed on Arbitrum, then..." Architecturally, this requires a verifiable condition evaluator, often an oracle or a light client, that the solver can query to prove the condition was met before proceeding.

Time-based intents introduce temporal constraints, which are critical for limit orders, vesting schedules, and recurring payments. These are not just simple block number checks. Key concepts include: - Deadlines: "Execute before block 20,000,000 or cancel." - Validity windows: "Execute only between 2 PM and 4 PM UTC." - Recurring schedules: "Execute this swap every Friday." Implementing these requires a reliable time source, which can be a blockchain's native timestamp (for approximate time) or a decentralized oracle like Chainlink's Time API for precise, cross-chain coordination.

The architectural challenge is ensuring atomicity—the entire intent either executes fully with all conditions met or fails without partial state changes. This is typically achieved through a commit-reveal or conditional transaction pattern. For example, a solver might submit a transaction with the condition check as a precompile, or use a specialized smart contract wallet (like Safe{Wallet} with modules) that only releases a signed payload once an off-chain verifier attests the condition is satisfied.

To design such a system, start by defining the intent schema. A simplified JSON structure might include fields for type, deadline, conditions (an array of predicate objects), and actions (an array of calldata to execute). Your backend must then route this intent to a solver network via a standard interface like the ERC-4337 UserOperation for account abstraction or a dedicated intent pool. The solver's job is to find the optimal execution path that satisfies all constraints before the deadline.

Finally, consider security and failure modes. What happens if an oracle reports incorrect data for a condition? How are solvers incentivized to handle time-sensitive intents reliably? Architectures should include contestation periods and solver bonds to penalize bad actors, and use multiple oracle feeds for critical conditions. By understanding these prerequisites—declarative intents, condition evaluation, time sources, atomic execution, and incentive security—you can build robust systems for the next generation of user-centric blockchain applications.

system-architecture-overview
CONDITIONAL AND TIME-BASED INTENTS

System Architecture Overview

Designing systems that can execute complex, multi-step transactions based on future conditions requires a specific architectural approach. This guide outlines the core components and patterns for building robust intent-based architectures.

An intent-based architecture shifts the paradigm from explicit transaction execution to declarative outcome specification. Instead of signing a transaction to swap 1 ETH for USDC on Uniswap V3, a user expresses an intent: "I want to acquire USDC for my ETH if the price reaches $3,500." The system's role is to fulfill this intent by constructing and executing the necessary transactions when conditions are met. This requires separating the intent expression layer, where users define goals, from the solver network, which competes to find optimal execution paths, and the execution layer, which carries out the transaction.

Conditional logic is implemented through oracles and keepers. For price-based conditions, decentralized oracle networks like Chainlink provide reliable, tamper-proof price feeds that your smart contracts can trust. Time-based conditions are typically managed by keeper networks such as Chainlink Automation or Gelato, which monitor your contract's state and trigger functions when a specific block timestamp or time interval is reached. Your architecture must integrate these services as external dependencies, designing your core contracts to be oracle-ready and keeper-compatible with clear, permissioned functions for triggering.

The core of the system is the intent contract. This smart contract holds the user's signed intent, the pledged funds (often in escrow), and the fulfillment logic. It must be designed for gas efficiency and security. Use a factory pattern (e.g., an IntentFactory.sol) to deploy minimal proxy contracts for each user intent, keeping state isolated and reducing deployment costs. The contract should expose a checkConditions function that oracles or keepers can call, and a fulfill function that only an approved solver can execute once conditions are verified. Implement reentrancy guards and access controls rigorously.

A critical challenge is handling intent lifecycle management. Intents can be in states like Pending, ReadyForFulfillment, Fulfilled, Cancelled, or Expired. Your architecture needs a reliable way to update and track these states. Consider using events for off-chain indexing (with tools like The Graph) and implementing time-locked cancellation functions that allow users to withdraw funds if a solver hasn't begun execution. For complex intents spanning multiple blocks, consider a commit-reveal scheme or state channels to manage interim states securely.

Finally, design for composability and failure. Intents may fail due to slippage, insufficient liquidity, or changing network conditions. Your architecture should include fallback handlers and partial fulfillment logic where possible. For example, if a DEX swap fails, the contract could route through a different DEX or return funds minus a penalty. Use established libraries like OpenZeppelin for security primitives and thoroughly test all condition paths, including edge cases like oracle downtime or keeper network congestion, using frameworks like Foundry or Hardhat.

core-components
CONDITIONAL & TIME-BASED INTENTS

Core Architectural Components

Building systems that execute actions based on logic or schedules requires specific architectural patterns. These components form the foundation for advanced automation in DeFi and on-chain applications.

ARCHITECTURAL COMPARISON

Condition Types: On-Chain vs Off-Chain vs Time

A comparison of condition types used to trigger intent execution, detailing their trust assumptions, latency, and typical use cases.

Feature / MetricOn-Chain ConditionOff-Chain ConditionTime-Based Condition

Trigger Source

Blockchain State (e.g., Uniswap pool price)

Oracle API, Keeper Network, User Input

Block Timestamp or Unix Epoch

Trust Assumption

Trustless (cryptographically verifiable)

Trusted (relies on oracle/keeper honesty)

Trustless (consensus-enforced)

Execution Latency

1-12 seconds (per block)

< 1 second (off-chain)

Precise to the block

Gas Cost for Verification

High (on-chain computation)

None to Low (off-chain signed data)

Low (simple timestamp check)

Censorship Resistance

Example Use Case

"Swap if ETH price on Uniswap > $4000"

"Mint NFT if team wallet holds > 1000 ETH"

"Release funds on January 1, 2025"

Implementation Complexity

Medium (requires on-chain logic)

High (requires oracle integration & signatures)

Low (native EVM opcode)

Common Protocols

Chainlink Data Feeds, Uniswap V3 TWAP

Pyth Network, Gelato, Keep3r

Native Solidity, OpenZeppelin Timelock

oracle-integration-patterns
ARCHITECTURE

Oracle Integration Patterns for Condition Checking

Designing smart contracts that react to external conditions requires robust oracle integration. This guide covers patterns for implementing conditional and time-based intents.

Conditional intents allow smart contracts to execute logic based on real-world data, such as market prices, weather events, or sports scores. Unlike simple function calls, these intents are declarative: they specify a desired outcome ("sell if ETH > $3500") rather than the exact transaction steps. To fulfill these intents, contracts rely on oracles—services that provide verified external data on-chain. The core architectural challenge is securely and efficiently integrating these data feeds to trigger contract execution only when predefined conditions are met.

The most common pattern is the Pull-based Oracle Check. Here, a contract stores an intent with its condition. An external keeper or relayer service periodically calls a function like checkAndExecute(). This function fetches the latest price from an oracle like Chainlink (AggregatorV3Interface) and executes the intent logic if the condition passes. This pattern is gas-efficient for the user but requires a trusted or incentivized off-chain actor. It's ideal for non-time-sensitive conditions where latency of a few minutes is acceptable.

For time-based conditions, developers often use a Scheduled Execution pattern. Combine a pull-based oracle check with a time trigger using block timestamps or dedicated scheduler contracts like Gelato Network or Chainlink Automation. For example, a contract could be programmed to check if a user's DAI balance on Aave has reached a certain threshold every week. The scheduler calls the contract, which then pulls the necessary data from the appropriate oracle and executes a withdrawal if the condition is true. This decouples the timing mechanism from the data verification.

A more advanced and secure pattern is the Push-based Oracle with Callback. Oracles like Chainlink Data Feeds (in decentralized oracle networks) can be configured to call your contract directly when a condition is met on their end. You implement a function like fulfill(bytes32 requestId, uint256 price) that contains your execution logic. While this can reduce latency, it requires careful contract design to handle the callback, manage request IDs, and protect against duplicate executions. This pattern is well-suited for high-frequency trading conditions or real-world event triggers.

When architecting these systems, key considerations include data freshness, source reliability, and cost. Using a decentralized oracle network (DON) mitigates single points of failure. Always verify the oracle address on-chain and implement circuit breakers or fallback oracles for critical logic. For production systems, audit the oracle's data quality and update frequency to ensure it matches your application's needs. Testing with oracle mock contracts in your development environment is essential.

To implement a basic pull-based check with Chainlink, your contract would inherit AggregatorV3Interface. Store the user's intent parameters, and create a permissioned executeIntent function that calls latestRoundData() to get the current price. Compare it to the condition and proceed with the core logic. Remember to handle edge cases like stale data by checking the updatedAt timestamp. This pattern forms the foundation for most DeFi conditional orders, limit orders, and automated portfolio management strategies.

time-based-scheduling
INTENT ARCHITECTURE

Implementing Time-Based Scheduling

This guide explains how to design smart contracts and off-chain agents that execute actions based on time conditions, a core component of user intents.

Time-based scheduling allows decentralized applications to automate actions like recurring payments, token vesting, or limit orders without requiring the user to manually sign a transaction each time. This is achieved by separating the intent declaration (the user's signed permission for a future action) from the execution trigger (the condition of a specific time being reached). Architecturally, this requires an off-chain solver or keeper network that monitors the blockchain state and submits the pre-authorized transaction when the condition is met.

The foundation is a smart contract that stores the user's intent. This contract must include the target function, calldata, and a timestamp or block number for execution. Crucially, the user signs a message approving this future call. The contract verifies this signature upon execution, ensuring only the authorized action runs at the specified time. A basic Solidity structure includes a mapping of scheduled calls and a function, executable by anyone, that checks block.timestamp >= scheduledTime and calls the target.

For reliable execution, you need an off-chain component. A keeper service like Chainlink Automation or Gelato Network polls your contract for pending time-based intents. When the condition is satisfied, the keeper calls the contract's execute function, paying the gas fee. You must design your contract to be keeper-compatible: execution should be permissionless and revert with a clear reason if conditions aren't met (e.g., NotReady or AlreadyExecuted). This pattern shifts gas costs and reliability concerns to specialized networks.

Advanced scheduling involves conditional time locks. For example, a user's intent might be "swap 1 ETH for USDC if the price is above $2000, but only after January 1st." This combines an oracle-based price check with a time delay. Implement this by having the execution function validate both the timestamp and call an oracle like Chainlink to verify the market condition. The intent is only fulfilled if all conditions in the logical AND statement are true at the moment of execution.

When architecting these systems, consider security and state. Use a nonce or unique ID for each scheduled intent to prevent replay attacks. Ensure the contract handles failed executions gracefully—if a keeper's transaction reverts due to temporary conditions (e.g., slippage), the intent should remain executable for a time window (like 24 hours) to allow retries. For complex sequences, consider frameworks like the Ethereum Alarm Clock or OpenZeppelin's TimelockController for governance, but adapt their patterns for generalized user intents.

watchtower-networks
ARCHITECTURE GUIDE

Designing Watchtower Networks

A technical guide to building watchtower networks that monitor and execute conditional and time-based intents on-chain.

A watchtower network is a decentralized system of off-chain nodes designed to monitor blockchain state and execute predefined actions when specific conditions are met. Unlike simple transaction relays, these networks are architected for conditional intents (e.g., "sell if price drops below $X") and time-based intents (e.g., "execute this swap in 24 hours"). The core challenge is ensuring reliable, censorship-resistant execution without introducing central points of failure. Key architectural components include a condition evaluator, a transaction signer, and a redundant node network.

The first architectural decision is the condition evaluation layer. Conditions can be on-chain (monitoring a Uniswap V3 pool's price via a Chainlink oracle), off-chain (checking an API for a specific event), or time-based (using a secure clock service). For on-chain conditions, watchtowers must efficiently poll or subscribe to events via RPC providers like Alchemy or Infura. For complex logic, a zk-proof or oracle network like Pyth or API3 may be required to attest to the condition's truth before execution is authorized.

Execution reliability demands a fault-tolerant network design. A naive single-node watchtower risks downtime or censorship. Instead, architect a federated or staked node network using a framework like Cosmos SDK or Substrate. Nodes can be incentivized to monitor the same intent via a stake-slashing mechanism; if a node fails to execute when conditions are met, its stake is penalized. Redundancy is achieved by having multiple nodes independently verify conditions and broadcast the execution transaction, with the first successful one claiming a reward.

Security is paramount, especially for managing private keys. The signing mechanism should never expose a plaintext key. Solutions include using multi-party computation (MPC) libraries like tss-lib for distributed key generation and signing, or smart contract wallets (Safe, Argent) where the watchtower triggers a transaction from a contract via a signed meta-transaction. For time-locks, integrate with a decentralized sequencer like Chainlink Automation or a sufficiently decentralized validator set to provide a robust time source.

Here is a simplified conceptual flow for a staked watchtower network handling a conditional limit order:

solidity
// 1. User submits signed intent to network
struct LimitOrderIntent {
    address user;
    address sellToken;
    uint256 sellAmount;
    uint256 priceTarget;
    uint256 expiry;
}
// 2. Watchtower nodes monitor the DEX price feed.
// 3. When priceTarget is met, nodes compete to submit proof.
// 4. Winning node submits execution tx to a settlement contract.

The settlement contract verifies the price proof and the node's stake before transferring funds and paying the node a fee.

When architecting your network, consider cost, latency, and finality. Ethereum mainnet monitoring is expensive; consider layer-2 solutions like Arbitrum or Optimism for condition evaluation. Use event streaming over WebSockets for low-latency alerts instead of polling. Ultimately, a well-designed watchtower network transforms passive user intents into active, guaranteed executions, forming a critical piece of infrastructure for autonomous DeFi and on-chain automation.

expiration-revocation
ARCHITECTURE GUIDE

Handling Intent Expiration and User Revocation

Designing robust intent-based systems requires explicit handling of state changes. This guide covers architectural patterns for managing conditional logic, time-based expiration, and user-initiated revocation.

In intent-centric architectures, an intent is a signed declaration of a user's desired outcome, not a direct transaction. Unlike a standard transaction that executes immediately, an intent is a conditional promise that must be fulfilled by a solver network. This introduces two critical states that your system must manage: the intent becoming invalid after a deadline (expiration) and the user withdrawing their permission before fulfillment (revocation). Failure to handle these states correctly can lead to wasted gas, failed settlements, and poor user experience.

Architecturally, intent expiration is typically implemented using a time-lock or deadline parameter. When a user submits an intent, they include a validUntil timestamp. Your smart contract or off-chain solver must check this condition before attempting fulfillment. For example, in a cross-chain swap intent, the contract would revert if block.timestamp > intent.deadline. A common pattern is to store intents in a mapping with their expiry, allowing periodic cleanup of stale entries to save on-chain storage costs. Off-chain, solvers should filter their search to only consider intents that are still within their validity window.

User revocation is a more active state change. The standard mechanism is for the intent object to specify a revocation nonce or to be mapped to a user's master nonce contract, like those used by EIP-3009 or EIP-3074. When a user wants to cancel an intent, they submit a revocation transaction that increments their nonce. Your fulfillment contract must then validate that the intent's nonce matches the user's current on-chain nonce; if it's lower, the intent is considered revoked. This design separates revocation signaling from the intent object itself, providing a gas-efficient way to invalidate multiple pending intents with a single transaction.

For complex conditional intents—such as "swap X for Y if the price is below Z"—your architecture needs an oracle or data feed dependency. These intents expire not just by time, but by condition failure. The fulfillment logic must query the oracle at execution time and revert if the condition is unmet. It's crucial that your system's timeout (expiration) is shorter than the oracle's data freshness guarantee to avoid executing on stale, inaccurate data. Using a decentralized oracle network like Chainlink provides cryptographically signed data that can be trustlessly verified within your contract's condition check.

Implementing these patterns requires careful state management. A recommended approach is to use an intent status enum (e.g., PENDING, FULFILLED, EXPIRED, REVOKED). Upon any state change, emit an event for off-chain indexers. This allows your frontend and solver network to update their views efficiently without polling. For example:

solidity
event IntentStatusUpdated(bytes32 indexed intentHash, Status newStatus, address indexed solver);

Always perform status checks (require(intent.status == Status.PENDING)) at the start of your fulfillment function as a guard against replay attacks and state inconsistencies.

In practice, integrate these checks into a modular architecture. The fulfillment flow should sequentially validate: 1) intent signature, 2) nonce for revocation, 3) timestamp for expiration, and 4) any custom conditions. Libraries like OpenZeppelin's SignatureChecker and EIP-712 utilities for structured data hashing are essential. By baking expiration and revocation into your core protocol logic, you create a more resilient and user-friendly system that aligns with the declarative nature of intents, giving users control while providing clear boundaries for solver operations.

CONDITIONAL & TIME-BASED INTENTS

Frequently Asked Questions

Common developer questions about architecting for conditional and time-based intents, covering design patterns, troubleshooting, and best practices.

A conditional intent executes based on a verifiable on-chain state, such as a specific token price on an oracle or a governance vote outcome. Its execution is triggered by an external condition being met. A time-based intent executes at or after a specific block number or timestamp, regardless of external state. The key architectural difference is the trigger source: conditionals rely on external data (e.g., Chainlink, Pyth), while time-based intents rely on the blockchain's internal clock.

For example:

  • Conditional: "Swap 1 ETH for USDC if the ETH price falls below $3,000."
  • Time-based: "Claim my staking rewards every 30 days, starting from block #20,000,000."
conclusion-next-steps
ARCHITECTING INTENTS

Conclusion and Next Steps

This guide has explored the core patterns for building conditional and time-based intents. The next step is to integrate these concepts into a production-ready application.

You now understand the architectural components for conditional intents: the intent expression (the user's desired outcome), the condition evaluator (a smart contract or oracle that checks on-chain state), and the execution layer (a solver or keeper network that fulfills the intent). For time-based logic, you can leverage EVM block timestamps, Chainlink Keepers, or Gelato Network to trigger actions. The key is decoupling the intent declaration from its fulfillment, enabling complex, multi-step workflows.

To implement this, start by defining your intent schema using a standard like EIP-712 for signed typed data. Your off-chain service should listen for these signed intents. Use a condition contract, such as a simple require(block.timestamp >= unlockTime, "Not yet"); check, that your solver queries before execution. For more complex conditions, integrate with Chainlink Data Feeds or Pyth Network for price data, or use The Graph to index and query historical state. Always include a validity window and revocation mechanism to prevent stale intents from being executed.

Consider security at every layer. Use signature replay protection with unique nonces or domain separators. Your condition contracts should be pausable and upgradeable using transparent proxy patterns. For time-based triggers, account for block timestamp manipulation by miners; using a decentralized oracle network like Chainlink provides more robust and tamper-resistant timekeeping. Audit the gas costs of your condition checks, as expensive evaluations will make your intents economically unviable for solvers.

The next evolution is moving towards generalized intent architectures. Explore frameworks like Anoma, SUAVE, or CoW Swap's solver competition, which abstract away the solver layer. Alternatively, build on existing infrastructure: Safe{Wallet} modules can act as condition evaluators, and OpenZeppelin Defender can manage automated time-based executions. The goal is to create a system where users express what they want, not how to achieve it, unlocking more sophisticated DeFi strategies, automated treasury management, and cross-chain asset workflows.

For hands-on practice, fork and experiment with these repositories: the Gelato Functions examples for serverless condition checking, OpenZeppelin's Defender Autotasks for scheduled transactions, and Uniswap's Permit2 + EIP-712 integration for intent signing patterns. The future of user interaction in Web3 is intent-centric. By mastering these conditional and time-based patterns, you are building the foundational logic for the next generation of autonomous, user-centric applications.

How to Architect Conditional and Time-Based Intents | ChainScore Guides