Factory-based wand creation system using alkamist/dust tokens with cellpack architecture and boiler security patterns
Gamba is an Orbital Wand Factory that creates individual wand NFTs through a gambling mechanism. Players send alkamist or dust tokens to improve their odds of successfully creating a wand. The factory uses boiler's proven security patterns and cellpack architecture to create individual wand NFTs from predefined templates.
- Factory Pattern:
OrbitalWandFactorycreates individual wand NFTs using cellpack calls - Predefined Templates: Six wand template contracts for different rarities
- Token Burning: Alkamist/dust tokens are burned to improve creation odds
- Child Registration: Factory tracks all created wand NFTs for security
// Single wand template ID - one template for all wand types
const WAND_TEMPLATE_ID: u128 = 0x1001; // Single wand template
// Rarity and type determined by interpolating imprinted state into SVG- Send Tokens: Send alkamist (2:25720) or dust (2:35275) tokens to factory
- Calculate Bonuses:
- Dust: +10 points per 1000 dust above 2000 threshold
- Alkamist: +5 points per alkamist token
- Roll Calculation: Base XOR (merkle root last byte) + bonuses
- Success Check: If final XOR โฅ 150, wand creation succeeds
- Cellpack Creation: Factory calls single wand template with creation data
- State Imprinting: Wand gets creation data imprinted during initialization (wand_id, XOR results, bonuses, amounts, etc.)
- NFT Return: User receives individual wand NFT token with imprinted state
- SVG Generation: When opcode 1000 is called on wand, it proxies back to factory for main template and interpolates its own imprinted values
- Alkamist: Minimum 1 token from position 2:25720
- Dust: Minimum 1000 tokens from position 2:35275 or other block 2 tokens
- Mixed: Can send both alkamist and dust for maximum bonuses
- Base Threshold: 150 (values 150-255 succeed)
- Base Win Rate: ~41.4% (106/256 possible outcomes)
- Enhanced Odds: Bonuses reduce effective threshold
- Example: 5000 dust (+40 bonus) = ~57.0% win rate
#[opcode(42)]
CastWand, // Main wand creation function
#[opcode(2000)]
GetWandCount, // Total wands created
#[opcode(2001)]
GetWandList, // Master list of all wand metadata
#[opcode(3000)]
GetAllRegisteredWands, // All registered wand NFTs
#[opcode(3001)]
IsRegisteredWand, // Check if wand is factory-created#[opcode(1000)]
GetData, // Individual wand generates its own SVG by calling back to factory
#[opcode(1001)]
GetContentType, // Returns "image/svg+xml"
#[opcode(1002)]
GetAttributes, // Returns wand metadata as JSONlet cellpack = Cellpack {
target: AlkaneId {
block: WAND_TEMPLATE_BLOCK,
tx: wand_template_id,
},
// These inputs become the imprinted state in the individual wand NFT
inputs: vec![
0x0, // Initialize opcode
wand_id, // Wand ID (imprinted)
final_xor_result as u128, // Final XOR result (imprinted)
base_xor_result as u128, // Base XOR result (imprinted)
dust_bonus as u128, // Dust bonus (imprinted)
alkamist_bonus as u128, // Alkamist bonus (imprinted)
total_dust, // Dust amount (imprinted)
total_alkamist, // Alkamist amount (imprinted)
block_height as u128, // Block height (imprinted)
txid.to_byte_array()[0] as u128, // Uniqueness (imprinted)
],
};During cellpack initialization, the wand template receives and stores these values as its internal state:
- Wand Identity: Unique ID and creation metadata
- XOR Results: Base randomness and final calculated result
- Token Data: Amounts of dust/alkamist burned for creation
- Bonuses: Calculated enhancement values
- Block Context: Creation block height and transaction uniqueness
// When opcode 1000 is called on individual wand NFT:
// 1. Wand reads its own imprinted state
// 2. Wand proxies call to factory for main SVG template
// 3. Wand interpolates its imprinted values into template
// 4. Returns customized SVG specific to this wand's propertiesfn has_tx_hash(&self, txid: &Txid) -> bool
fn add_tx_hash(&self, txid: &Txid) -> Result<()>fn register_wand(&self, wand_id: &AlkaneId)
fn is_registered_wand_internal(&self, wand_id: &AlkaneId) -> bool// All arithmetic uses checked operations
let total_alkamist: u128 = alkamist_transfers.iter()
.try_fold(0u128, |acc, t| acc.checked_add(t.value))
.ok_or_else(|| anyhow!("Alkamist amount overflow"))?;fn validate_incoming_alkanes(&self) -> Result<()>
fn is_valid_alkamist_or_dust(&self, id: &AlkaneId) -> bool- 150-170: Common Wands
- 171-190: Rare Wands
- 191-210: Epic Wands
- 211-230: Legendary Wands
- 231-250: Mythic Wands
- 251-255: Cosmic Wands - Ultra Rare!
- Unique ID: Sequential factory-assigned ID
- Template Type: Determined by final XOR result
- Imprinted State: Creation data permanently stored during initialization (XOR results, token amounts, bonuses, block height)
- Factory Provenance: Registered as factory child for authenticity
- Self-Rendering: Reads own imprinted state, proxies to factory for template, interpolates values for unique SVG
- Rust 1.70+
- Alkane runtime environment
- Position tokens at 2:25720 (alkamist) and 2:35275 (dust)
git clone <repository>
cd gamba
cargo build --release # Builds both factory and wand template contracts# Run comprehensive integration tests on factory (includes wand template testing)
cargo test -p orbital-wand-factory --test orbital_wand_integration_test
# All tests use index_block methods for proper indexer testing
# Tests include:
# - Factory deployment and initialization
# - Wand template deployment and initialization
# - Individual wand NFT functionality testing
# - SVG generation by individual wands
# - Multi-scenario gambling with various token amountsThe build system generates real WASM bytecode for both contracts:
build.rscompiles both factory and wand template to WASM- Generated files:
orbital_wand_factory.wasm,wand_template.wasm - Workspace structure with separate contracts for factory and template
- Test helpers:
factory/src/tests/std/*_build.rsuseinclude_bytes!for real bytecode
gamba/
โโโ factory/
โ โโโ src/
โ โ โโโ lib.rs # Factory module exports
โ โ โโโ orbital_wand.rs # OrbitalWandFactory implementation
โ โ โโโ probability.rs # Probability calculations
โ โ โโโ wand_svg.rs # SVG generation
โ โ โโโ tests/ # Factory tests
โ โโโ Cargo.toml # Factory dependencies
โโโ wand-template/
โ โโโ src/
โ โ โโโ lib.rs # Template module exports
โ โ โโโ wand_template.rs # WandTemplate implementation
โ โ โโโ wand_svg.rs # SVG generation
โ โโโ Cargo.toml # Template dependencies
โโโ src/ # Legacy source (for reference)
โโโ build.rs # Build script for both contracts
โโโ Cargo.toml # Workspace configuration
โโโ README.md # This file
- Transaction Replay Protection: Each transaction can only be used once
- Child Registration: All created wands are registered and tracked
- Overflow Protection: All arithmetic uses checked operations
- Input Validation: Strict token ID and value validation
- Initialization Protection:
observe_initialization()prevents re-init - Detailed Error Messages: Comprehensive error reporting
- Template Validation: Only calls predefined wand templates
- Token Burning: Tokens are consumed regardless of success/failure
- Randomness: Uses merkle root last byte for cryptographic randomness
- Bonus Caps: Dust/alkamist bonuses are capped to prevent overflow
- Randomness Source: Last byte of merkle root (0-255)
- Success Threshold: 150 (41.4% base win rate)
- Token Burning: All sent tokens are burned (deflationary)
// Dust bonus: +10 per 1000 dust above 2000 threshold
let dust_bonus = if dust_amount >= 2000 {
std::cmp::min(((dust_amount - 2000) / 1000) * 10, 255) as u8
} else { 0 };
// Alkamist bonus: +5 per alkamist token
let alkamist_bonus = std::cmp::min(alkamist_amount * 5, 255) as u8;- 1000 dust: 41.4% win rate (no bonus)
- 3000 dust: 45.3% win rate (+10 bonus)
- 5000 dust: 49.2% win rate (+20 bonus)
- 1 alkamist: 43.4% win rate (+5 bonus)
- 5000 dust + 2 alkamist: 53.1% win rate (+30 total bonus)
The factory requires one wand template contract deployed at:
- Block 6, TX 0x1001 (Single wand template for all types)
- Template must implement initialization opcode 0x0
- Template must implement opcode 1000 for SVG generation
- Template receives and stores creation data as imprinted state via cellpack inputs
- Individual wand tokens generate SVG by interpolating their own imprinted state values
- Rarity and type determined by the wand template based on imprinted XOR results
- Alkamist Position: Block 2, TX 25720
- Dust Position: Block 2, TX 35275
- Backward Compatibility: Accepts any block 2 tokens as dust (except alkamist)
test_orbital_wand_comprehensive_integration(): Full system testtest_orbital_wand_edge_cases(): Edge case validation- All tests use
index_block()methods: Proper indexer testing - Multi-scenario testing: Different dust/alkamist combinations
- State verification: Before/after state comparison
- Trace analysis: Comprehensive execution trace capture
- Factory and wand template deployment and initialization
- Position token conversion flows
- Gambling mechanics with various stakes
- Individual wand NFT functionality testing
- SVG generation by individual wands (not factory)
- Wand rarity, type, and power level methods
- Statistical analysis and win rate verification
- Edge cases (zero dust, maximum dust, invalid opcodes)
Deploy single wand template contract to block 6, TX 0x1001
Deploy OrbitalWandFactory contract
- Call initialize opcode (0x0) on factory
- Call initialize opcode (0x0) on wand template
- Test wand creation with various token amounts
- Verify child registration works correctly
- Test individual wand NFT functionality
- Confirm SVG generation by individual wands
- Verify rarity/type methods on wand templates
- Total wands created:
GetWandCount() - Win rate tracking:
GetWinRate() - Token consumption:
GetTotalDustConsumed(),GetTotalAlkamistConsumed() - Registered wands:
GetAllRegisteredWands()
- Average gas per wand creation
- Template distribution (Common vs Rare vs Epic, etc.)
- User behavior patterns (dust vs alkamist preferences)
- Additional wand types and rarities
- Seasonal or event-specific templates
- Community-created template submissions
- Multi-token staking (combine different position types)
- Time-based bonuses or penalties
- Wand utility in other contracts
- Wand marketplace integration
- Staking rewards for wand holders
- Governance tokens for template approval
- Factory Pattern: This is NOT a simple gambling contract - it's a factory that creates individual NFTs
- Cellpack Usage: Uses boiler's cellpack pattern to call template contracts
- Child Registration: MUST register all created wands for security
- Token Burning: Tokens are consumed regardless of outcome (not returned)
- Template Dependencies: Requires single wand template contract to be deployed first
- SVG Architecture: Factory does NOT generate SVG - individual wand tokens have state imprinted during initialization, then proxy back to factory for main template and interpolate their own values (similar to panda contract pattern)
- Boiler Inheritance: Security patterns are inherited from boiler vault factory
- Position Validation: Only accepts specific alkamist/dust positions
- Overflow Protection: All arithmetic must use checked operations
- Replay Protection: Transaction hash tracking is critical
- Indexer-Only: All tests MUST use
index_block()methods - Integration Focus: No unit tests - only comprehensive integration tests
- Real Bytecode: Build system generates actual WASM, no placeholders
- WASM Generation:
build.rscompiles both contracts to real bytecode - Workspace Structure: Separate contracts for factory and wand template
- Include Bytes: Test helpers use
include_bytes!for generated WASM - Contract Coordination: Factory and template must be built and deployed together
Built with ๐๏ธ Factory Pattern + ๐ Boiler Security + ๐ฒ Provable Randomness
May your tokens forge legendary wands! ๐ชโจ๐ฅ