Skip to content

ISSUE-CU06-002: Testing for Claim Prize FunctionalityΒ #547

@davidmelendez

Description

@davidmelendez

ISSUE-CU06-002: Testing for Claim Prize Functionality

✨ Issue Request

Implement complete unit and integration test suite for the prize claiming functionality (CU-06), covering all use cases and error scenarios.

πŸ“Œ Description

This issue focuses exclusively on implementing tests for the ClaimPrize functionality of use case CU-06. It is separated from the main implementation issue (SL-CU06-001) to facilitate development during the hackathon. Tests should run with Starknet Foundry (snforge) and cover both successful cases and error scenarios.

πŸ› οΈ Steps to Reproduce (if applicable)

Prerequisites:

  1. Issue SL-CU06-001 must be completed and implemented
  2. The ClaimPrize function must be operational in Lottery.cairo
  3. The prize distribution system (CU-05) must be functional

πŸ–ΌοΈ Screenshots (if applicable)

Not applicable for testing.

🎯 Expected Behavior

The test suite should cover:

Unit Tests (Cairo - snforge):

  1. πŸ”Ή Basic successful claim test

    • Setup: finalized draw, completed distribution, ticket with assigned prize
    • Execute: ClaimPrize(drawId, ticketId)
    • Verify: tokens transferred, ticket.claimed = true, event emitted
  2. πŸ”Ή Ownership validation test

    • Try to claim another player's ticket prize
    • Verify: transaction reverts with 'Not ticket owner'
  3. πŸ”Ή Double claim test

    • Claim prize successfully
    • Try to claim same ticket again
    • Verify: transaction reverts with 'Prize already claimed'
  4. πŸ”Ή No assigned prize test

    • Ticket without prize (prize_assigned = false)
    • Try to claim
    • Verify: transaction reverts with 'No prize assigned'
  5. πŸ”Ή No prize amount test

    • Ticket with prize_assigned = true but prize_amount = 0
    • Try to claim
    • Verify: transaction reverts with 'No prize amount'
  6. πŸ”Ή Draw not finalized test

    • Draw with isActive = true
    • Try to claim prize
    • Verify: transaction reverts with 'Draw still active'
  7. πŸ”Ή Distribution not completed test

    • Finalized draw but distribution_done = false
    • Try to claim prize
    • Verify: transaction reverts with 'Distribution not done'
  8. πŸ”Ή Nonexistent draw test

    • Try to claim with non-existent drawId
    • Verify: transaction reverts with 'Draw is not active'
  9. πŸ”Ή Reentrancy protection test

    • Simulate reentrancy attack on ClaimPrize
    • Verify: reentrancy guard prevents attack
  10. πŸ”Ή Insufficient vault balance test

    • Vault with balance less than prize
    • Try to claim prize
    • Verify: transaction reverts with 'Transfer failed'
  11. πŸ”Ή Multiple claims test

    • Several tickets with assigned prizes
    • Claim all successfully
    • Verify: each claim correct, balances updated
  12. πŸ”Ή Event emission test

    • Claim prize successfully
    • Verify: PrizeClaimed event with correct fields (drawId, player, ticketId, prizeAmount)

Integration Tests (Cairo - snforge):

  1. πŸ”Ή Complete CU-05 β†’ CU-06 flow test

    • Create draw, buy tickets
    • Execute DrawNumbers
    • Execute DistributePrizes
    • Claim prizes from multiple winners
    • Verify: consistent end state
  2. πŸ”Ή Different prize levels test

    • Tickets with 1, 2, 3, 4 matches
    • Distribute prizes
    • Claim each level
    • Verify: correct amounts according to percentages
  3. πŸ”Ή Token balances test

    • Setup with known initial balances
    • Execute complete flow until claim
    • Verify: correct final balances of players and vault

πŸš€ Suggested Solution / Feature Request

Test file structure:

Create file: packages/snfoundry/contracts/tests/test_CU06_claim_prize.cairo

use snforge_std::{declare, ContractClassTrait, start_prank, stop_prank, CheatTarget};
use starknet::{ContractAddress, contract_address_const};

// Successful claim test
#[test]
fn test_claim_prize_success() {
    // Setup: deploy contracts, create draw, buy ticket, distribute prizes
    // Execute: ClaimPrize
    // Assert: ticket.claimed = true, balance updated, event emitted
}

// Double claim test
#[test]
#[should_panic(expected: ('Prize already claimed',))]
fn test_claim_prize_already_claimed() {
    // Setup: claim prize once
    // Execute: try to claim again
    // Should panic
}

// No ownership test
#[test]
#[should_panic(expected: ('Not ticket owner',))]
fn test_claim_prize_not_owner() {
    // Setup: ticket owned by player1
    // Execute: player2 tries to claim
    // Should panic
}

// Active draw test
#[test]
#[should_panic(expected: ('Draw still active',))]
fn test_claim_prize_draw_active() {
    // Setup: draw with isActive = true
    // Execute: try to claim
    // Should panic
}

// Distribution not completed test
#[test]
#[should_panic(expected: ('Distribution not done',))]
fn test_claim_prize_distribution_not_done() {
    // Setup: draw finalized but distribution_done = false
    // Execute: try to claim
    // Should panic
}

// No assigned prize test
#[test]
#[should_panic(expected: ('No prize assigned',))]
fn test_claim_prize_no_prize_assigned() {
    // Setup: ticket with prize_assigned = false
    // Execute: try to claim
    // Should panic
}

// No prize amount test
#[test]
#[should_panic(expected: ('No prize amount',))]
fn test_claim_prize_no_amount() {
    // Setup: ticket with prize_amount = 0
    // Execute: try to claim
    // Should panic
}

// PrizeClaimed event test
#[test]
fn test_claim_prize_event_emission() {
    // Setup: valid claim scenario
    // Execute: ClaimPrize
    // Assert: PrizeClaimed event with correct fields
}

// Multiple claims test
#[test]
fn test_claim_multiple_prizes() {
    // Setup: multiple tickets with prizes
    // Execute: claim all prizes
    // Assert: all claimed successfully
}

// Full flow test
#[test]
fn test_full_flow_distribute_and_claim() {
    // Setup: complete lottery flow
    // Execute: BuyTicket -> DrawNumbers -> DistributePrizes -> ClaimPrize
    // Assert: end state consistent
}

Create file: packages/snfoundry/contracts/tests/test_CU06_integration.cairo

Integration tests that validate:

  • Interaction between Lottery, StarkPlayERC20 and StarkPlayVault
  • Complete flow of multiple players claiming prizes
  • Final balance validation
  • Performance with large number of tickets

Testing helpers:

Add helper functions in tests:

// Helper for complete setup
fn setup_claim_scenario() -> (
    ContractAddress, // lottery
    ContractAddress, // token
    ContractAddress, // vault
    u64, // drawId
    felt252, // ticketId
    ContractAddress, // player
) {
    // Deploy contracts
    // Create draw
    // Buy ticket
    // Finalize draw
    // Distribute prizes
    // Return addresses and IDs
}

// Helper to verify ticket state
fn assert_ticket_state(
    lottery: ContractAddress,
    drawId: u64,
    ticketId: felt252,
    expected_claimed: bool,
    expected_prize_amount: u256,
) {
    // Read ticket
    // Assert claimed status
    // Assert prize amount
}

// Helper to verify token balance
fn assert_token_balance(
    token: ContractAddress,
    account: ContractAddress,
    expected_balance: u256,
) {
    // Read balance
    // Assert equals expected
}

Commands to run tests:

# Run all CU06 tests
cd packages/snfoundry/contracts
scarb test test_CU06

# Run specific test
scarb test test_claim_prize_success

# Run with detailed output
scarb test test_CU06 --verbose

πŸ“Œ Additional Notes

Expected coverage:

  • Successful cases: 30%
  • Security validations: 40%
  • Error cases: 30%
  • Target: >90% code coverage on ClaimPrize function

Test priority:

  1. High: Security tests (ownership, double claim, reentrancy)
  2. Medium: Validation tests (draw state, assigned prizes)
  3. Low: Integration and performance tests

Implementation notes:

  • Use start_prank / stop_prank to simulate different callers
  • Use declare to deploy contracts in test environment
  • Mock vault if needed to simulate specific scenarios
  • Consider tests with gas measurement for future optimization

Frontend testing (optional for separate issue):

  • Tests with Vitest for UI components
  • Integration tests with mock wallet
  • E2E tests with Playwright (optional)

Documentation:

  • Document each test with explanatory comments
  • Add section in README about running tests
  • Include examples of expected output

⚠️ Before Applying

Please read this guide: Contributor Guidelines

Definition of Done:

  • File test_CU06_claim_prize.cairo created with all unit tests
  • File test_CU06_integration.cairo created with integration tests
  • All tests pass successfully with scarb test
  • Code coverage >90% for ClaimPrize function
  • Helpers and utilities implemented
  • Test documentation added to README
  • Reentrancy tests implemented and passing
  • Event tests validating correct fields
  • Balance tests validating correct transfers

Metadata

Metadata

Assignees

No one assigned

    Type

    No fields configured for Task.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions