The Gauntelt program is a Solana/Anchor smart contract for running competition tournaments using a Swiss-system model. It supports tournament creation, participant registration, point scoring, winner determination, and secured prize distribution.
- Creates a Swiss-system competition
- Manages participant registration and competition stages
- Stores prize funds in an on-chain vault
- Determines the winner based on leaderboard results
- Enables the winner to withdraw the prize
SwissSystem— the main competition accountParticipant— a participant account in the tournamentLeaderBoard— the leaderboard and score storageVault— prize fund storage tied to the tournament
- Create a Swiss-system tournament
- Register participants
- Update stages: registration, competition, withdrawal
- Award points to participants
- Determine the winner and record it in the
Vault - Winner withdraws the prize
# Install dependencies
cd ./competition-constructor/Gauntelt
yarn install
# Build the Anchor program
anchor build
# Run tests
anchor test -- --features testing
**Note:** Before running tests, update the `INITIALIZER` constant in `programs/Gauntelt/src/instructions/admin/program_config_init.rs` to your Solana wallet address (the one used by Anchor). Otherwise, the tests will fail due to authority mismatch.If you want to run the faster tests from Anchor.toml:
yarn run ts-mocha -p ./tsconfig.json -t 1000000 ./tests/program_config.ts ./tests/constructor.ts ./tests/swiss_system.ts ./tests/swiss_system_vault_create.ts ./tests/swiss_system_vault_spl_create.ts ./tests/swiss_system_leaderboard_create.ts ./tests/swiss_system_participant_create.ts ./tests/swiss_system_points_award.ts ./tests/swiss_system_winner_determine.ts ./tests/swiss_system_prize_withdraw.tsThe program is deployed on devnet at: 63yvyYYUHSZyHEKnz4YerXBvZ5VomBwZtLF1XLmSWfbR
Important: To run tests successfully, you must update the INITIALIZER constant in programs/competition-constructor-program/src/instructions/admin/program_config_init.rs to match your Solana wallet address (the one configured in Anchor). The tests use the --features testing flag, which sets the initializer to a specific address. Change it to your own address to avoid authority validation failures.
The tests/ directory contains the following scenarios:
constructor.ts— basic initialization checksprogram_config.ts— Anchor configuration and program addressesswiss_system.ts— general Swiss-system behavior testsswiss_system_vault_create.ts— vault creation testsswiss_system_vault_spl_create.ts— SPL vault creation testsswiss_system_leaderboard_create.ts— leaderboard creation testsswiss_system_participant_create.ts— participant registration testsswiss_system_points_award.ts— score awarding testsswiss_system_winner_determine.ts— winner determination testsswiss_system_prize_withdraw.ts— prize withdrawal testsswiss_system_stage_update.ts— competition stage update tests
The program uses a Vault account as a PDA (Program Derived Address), created from tournament-specific seeds. The prize funds remain locked by the program until:
- the competition stage has finished,
- the winner is determined,
- the current stage is the withdrawal period.
When the winner requests withdrawal, the smart contract verifies:
- the
Vaultaccount belongs to the correct Swiss-system tournament, - the winner is recorded in the
Vaultstate, - the current stage is
WithdrawPeriod, - the request is made by the winner or an authorized recipient.
If all checks pass, the program transfers funds from the Vault to the winner's account.
flowchart TD
A[Tournament creation] --> B[Create SwissSystem]
B --> C[Create Vault]
C --> D[Deposit prize fund]
D --> E[Run competition]
E --> F[Determine winner from LeaderBoard]
F --> G[Write winner address into Vault.winner]
G --> H[Withdraw request]
H --> I{Contract checks}
I -->|valid winner and stage| J[Transfer funds]
I -->|invalid| K[Reject]
- No duplicate initialization of accounts
- Strict authority validation
- Deterministic leaderboard updates
- No zero-point or invalid point assignments
- Prize distribution only after winner determination
While building the system, several edge cases were identified:
- role collision (authority = participant)
- duplicate initialization attacks
- inconsistent leaderboard updates
These are covered by tests.