Skip to content

kirtiraj22/escrow

Repository files navigation

Solana Escrow Contract using Anchor

A simple escrow contract built using Solana and the Anchor framework. It enables two parties to trustlessly exchange tokens. If the trade is not completed, the maker can reclaim their tokens — ensuring a fair and fail-safe process.


The whole code explanation can be found here

✨ Features

  • 🔒 PDA-controlled vaults for full security
  • ✅ SPL token validation via transfer_checked
  • ↻ Refundable offer if no taker appears
  • 💥 Closes ATAs to reclaim rent
  • 💳 Supports SPL tokens via token-interface

📁 Folder Structure

.
├── programs/
│   └── escrow/
│       ├── src/
│       │   ├── lib.rs              # Entrypoint for the program
│       │   ├── instructions/
│       │   │   ├── make_offer.rs   # Handles offer creation
│       │   │   ├── take_offer.rs   # Handles trade acceptance
│       │   │   ├── refund_offer.rs # Handles refund logic
│       │   │   └── shared.rs       # Reusable helpers (transfers, close)
│       │   └── state/
│       │       └── offer.rs        # Offer account definition
├── migrations/
├── tests/
├── Cargo.toml
└── Anchor.toml

📜 Smart Contract Flow

1. make_offer

The maker initiates an offer by doing the following:

  • Creates a PDA-owned Offer account using seeds ["offer", maker_pubkey, id]

  • Transfers a specified amount of Token A from their wallet to a vault ATA owned by the Offer PDA

  • Vault address is a derived associated token account with:

    • mint = token_mint_a
    • authority = offer PDA

Once created, this offer waits for a taker.

2. take_offer

A taker accepts the offer:

  • Sends the expected Token B amount directly to the maker's token account
  • Receives Token A from the vault (vault ➔ taker)
  • This transaction uses PDA signer seeds to allow the vault (PDA-owned) to transfer Token A
  • Finally, the vault ATA is closed, and rent is reclaimed
  • The offer account is also closed

3. refund_offer

If no one takes the offer, the maker can:

  • Reclaim their Token A from the vault
  • Vault is closed after refund
  • Offer account is closed too

This ensures the maker doesn’t lose tokens to stuck or expired offers.


📆 Accounts Explained

Account Description
Offer Stores trade data: maker, token A/B mints, amount wanted, bump
Vault PDA-owned ATA holding Token A
taker_token_account_b ATA of taker for sending Token B
maker_token_account_b ATA of maker to receive Token B
taker_token_account_a ATA of taker to receive Token A

📅 Utility Functions

transfer_tokens

Safely moves SPL tokens using transfer_checked CPI, with optional signer seeds for PDA authority.

close_token_account

Closes an ATA and sends the lamports to the specified destination. Uses PDA authority if needed.


🚀 Getting Started

1. Install dependencies

anchor install

2. Build the program

anchor build

3. Run local validator

anchor localnet

4. Deploy to local validator

anchor deploy

5. Run tests (if implemented)

anchor test

🛡️ Security Considerations

  • Vault is strictly controlled by a PDA (no keypairs)
  • Transfer amounts are validated with mint precision using transfer_checked
  • Vaults are only created using init_if_needed and ATAs, reducing errors
  • All accounts are closed after use to free up space and reclaim rent

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published