Skip to content

Add Anchor example programs#26

Open
tilo-14 wants to merge 4 commits intomainfrom
pr/anchor-examples
Open

Add Anchor example programs#26
tilo-14 wants to merge 4 commits intomainfrom
pr/anchor-examples

Conversation

@tilo-14
Copy link
Contributor

@tilo-14 tilo-14 commented Feb 16, 2026

Summary

  • Add four Light Token Anchor example programs: escrow, fundraiser, token-swap, light-token-minter
  • Each program tests 5 token configurations (SPL, Token2022, Light, LightSpl, LightT22)
  • Shared test utilities crate for mint/ATA creation, balance verification, SPL interface PDAs
  • Fix light-token-minter: remove deprecated associated_token::bump (now derived on-chain)
  • Update CI workflow to test the four example programs

Programs

Program Description
escrow Peer-to-peer token swap with rent-free Light Token vaults
fundraiser Crowdfunding with contribute, claim, and refund flows
token-swap Constant-product AMM with rent-free pool vaults
light-token-minter Light Token mint creation and minting

Test plan

  • cargo test-sbf -p escrow
  • cargo test-sbf -p fundraiser
  • cargo test-sbf -p light-token-minter
  • cargo test-sbf -p swap_example

Open with Devin

…ken-minter

Add four Light Token example programs with shared test utilities:
- escrow: peer-to-peer token swap with rent-free Light Token vaults
- fundraiser: crowdfunding with contribute, claim, and refund flows
- token-swap: constant-product AMM with rent-free pool vaults
- light-token-minter: Light Token mint creation and minting

Each program tests 5 token configurations (SPL, Token2022, Light,
LightSpl, LightT22) demonstrating cross-standard transfers between
SPL/Token2022 user accounts and Light Token vaults.

Fix light-token-minter: remove deprecated associated_token::bump
(now derived on-chain by the cToken program).

Update CI to test the four example programs.
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 3 potential issues.

View 7 additional findings in Devin Review.

Open in Devin Review

Comment on lines 68 to +88
time = "=0.3.41"

# Internal
test-utils = { path = "basic-instructions/test-utils" }
shared-test-utils = { path = "shared-test-utils" }

# Patch crates.io light-* deps to use local monorepo paths.
# This avoids "two different versions of the same crate" errors
# when light-client/light-program-test (path deps) pull in local
# copies of crates that our programs also reference from crates.io.
[patch.crates-io]
light-sdk = { path = "/home/tilo/Workspace/light-protocol/sdk-libs/sdk" }
light-sdk-macros = { path = "/home/tilo/Workspace/light-protocol/sdk-libs/macros" }
light-sdk-types = { path = "/home/tilo/Workspace/light-protocol/sdk-libs/sdk-types" }
light-account = { path = "/home/tilo/Workspace/light-protocol/sdk-libs/account" }
light-compressible = { path = "/home/tilo/Workspace/light-protocol/program-libs/compressible" }
light-hasher = { path = "/home/tilo/Workspace/light-protocol/program-libs/hasher" }
light-macros = { path = "/home/tilo/Workspace/light-protocol/program-libs/macros" }
light-compressed-account = { path = "/home/tilo/Workspace/light-protocol/program-libs/compressed-account" }
light-token = { path = "/home/tilo/Workspace/light-protocol/sdk-libs/token-sdk" }
light-token-types = { path = "/home/tilo/Workspace/light-protocol/sdk-libs/token-types" }
light-token-interface = { path = "/home/tilo/Workspace/light-protocol/program-libs/token-interface" }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Hardcoded local filesystem paths in workspace Cargo.toml break CI and other developers

The workspace Cargo.toml contains hardcoded paths to /home/tilo/Workspace/light-protocol/... for light-program-test, light-client, and all [patch.crates-io] entries. These paths only exist on one developer's machine.

Impact

At programs/anchor/Cargo.toml:58-59:

light-program-test = { path = "/home/tilo/Workspace/light-protocol/sdk-libs/program-test" }
light-client = { path = "/home/tilo/Workspace/light-protocol/sdk-libs/client", features = ["v2", "anchor"] }

And programs/anchor/Cargo.toml:77-88 patches all light-* crates to local paths.

This means:

  1. CI builds will fail because /home/tilo/Workspace/light-protocol/ doesn't exist on GitHub runners
  2. No other developer can build the project without the exact same directory structure
  3. The cargo test-sbf commands listed in the CI workflow (programs/anchor/Cargo.toml is the workspace root) will all fail

Impact: Complete CI failure and inability for any other developer to build/test the project.

(Refers to lines 58-88)

Prompt for agents
Replace the hardcoded local paths in programs/anchor/Cargo.toml with published crate versions from crates.io. Lines 58-59 should use versioned dependencies like the other light-* crates (e.g., light-program-test = { version = "0.20.0" } and light-client = { version = "0.20.0", features = ["v2", "anchor"] }). The entire [patch.crates-io] section at lines 77-88 should be removed, as it patches all crates to local paths. If local development requires path overrides, use a .cargo/config.toml with [patch] that is gitignored, or use workspace-level path overrides that are conditional.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

tilo-14 added 2 commits February 16, 2026 19:22
- Remove duplicate cache-photon step ID in setup action
- Add example programs to root README (escrow, fundraiser, minter, swap)
- Fix broken create-ata links to create-associated-token-account
- Update programs/anchor README with correct build and test commands
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 new potential issues.

View 11 additional findings in Devin Review.

Open in Devin Review

Comment on lines +73 to +76
require!(
amount >= 10_u64.pow(self.mint_to_raise.decimals as u32),
FundraiserError::ContributionTooSmall
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Fundraiser contribute() minimum amount check panics on overflow for high-decimal mints

The contribute() function computes the minimum contribution as 10_u64.pow(self.mint_to_raise.decimals as u32) without checking for overflow. If a mint has decimals > 19, this expression overflows u64.

Detailed Explanation

At programs/anchor/fundraiser/src/instructions/contribute.rs:74:

require!(
    amount >= 10_u64.pow(self.mint_to_raise.decimals as u32),
    FundraiserError::ContributionTooSmall
);

10_u64.pow(20) = 10^20 which exceeds u64::MAX (≈1.8×10^19). The workspace Cargo.toml sets overflow-checks = true for the release profile, so this would cause a panic (program abort) rather than silent wraparound.

While SPL Token mints typically use decimals 0-9, Token-2022 mints can be created with any u8 value for decimals. Since the fundraiser supports Token-2022 mints (via TokenConfig::Token2022), a malicious or misconfigured mint with decimals >= 20 would make the contribute instruction permanently fail with a panic.

Impact: A fundraiser created with a high-decimal mint would be unable to accept any contributions, effectively locking the fundraiser in a broken state.

Suggested change
require!(
amount >= 10_u64.pow(self.mint_to_raise.decimals as u32),
FundraiserError::ContributionTooSmall
);
let min_amount = 10_u64.checked_pow(self.mint_to_raise.decimals as u32)
.ok_or(FundraiserError::CalculationOverflow)?;
require!(
amount >= min_amount,
FundraiserError::ContributionTooSmall
);
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +77 to +80
require!(
params.amount >= MIN_AMOUNT_TO_RAISE.checked_mul(10_u64.pow(self.mint_to_raise.decimals as u32)).ok_or(FundraiserError::InvalidAmount)?,
FundraiserError::InvalidAmount
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Fundraiser initialize() minimum amount check panics on overflow for high-decimal mints

The initialize() function computes the minimum amount to raise as MIN_AMOUNT_TO_RAISE.checked_mul(10_u64.pow(self.mint_to_raise.decimals as u32)), but the inner pow call is unchecked and will panic for decimals > 19.

Detailed Explanation

At programs/anchor/fundraiser/src/instructions/initialize.rs:78:

require!(
    params.amount >= MIN_AMOUNT_TO_RAISE
        .checked_mul(10_u64.pow(self.mint_to_raise.decimals as u32))
        .ok_or(FundraiserError::InvalidAmount)?,
    FundraiserError::InvalidAmount
);

While checked_mul is used for the multiplication, the 10_u64.pow(decimals) call itself is not checked. For decimals >= 20, pow overflows u64 and panics (since overflow-checks = true in the release profile). The checked_mul never gets a chance to catch the overflow.

Impact: Creating a fundraiser with a high-decimal Token-2022 mint would cause the initialize instruction to panic, wasting the caller's transaction fee.

Suggested change
require!(
params.amount >= MIN_AMOUNT_TO_RAISE.checked_mul(10_u64.pow(self.mint_to_raise.decimals as u32)).ok_or(FundraiserError::InvalidAmount)?,
FundraiserError::InvalidAmount
);
let min_unit = 10_u64.checked_pow(self.mint_to_raise.decimals as u32)
.and_then(|v| MIN_AMOUNT_TO_RAISE.checked_mul(v))
.ok_or(FundraiserError::InvalidAmount)?;
require!(
params.amount >= min_unit,
FundraiserError::InvalidAmount
);
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant