You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Comprehensive reference for every configurable parameter, constant, storage key, error code, and validation rule in the CrowdPass Soroban smart contracts.
Shared rlib compiled into every contract. Provides: upgrade timelock, pause guard, admin management, version counter, and TTL extension helpers.
1.1 Upgrade Timelock Constants
Constant
Type
Default
Notes
UPGRADE_DELAY_LEDGERS
u32
17_280
Ledgers between schedule_upgrade and commit_upgrade. At 5 s/ledger ≈ 24 hours. Increase for more stakeholder reaction time; decrease for faster patch cycles.
LEDGER_SECONDS
u32
5
Assumed ledger cadence. Used only to derive LEDGERS_PER_DAY. Does not affect on-chain behaviour (ledger sequence numbers, not wall-clock time, are used).
SECONDS_PER_DAY
u32
86_400
Informational. Used to derive LEDGERS_PER_DAY.
LEDGERS_PER_DAY
u32
17_280
Derived: 86_400 / 5. Informational only.
1.2 Storage TTL Constants
Constant
Type
Default
Impact of Changing
DEFAULT_TTL_THRESHOLD_LEDGERS
u32
518_400 (30 days)
When remaining TTL falls below this threshold an extension is triggered. Raising it means entries refresh more eagerly (higher fees); lowering it risks expiry of rarely-touched state.
DEFAULT_TTL_EXTEND_TO_LEDGERS
u32
1_728_000 (100 days)
Target TTL set during extension. Must be greater than DEFAULT_TTL_THRESHOLD_LEDGERS. Increasing reduces how often extension transactions run; decreasing saves rent but requires more frequent activity.
Warning: If DEFAULT_TTL_EXTEND_TO_LEDGERS is set below DEFAULT_TTL_THRESHOLD_LEDGERS, every write will re-trigger an extension on the same ledger, wasting fees.
1.3 UpgradeKey Storage Layout
Key
Storage Type
Value Type
Purpose
UpgradeKey::Admin
Instance
Address
Contract administrator. Required for all admin-gated operations.
UpgradeKey::Version
Instance
u32
Monotonically incrementing version. Starts at 1; bumped by commit_upgrade().
UpgradeKey::Paused
Instance
bool
When true, all state-mutating entry points revert via require_not_paused().
UpgradeKey::PendingUpgrade
Instance
(BytesN<32>, u32)
Tuple of (new_wasm_hash, scheduled_at_ledger). Written by schedule_upgrade(); consumed by commit_upgrade().
1.4 Admin & Upgrade Functions
Function
Auth Required
Description
schedule_upgrade(new_wasm_hash)
Admin
Records new WASM hash + current ledger sequence. Emits upgrade_scheduled. Cannot be committed until UPGRADE_DELAY_LEDGERS have elapsed.
Primary user-facing contract. Organizers create events; buyers purchase tickets; the contract escrows ticket revenue until the event ends, then releases funds to the organizer.
2.1 Hard-Coded Constants
These are baked into the WASM binary. Changing them requires a contract upgrade.
Constant
Type
Default
Range
Impact of Changing
MAX_STRING_BYTES
u32
200
1 – 200
Maximum byte length for theme and event_type. Very long strings increase ledger entry size and fees. Values shorter than 1 byte are rejected with InvalidStringInput.
MAX_TICKET_TIERS
u32
32
1 – 32
Maximum ticket tiers per event. Each tier is stored as a TicketTier struct. Raising this increases per-event storage; lowering prevents flexible pricing models.
MAX_TICKETS_PER_EVENT
u128
500_000
1 – 500_000
Maximum total tickets across all tiers. Prevents a single event from monopolising network state.
MAX_TICKET_PRICE
i128
10_000_000_000_000_000
>= 0
Maximum ticket_price in the token's smallest unit. Prevents overflow in total_price = price × quantity.
MAX_ORGANIZER_OPEN_EVENTS
u32
50
1 – u32::MAX
Maximum concurrent active events per organizer. Prevents resource exhaustion.
EVENT_CREATE_COOLDOWN_SECS
u64
120
0 – any u64
Minimum seconds between successive event creations by the same organizer. 0 disables rate limiting.
MAX_EVENT_DURATION_SECS
u64
31_622_400
1 – any u64
Maximum allowed span between start_date and end_date (366 × 86 400 ≈ one leap year).
MAX_EVENT_START_AHEAD_SECS
u64
158_112_000
1 – any u64
Maximum seconds in the future that start_date may be set (5 × 366 days).
MAX_PURCHASE_QUANTITY
u128
500
1 – u128::MAX
Maximum tickets per single purchase_tickets() call. Prevents excessive NFT minting gas in one transaction.
2.2 CreateEventParams Fields
Field
Type
Default
Constraints
Notes
organizer
Address
—
Any valid Stellar address
Must call require_auth(). Only this address can cancel, update, or withdraw funds for the event.
theme
String
—
1 – MAX_STRING_BYTES bytes
Display name. Empty or too-long values → InvalidStringInput.
event_type
String
—
1 – MAX_STRING_BYTES bytes
Category label (e.g. "Conference"). Same length rules as theme.
start_date
u64
—
now < start_date ≤ now + MAX_EVENT_START_AHEAD_SECS
Unix timestamp (seconds). Must be strictly in the future and within the lookahead window.
Deploys a fresh TicketNFT WASM instance for each event. Called internally by EventManager during event creation.
3.1 Constructor Parameters
Parameter
Type
Constraints
Notes
admin
Address
Any valid Stellar address
Controls deploy_ticket() and all upgrade/pause operations. Normally set to the EventManager address so it can autonomously deploy NFT contracts.
ticket_wasm_hash
BytesN<32>
32-byte hash of uploaded WASM
WASM hash of the TicketNFT contract. Must be uploaded to the network before factory deployment. Changing it (via upgrade) affects all future NFT deployments.
3.2 DataKey Storage Layout
Key
Storage
Value Type
Purpose
Admin
Instance
Address
Factory administrator for require_auth() checks in deploy_ticket().
TicketWasmHash
Instance
BytesN<32>
WASM hash for all NFT contract deployments. Updatable only through the upgrade mechanism.
TotalTickets
Instance
u32
Running count of deployed ticket contracts. Starts at 0; incremented to 1-indexed on each deployment.
TicketContract(u32)
Persistent
Address
Maps ticket_id (1-indexed) to the deployed NFT contract address.
3.3 Error Codes
Code
Name
When Triggered
1
NotInitialized
Admin or TicketWasmHash not found in instance storage.
2
Unauthorized
Reserved — auth failures surface via require_auth() panic.
Non-fungible token contract where each address may hold at most one token. Tokens are sequentially ID'd starting at 1.
4.1 Constructor Parameters
Parameter
Type
Notes
minter
Address
Sole address authorised to call mint_ticket_nft(). In production this is the EventManager contract address. Also controls metadata updates on tickets without a registered event.
4.2 Mint Behaviour & Defaults
Parameter
Type
Default
Notes
NextTokenId (auto)
u128
1
Sequential token IDs stored in instance storage. Never reused after a burn.
metadata.name
String
"Ticket"
Applied at mint. Can be updated post-mint via update_metadata().
metadata.tier
String
"General"
Default tier label. Update via update_metadata().
metadata.event_id
u32
0
When 0, metadata admin rights belong to the minter. When > 0, the registered organizer in EventInfo(event_id) controls metadata.
token_uri default
String
"onchain://ticket"
Returned by token_uri() when no OffChainMetadata is set. Override per-token via update_off_chain_uri().
4.3 Transfer Rules
Each address may hold at most 1 token. RecipientAlreadyHasTicket is returned if the recipient's balance > 0.
The from address must be the current owner; Unauthorized is returned otherwise.
TicketMetadata is retained through transfers — it is bound to the token_id, not the owner address.
4.4 DataKey Storage Layout
Key
Storage
Value Type
Purpose
Minter
Instance
Address
Address authorised to mint. Set in constructor.
NextTokenId
Instance
u128
Next token ID to assign. Starts at 1.
Owner(u128)
Persistent
Address
Current owner of token_id. Removed on burn (is_valid() returns false when missing).
Balance(Address)
Persistent
u128
0 or 1. Enforces the one-ticket-per-address invariant.
Factory and directory for Token-Bound Accounts. Each TBA address is deterministically derived from (implementation_hash, token_contract, token_id, salt).
5.1 Constructor Parameters
Parameter
Type
Notes
admin
Address
Upgrade admin for the registry itself. Does not control individual TBA accounts.
tba_account_wasm_hash
BytesN<32>
WASM hash deployed for every create_account() call. Changing this (via upgrade) affects only future TBA deployments — existing TBAs are unaffected.
5.2 create_account() Parameters
Parameter
Type
Notes
implementation_hash
BytesN<32>
Conceptually the TBA "version". Together with salt allows multiple TBAs per NFT.
token_contract
Address
The NFT contract this TBA is bound to. Must implement owner_of(u128) -> Address.
token_id
u128
The specific NFT token that controls this TBA. The caller must be the current NFT owner.
salt
BytesN<32>
User-supplied entropy for deterministic address derivation. Reusing the same salt for identical parameters → AccountAlreadyDeployed.
This value is passed to env.deployer().with_current_contract(composite_salt).deploy_v2(wasm_hash, []). The resulting address is fully deterministic and can be predicted via get_account() before deployment.
5.4 DataKey Storage Layout
Key
Storage
Value Type
Purpose
ImplementationWasmHash
Instance
BytesN<32>
WASM hash for TbaAccount deployment. Set in constructor.
DeployedAccount(BytesN<32>)
Persistent
Address
Maps composite_salt → deployed TBA address. Presence used as the "already deployed" guard.
AccountCount(Address, u128)
Persistent
u32
Number of TBAs deployed for a given (token_contract, token_id) pair.
5.5 Error Codes
Code
Name
When Triggered
1
AccountAlreadyDeployed
A TBA with the same composite salt already exists in persistent storage.
2
NotInitialized
ImplementationWasmHash not found in instance storage.
Smart-wallet bound to a specific NFT. Whoever holds the NFT controls the TBA. Ownership is checked live via cross-contract call on every operation.
6.1 initialize() Parameters
Called once by the TbaRegistry immediately after deployment.
Parameter
Type
Notes
token_contract
Address
NFT contract whose owner_of() is called on every execute() and __check_auth().
token_id
u128
Specific NFT token ID. Stored as u128 — no u64 truncation (verified by fuzz test test_large_token_id_success, supports IDs > u64::MAX).
implementation_hash
BytesN<32>
Stored for auditing purposes only. Not used in runtime logic.
salt
BytesN<32>
Stored for auditing purposes only. Corresponds to the registry's deployment salt.
6.2 Nonce
A u64 counter in instance storage under DataKey::Nonce. Starts at 0; incremented by 1 on every successful execute() call. Publicly readable via nonce(). Emitted in the TransactionExecuted event for replay-protection and sequencing.
6.3 Ownership Transfer Behaviour
There is no explicit ownership transfer function. Ownership automatically follows the NFT: when the underlying TicketNFT token is transferred via transfer_from(), the new address becomes the TBA owner and gains execute() rights on the next call. The old owner's authority is revoked immediately.
6.4 DataKey Storage Layout
Key
Storage
Value Type
Purpose
DataKey::TokenContract
Instance
Address
NFT contract address. Queried on every execute() and __check_auth().
DataKey::TokenId
Instance
u128
NFT token ID used in owner_of() cross-contract calls.
DataKey::ImplementationHash
Instance
BytesN<32>
WASM hash recorded at init for traceability.
DataKey::Salt
Instance
BytesN<32>
Deployment salt recorded at init for traceability.
DataKey::Initialized
Instance
bool
Re-initialization guard. AlreadyInitialized returned if already true.
DataKey::Nonce
Instance
u64
Transaction counter. Starts at 0; incremented on each execute().
6.5 Error Codes
Code
Name
When Triggered
1
AlreadyInitialized
initialize() called when the Initialized flag is already true.
2
NotInitialized
execute() or owner() called before initialize() was run.
Secondary-market contract for peer-to-peer ticket resale. Sellers list tickets; buyers pay and receive the NFT atomically.
7.1 Constructor Parameters
Parameter
Type
Default
Notes
admin
Address
—
Marketplace administrator. Controls update_price_cap() and all upgrade/pause operations.
max_price_multiplier
i128
—
Upper bound multiplier on listing prices. Stored in PriceCap; enforcement logic is a planned enhancement (currently only price > 0 is enforced).
min_price_multiplier
i128
—
Lower bound multiplier. Same implementation note as max_price_multiplier.
MaxListingsPerUser
u32
10
Per-user listing cap stored at construction. Not yet enforced per-user in create_listing() — planned for a future version.
7.2 PriceCap Configuration
Field
Type
Default
Notes
max_price_multiplier
i128
Set in constructor
Upper cap. Active only when active = true. Full multiplier enforcement is a future enhancement.
min_price_multiplier
i128
Set in constructor
Lower cap. Same note.
active
bool
true
When false, all price cap enforcement is skipped. Toggle via update_price_cap().
Production Note: The current implementation uses the Admin address as the payment token in purchase_ticket(). A dedicated SEP-41 token contract should be configured for XLM or USDC payments before mainnet deployment. This requires a contract upgrade.
7.3 DataKey Storage Layout
Key
Storage
Value Type
Purpose
Listing(u32)
Persistent
Listing
Full listing record. listing_id is a 0-indexed sequential counter.
Sale(u32)
Persistent
Sale
Historical completed sale record. sale_id is a 0-indexed sequential counter.
TotalListings
Persistent
u32
Total listings ever created (not just active). Used as the next listing_id.
TotalSales
Persistent
u32
Total completed sales. Used as the next sale_id.
PriceCap
Persistent
PriceCap
Current price cap policy. Updatable by admin via update_price_cap().
Admin
Persistent
Address
Marketplace admin address. Also used as the payment token placeholder (see production note above).
MaxListingsPerUser
Persistent
u32
Stored per-user listing limit (currently unenforced in create_listing()).
7.4 Error Codes
Code
Name
When Triggered
1
ListingNotFound
purchase_ticket() or cancel_listing() called with a non-existent listing_id.
2
ListingNotActive
purchase_ticket() called on a listing whose active flag is false.
3
CannotPurchaseOwnListing
buyer == listing.seller in purchase_ticket().
4
PaymentTokenNotConfigured
Admin address not found in persistent storage.
5
OnlySellerCanCancel
cancel_listing() caller is not the original listing seller.
6
ListingAlreadyInactive
cancel_listing() called on a listing already set to active = false.
7
PriceMustBePositive
Reserved; currently checked via panic in create_listing().
8
InsufficientBalance
Reserved; insufficient balance surfaces as a failed token.transfer().
9
Unauthorized
update_price_cap() caller does not match the stored admin address.
8. Cross-Contract Call Matrix
Caller
Callee
Function
When
EventManager
TicketFactory
deploy_ticket()
During create_event_with_tiers() — deploys a new NFT contract per event.
EventManager
TicketNFT
mint_ticket_nft()
During purchase_ticket(s)() — one call per ticket in the quantity.
EventManager
SEP-41 Token
transfer()
During purchase (buyer → contract) and claim_refund / withdraw_funds (contract → recipient/organizer).
TbaRegistry
TicketNFT
owner_of()
Before deploying a TBA to verify the caller is the NFT owner.
TbaRegistry
TbaAccount
initialize()
Immediately after deploying each TBA contract.
TbaAccount
TicketNFT
owner_of()
On every execute() and __check_auth() call — live ownership check.
TbaAccount
Any contract
Any function
Via execute() — the TBA relays arbitrary calls on behalf of the NFT owner.
Marketplace
TicketNFT
balance()
In create_listing() to verify the seller holds tickets.
Marketplace
SEP-41 Token
transfer()
In purchase_ticket() to move payment from buyer to seller.
Marketplace
TicketNFT
transfer_from()
In purchase_ticket() to move the NFT from seller to buyer.
9. Configuration Change Impact Summary
Parameter
Change
Primary Impact
UPGRADE_DELAY_LEDGERS
Increase
Longer community review window before upgrades; slower emergency patches.