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

Launching a Cross-Chain Fundraising Campaign with Time-Locked Releases

A technical guide to implementing a cross-chain fundraising campaign where capital is held in escrow and released to the project team only upon verified milestone completion, using smart contracts and oracles.
Chainscore © 2026
introduction
TUTORIAL

Introduction to Cross-Chain Milestone Fundraising

A guide to structuring and launching a token sale that distributes funds across multiple blockchains and releases them based on project milestones.

Cross-chain milestone fundraising is a capital formation model that combines two powerful concepts: multi-chain token distribution and conditional fund release. Instead of a single, one-time token sale on one blockchain, projects launch a coordinated campaign across multiple networks like Ethereum, Solana, and Polygon. The raised capital is not delivered to the project team all at once. Instead, it is held in a secure, programmable escrow contract and released in tranches only after pre-defined, verifiable development milestones are achieved. This structure aligns investor and builder incentives, reducing the risk of fund mismanagement.

The technical architecture relies on smart contracts deployed on each supported chain. A primary controller contract, often on a hub chain like Ethereum or a dedicated appchain, defines the global fundraising parameters: total raise cap, token price, supported payment tokens (e.g., ETH, USDC, SOL), and the milestone schedule. Separate sale contracts on each target chain handle local contributions. These contracts use cross-chain messaging protocols like Axelar's GMP, LayerZero, or Wormhole to relay contribution data and milestone completion proofs back to the controller, ensuring a unified state across all chains.

Setting up a campaign involves several key steps. First, define clear, objective milestones (e.g., "Mainnet V1 Launch," "10,000 Active Users") that can be verified on-chain or via trusted oracles. Next, deploy the smart contract suite, configuring the milestone release schedule and fund allocation. For example, a campaign might release 20% of funds upon completion of the first milestone, 30% for the second, and the final 50% for the third. Contributors interact with the sale contract on their preferred chain, receiving a claimable receipt token representing their future allocation of the project's native token.

Here is a simplified code snippet illustrating a milestone release condition in a Solidity escrow contract:

solidity
function releaseFunds(uint256 milestoneIndex) public onlyOwner {
    require(milestoneIndex < milestones.length, "Invalid milestone");
    Milestone storage m = milestones[milestoneIndex];
    require(!m.isReleased, "Already released");
    require(m.verifier.verifyCompletion(), "Milestone not complete"); // Calls an oracle or verification contract
    
    uint256 amountToRelease = (totalRaised * m.releasePercentage) / 100;
    m.isReleased = true;
    
    (bool success, ) = treasury.call{value: amountToRelease}("");
    require(success, "Release failed");
}

The verifier contract could check for a specific on-chain event or a signed attestation from a committee.

This model offers significant advantages. For investors, it provides transparency and security, as funds are only disbursed for proven progress. For project teams, it demonstrates credibility and long-term commitment, potentially attracting more serious backers. It also enables broader participation by lowering barriers for users on different blockchains who prefer to transact in their native ecosystem assets. Successful implementations can be seen in projects like Axie Infinity's community treasury and various DAO funding rounds that use platforms like Llama for stream-based payments.

When planning a campaign, consider gas costs for cross-chain messages, the finality times of connected chains, and the security of the chosen interoperability protocol. Always conduct thorough audits on all contracts, especially the cross-chain logic and escrow mechanisms. This fundraising model represents an evolution toward more accountable, efficient, and accessible capital formation in the Web3 space, moving beyond simple initial coin offerings (ICOs) to structured, performance-based financing.

prerequisites
CROSS-CHAIN FUNDRAISING

Prerequisites and System Architecture Overview

This guide outlines the technical foundation required to build a secure, cross-chain fundraising campaign with automated, time-locked token releases.

Before deploying a cross-chain fundraising campaign, you must establish a secure development environment and understand the core architectural components. Essential prerequisites include: a code editor like VS Code, Node.js v18+ and npm/yarn for package management, and a basic understanding of Solidity and JavaScript/TypeScript. You will need testnet ETH/MATIC for deployment and interaction, and wallets such as MetaMask configured for multiple networks (e.g., Ethereum Sepolia, Polygon Amoy). Familiarity with Hardhat or Foundry for smart contract development and testing is also required.

The system architecture for a time-locked, cross-chain campaign is composed of three primary layers. The Smart Contract Layer resides on a primary chain (like Ethereum) and contains the core fundraising logic, including the token sale mechanism and a vesting contract (e.g., using OpenZeppelin's VestingWallet). The Cross-Chain Messaging Layer is responsible for securely communicating release schedules and participant data to secondary chains; this typically involves a protocol like Axelar, Wormhole, or LayerZero. Finally, the Release Execution Layer consists of lightweight receiver contracts on destination chains that hold tokens and execute the scheduled releases based on validated cross-chain messages.

A critical design decision is choosing between a lock-and-mint versus a liquidity pool model for cross-chain token distribution. In a lock-and-mint system, all funds are raised on the main chain, and a canonical token is locked in a vault. Equivalent wrapped tokens are then minted on destination chains and released over time. Alternatively, a liquidity pool model involves pre-bridging a portion of the token supply to destination chains and seeding liquidity pools, allowing for immediate trading post-release. The lock-and-mint model is generally simpler and more secure for controlled, linear vesting schedules.

Security and trust assumptions are paramount. You must audit the entire message flow, as the system's security is only as strong as its weakest link—often the cross-chain messaging protocol. Ensure the vesting contract on the main chain is pausable in case of emergencies and that the receiver contracts on destination chains have strict access controls, allowing only the authorized cross-chain messenger to trigger releases. Always implement a multisig or DAO-controlled admin for contract upgrades and parameter changes to avoid centralization risks.

For development and testing, use a combination of local forked networks and public testnets. Simulate the entire cross-chain flow using the testnet environments of your chosen messaging protocol (e.g., Axelar's testnet galileo). Write comprehensive tests that cover: successful fundraising, failed cross-chain messages, early cancellation scenarios, and the correct calculation of vested amounts over time. Tools like Hardhat Ignition or OpenZeppelin Defender can help automate the deployment and management of this multi-contract, multi-chain system.

key-concepts
IMPLEMENTATION GUIDE

Core Technical Components

To launch a secure, cross-chain fundraising campaign with time-locked releases, you need to integrate several key technical components. This guide covers the essential building blocks.

05

Fund Distribution & Claim Mechanisms

Design a secure process for contributors to claim their tokens post-fundraise. Avoid airdropping large sums to EOAs; instead, use a claim contract. Contributors interact with this contract to receive their tokens, which are either sent directly or deposited into their vesting schedule. For cross-chain, users may claim on their preferred chain.

Considerations:

  • Merklized Claims: Use a Merkle tree to prove inclusion in the allowlist efficiently.
  • Gas Fees: Sponsor gas for claims or use a meta-transaction relayer.
  • UI/UX: Provide a simple frontend for users to connect their wallet and claim.
contract-design
ARCHITECTURE

Step 1: Designing the Smart Contract System

The foundation of a secure cross-chain fundraising campaign is a modular smart contract system. This step outlines the core components and their interactions.

A robust cross-chain fundraising system requires multiple smart contracts working in concert. The primary components are a Vault contract to hold raised funds, a Release Scheduler to manage time-locked distributions, and a Cross-Chain Messaging adapter. The Vault is deployed on the fundraising chain (e.g., Ethereum mainnet), while a corresponding Receiver contract is deployed on each beneficiary chain (e.g., Arbitrum, Polygon). This separation of concerns enhances security and flexibility.

The core logic resides in the Vault.sol contract. It must handle three key functions: accepting contributions in a native token or stablecoin, tracking total funds raised, and enforcing the release schedule. A common pattern is to use a mapping to record each beneficiary's allocated share and a ReleaseSchedule struct to define unlock timestamps and amounts. The contract should reject any direct transfer functions, allowing funds to leave only via the authorized cross-chain release mechanism.

Time-locked releases are managed by the ReleaseScheduler.sol module. This contract stores an array of Release structs, each containing a releaseTime (Unix timestamp) and a percentage or amount. When a release is triggered—either manually by an authorized party or automatically via a keeper—the scheduler calculates the releasable amount and initiates a cross-chain message. It's critical that this logic is immutable once the campaign starts to prevent manipulation.

For cross-chain communication, you must integrate a secure messaging protocol like Axelar, LayerZero, or Wormhole. Your Vault will call the protocol's send function, which includes the destination chain ID, the target Receiver contract address, and the calldata payload (e.g., releaseFunds(beneficiaryAddress, amount)). The payload is executed on the destination chain only after the protocol's decentralized validators verify the message. Always use the protocol's official SDKs for encoding.

Security considerations are paramount. Implement access controls (using OpenZeppelin's Ownable or AccessControl) for administrative functions like setting the schedule. Include a timelock for any critical parameter changes before the campaign goes live. Use checks-effects-interactions patterns to prevent reentrancy. Finally, ensure the contract is pausable in case of an emergency, but design the pause function to not interfere with in-flight cross-chain messages to avoid funds being stuck.

milestone-verification
TIME-LOCKED RELEASE LOGIC

Implementing Milestone Verification

This section details how to implement the on-chain logic that verifies campaign milestones and controls the release of funds from escrow.

Milestone verification is the core mechanism that transforms a simple escrow into a programmable funding schedule. The smart contract must contain logic to accept and validate proof that a predefined project milestone has been completed before releasing the next tranche of funds. This is typically implemented using a releaseFunds function that can only be called by an authorized party—often the project creator—once specific conditions are met. The contract stores the total raised amount, the release schedule (e.g., 30% for Milestone 1, 40% for Milestone 2), and tracks which milestones have already been paid out.

The verification condition itself can be implemented in several ways, each with different trust assumptions. A simple, centralized approach uses an onlyOwner or onlyAdmin modifier, where a designated multisig wallet attests to milestone completion by submitting the transaction. For a more decentralized model, you can integrate with a decentralized oracle network like Chainlink Functions to allow off-chain verification (e.g., checking for a specific GitHub release tag or an on-chain transaction). Another model is community-governed verification, where a snapshot of token holders votes to approve the release. The chosen method should be transparent and documented in the campaign's terms.

Here is a simplified Solidity code snippet illustrating the state variables and function skeleton for a milestone release contract using an admin model:

solidity
contract MilestoneEscrow {
    address public admin;
    uint256 public totalFunds;
    uint256 public currentMilestone;
    mapping(uint256 => uint256) public milestoneAmount; // Milestone index -> payout amount
    mapping(uint256 => bool) public milestoneReleased; // Milestone index -> released status

    constructor(address _admin, uint256[] memory _amounts) {
        admin = _admin;
        // Initialize milestone amounts from _amounts array
        for (uint i = 0; i < _amounts.length; i++) {
            milestoneAmount[i] = _amounts[i];
            totalFunds += _amounts[i];
        }
    }

    function releaseMilestone(uint256 _milestoneIndex) external {
        require(msg.sender == admin, "Unauthorized");
        require(_milestoneIndex == currentMilestone, "Invalid milestone");
        require(!milestoneReleased[_milestoneIndex], "Already released");
        require(address(this).balance >= milestoneAmount[_milestoneIndex], "Insufficient funds");

        milestoneReleased[_milestoneIndex] = true;
        currentMilestone++;
        // Transfer logic to beneficiary goes here
    }
}

For cross-chain campaigns, this verification logic must be deployed on the destination chain where the funds are escrowed. When a backer contributes on Chain A, the bridge protocol locks the tokens and mints a representation on Chain B, which are then deposited into this escrow contract. The milestone verification and release occur entirely on Chain B. Once released, the funds (in the bridged asset) can be used by the project team. If the team needs native assets on another chain, a second bridge transaction would be required, adding complexity and cost. It's crucial to audit the interaction between the bridge protocol's asset representation and your escrow logic to prevent reentrancy or balance accounting errors.

Thorough testing is non-negotiable. Your test suite should simulate the full flow: funding the escrow, attempting unauthorized releases, successfully verifying and releasing sequential milestones, and handling edge cases like insufficient escrow balance. Use a development framework like Hardhat or Foundry to write comprehensive unit and integration tests. For cross-chain simulations, consider using local forking of the destination chain or services like Axelar's testnet or LayerZero's testnet to deploy and test your contract in an environment that mimics mainnet bridge interactions before launch.

cross-chain-integration
IMPLEMENTATION

Integrating Cross-Chain Messaging for Fundraising

This step connects your fundraising smart contracts across multiple blockchains, enabling automated, trustless release of funds based on campaign milestones.

Cross-chain messaging is the core infrastructure that allows your fundraising contract on one chain (e.g., Ethereum) to securely communicate with a vault contract holding funds on another chain (e.g., Arbitrum or Polygon). Instead of manually bridging assets, you use a protocol like Axelar, LayerZero, or Wormhole to send a verifiable message. This message instructs the vault to release a specific amount of tokens to the project's wallet once a predefined condition, like a successful milestone verification, is met. This creates a seamless, automated flow for multi-chain capital deployment.

To implement this, you'll need to write two key smart contract functions. First, a function on your main fundraising contract that, when a milestone is approved, calls the cross-chain messenger. Second, a receive function on the destination vault contract that verifies the incoming message's authenticity. Here's a simplified example using a generic messenger pattern:

solidity
// On Source Chain (Fundraiser)
function releaseMilestoneFunds(uint256 milestoneId, uint256 amount, address vaultOnDestChain) external {
    require(milestoneVerified[milestoneId], "Milestone not met");
    bytes memory payload = abi.encode(milestoneId, amount, msg.sender);
    crossChainMessenger.sendMessage(vaultOnDestChain, payload);
    emit FundsReleased(milestoneId, amount);
}

Security is paramount. You must verify that the message received on the destination chain originates from your authorized fundraiser contract. Never trust arbitrary calls. Each messaging protocol has a specific method for this verification, such as checking a trusted sourceAddress and sourceChain provided by the protocol's Gateway or Endpoint contract. Failing to implement proper access control could allow anyone to drain the vault. Always use the official protocol SDKs and audit your integration thoroughly.

For a Time-Locked Release campaign, the cross-chain message payload should encode the release schedule. Instead of sending the full amount at once, the payload could specify a vesting cliff and a linear release rate. The vault contract on the destination chain would then enforce this schedule, releasing tokens over time directly to the project wallet. This removes the need for the project to manually claim funds and provides transparent, on-chain proof of the release cadence to backers.

When choosing a cross-chain messaging protocol, consider security models (optimistic vs. cryptographic proofs), supported chains, cost, and latency. For high-value fundraising, protocols with robust validator sets like Axelar or Wormhole are recommended. For faster, lower-cost releases between EVM chains, LayerZero or Hyperlane may be suitable. Test your integration extensively on testnets like Sepolia and Arbitrum Sepolia before mainnet deployment.

The final architecture creates a powerful, decentralized fundraising mechanism. Backers lock funds in a vault on their preferred chain. The project team builds and verifies milestones. Upon verification, an automated, trustless message triggers the release of the next tranche of funds across the chain boundary. This reduces administrative overhead, enhances transparency, and unlocks liquidity from any supported blockchain for your project's growth.

SECURITY & COST

Cross-Chain Messaging Protocol Comparison

Comparison of leading protocols for securing cross-chain fund releases, focusing on security models, costs, and finality.

Feature / MetricLayerZeroWormholeAxelarChainlink CCIP

Security Model

Decentralized Verifier Network

Guardian Network (19/33)

Proof-of-Stake Validator Set

Decentralized Oracle Network

Time to Finality

3-5 minutes

~15 seconds

~6 minutes

2-4 minutes

Approx. Gas Cost (Simple Msg)

$2-5

$0.50-1.50

$5-10

$10-20

Native Token Required

Programmable Logic (General Msg)

Time-Lock Condition Support

Maximum Message Size

256 bytes

10 KB

1 MB

Unlimited (off-chain)

Audits & Bug Bounties

deployment-testing
LAUNCH CHECKLIST

Step 4: Deployment, Testing, and Security

This final step covers the critical actions required to securely deploy your cross-chain fundraising contract, verify its functionality, and prepare for the campaign launch.

Before deployment, conduct a final audit of your smart contract code. This includes reviewing the releaseSchedule mapping, the releaseFunds function's access controls, and the integration with the chosen bridge's messaging layer (e.g., Axelar's callContract, Wormhole's sendPayloadToEvm, or LayerZero's send). Ensure the contract's onlyOwner or onlyManager modifiers are correctly applied to all administrative functions. Use static analysis tools like Slither or Mythril to identify common vulnerabilities. For production deployments, consider engaging a professional audit firm; platforms like Code4rena and Sherlock host competitive audit contests.

Deploy your contract to a testnet on both the source and destination chains. For an Ethereum-to-Polygon campaign, you would deploy to Goerli (or Sepolia) and Mumbai. Use the same deployment script with environment-specific RPC URLs and private keys. After deployment, immediately verify and publish the source code on the respective block explorers (Etherscan, Polygonscan). This transparency is crucial for backer trust. Store the deployment addresses and transaction hashes for your records.

Execute a comprehensive, multi-chain test. Simulate the entire campaign lifecycle: a backer sends funds to the contract on Chain A, you (the manager) trigger a scheduled release, and the contract initiates a cross-chain message. Use testnet bridge tokens to validate the transfer to the recipient wallet on Chain B. Test edge cases: what happens if a release is triggered before its timestamp? What if the bridge fails and the receiveMessage function is called with invalid data? Tools like Foundry's forge test with the vm.chainId() cheatcode or Hardhat's network configurations are essential for this stage.

Implement monitoring and emergency procedures. Once live, you must monitor the contract's state and the bridge's status. Set up alerts for key events: FundsDeposited, ReleaseInitiated, FundsReleased. For bridges with a risk of failed messages, understand the governance recovery process. Have a clear, pre-written communication plan for backers in case of technical delays. Security is ongoing; consider implementing a timelock for administrative functions post-launch to provide a safety net against compromised manager keys.

Finally, prepare your frontend and documentation for launch. The dApp interface should clearly display the contract address, the release schedule, the total funds raised, and the bridge being used. Provide a direct link to the verified source code. Educate your community on how cross-chain transactions work, including expected confirmation times and fee estimates. A successful launch depends on both technical robustness and clear communication, ensuring backers understand the innovative, time-locked mechanism securing their funds.

TIME-LOCKED FUNDRAISING

Frequently Asked Questions

Common technical questions and solutions for developers building cross-chain fundraising campaigns with scheduled token releases.

A time-locked release schedule is a smart contract mechanism that automatically distributes tokens to investors or a treasury based on predefined milestones, not a single date. It works by using a vesting contract or token locker (like OpenZeppelin's VestingWallet) that holds the total allocation and releases it linearly or in cliffs.

For a cross-chain campaign, this contract is typically deployed on the fundraising chain (e.g., Ethereum). The release logic is encoded in the contract's state, with functions like release() or vestedAmount(address beneficiary, uint64 timestamp) calculating the available amount. Investors or a DAO treasury can claim their unlocked tokens by calling this function after each vesting period elapses, which is verified on-chain by block timestamp.

conclusion
IMPLEMENTATION SUMMARY

Conclusion and Next Steps

You have now configured a secure, automated fundraising campaign with time-locked token releases across multiple blockchains.

This guide walked through building a cross-chain fundraising campaign using a modular architecture. The core components are a VestingVault contract for time-locked token releases, a CampaignFactory for deployment, and a CrossChainMessenger (like Axelar or LayerZero) to synchronize state. By separating logic, you achieve flexibility and security; the vault holds funds securely, while the messenger handles the trust-minimized communication layer. This pattern is used by protocols like Uniswap Grants and Gitcoin for transparent, scheduled disbursements.

For production deployment, rigorous testing is essential. Use a framework like Foundry or Hardhat to simulate mainnet conditions. Key tests include: verifying vesting schedules calculate correctly, ensuring only the campaign owner can trigger releases, and testing cross-chain message failure scenarios with tools like Axelar's testnet sandbox or LayerZero's testnet. Security audits from firms like OpenZeppelin or CertiK are recommended before locking significant value, especially for custom bridging logic.

To extend this system, consider integrating Chainlink Automation or Gelato Network to trigger release functions automatically when cliff periods expire, removing manual steps. You could also implement a multi-signature requirement for the campaign owner role using a Safe{Wallet} for enhanced security. For analytics, emit standardized events from your contracts and use indexers like The Graph or Covalent to track fundraising progress and token distributions in real-time across all supported chains.

The next step is to deploy your contracts. Start on a testnet like Sepolia or Polygon Amoy. Use a block explorer to verify your contract source code publicly. For the frontend, libraries like wagmi and viem simplify interaction with your contracts across EVM chains. Document your campaign's vesting schedule and cross-chain mechanics clearly for contributors, as transparency builds trust in decentralized fundraising.

How to Launch a Cross-Chain Fundraising Campaign with Time-Locked Releases | ChainScore Guides