TicketMaster leverages Ekubo's TWAMM extension to deliver demand-based, market-rate pricing for Dungeon Tickets. Built as an extension to OpenZeppelin's ERC20 component, this system provides a stateful flow that automates TWAMM pool initialization, order creation, and distribution of proceeds. The contract monitors Ekubo's on-chain oracle price feed over a configurable lookback period and can temporarily throttle issuance when the market trades below a configured threshold, resuming once conditions recover.
src/contract.cairo– TicketMaster contract that owns the ERC20 logic and the TWAMM orchestrationsrc/interfaces.cairo– Starknet interface exposing the on-chain API consumed by clients/testssrc/utils.cairo– Time-alignment and TWAMM fee helpers shared by the contract and inline testssrc/constants.cairo– Error strings and math constants reused across modulestests/– Starknet Foundry integration and fork teststarget/,.snfoundry_cache/– Build artefacts (kept out of version control)
TicketMaster keeps a strict deployment state to protect critical actions:
- 0 – Initial: Deployment finished, Ekubo pools not yet initialized
- 1 – DistributionPoolInitialized:
init_distribution_poolstored the caller-supplied tick, initialized the distribution pool, and cached its identifier - 2 – LiquidityProvided:
provide_initial_liquidityminted/seeded the pool and cached bounds - 3 – DistributionStarted:
start_token_distributionopened the TWAMM order and locked supply
Transition enforcement (assertions on deployment_state) is the primary access-control barrier.
constructor(
owner: ContractAddress,
name: ByteArray,
symbol: ByteArray,
total_supply: u128,
distribution_pool_fee: u128,
payment_token: ContractAddress,
buyback_token: ContractAddress,
core_address: ContractAddress,
positions_address: ContractAddress,
position_nft_address: ContractAddress,
extension_address: ContractAddress,
registry_address: ContractAddress,
oracle_address: ContractAddress,
issuance_reduction_price_x128: u256,
issuance_reduction_price_duration: u64,
issuance_reduction_bips: u128,
treasury_address: ContractAddress,
recipients: Array<ContractAddress>,
amounts: Array<u256>,
distribution_end_time: u64,
buyback_order_config: BuybackOrderConfig,
)
- Registers the token with Ekubo's on-chain registry (mints 1 unit directly to the registry)
- Mints the distribution ERC20 to a configurable list of recipients and records the remainder for
TWAMM execution (
tokens_for_distribution) - Stores Ekubo dispatchers (core, positions, registry, extension), the associated position NFT address, oracle access, and bootstrap parameters for both the distribution and buyback legs
- Defers pool ticks and seed liquidity to owner-only bootstrap calls so deployment-time pricing can be computed off-chain after the contract address is known
- Validates and caches issuance throttling configuration: a Q128 price threshold (
issuance_reduction_price_x128), a lookback duration in seconds (issuance_reduction_price_duration, owner-configurable post-deployment), and a basis-point reduction (issuance_reduction_bips) that controls how much the distribution rate decreases when Ekubo's on-chain oracle reports prices below the threshold - Accepts
buyback_order_configto configure buyback TWAMM order constraints (min/max delay, min/max duration, fee) - Aligns both optional start and mandatory end times to Ekubo's TWAMM bucket size; the current start time is tracked separately so restarts and throttling can reuse the most recent activation point
deployment_statestarts at0; time metadata is populated later by TWAMM calls
The contract follows a strict four-phase deployment sequence:
-
Initialize Distribution Pool –
init_distribution_pool(distribution_tick)(owner-only)- Takes the distribution pool's initial tick as a parameter (must be computed off-chain after contract deployment)
- Invokes Ekubo Core's
initialize_poolto create the distribution pool - Caches the resulting pool identifier and advances state to
1 (DistributionPoolInitialized)
-
Seed Initial Liquidity –
provide_initial_liquidity(payment_amount, dungeon_amount, min_liquidity)(owner-only)- Transfers
payment_amountof payment tokens from the caller to the contract - Mints
dungeon_amountof dungeon tickets directly to Ekubo Positions contract - Calls Ekubo's
mint_and_deposit_and_clear_bothwith symmetric bounds to establish the initial liquidity position - Validates that the resulting liquidity meets the
min_liquiditythreshold - Stores the liquidity position ID for future reference
- Advances state to
2 (LiquidityProvided)
- Transfers
-
Start Token Distribution –
start_token_distribution()(callable by anyone once liquidity is provided)- Mints the remaining distribution supply (
tokens_for_distribution) to Ekubo Positions - Opens a TWAMM sell order via
mint_and_increase_sell_amount - Aligns the end time using
utils::get_buyback_endtimeand caps it withutils::get_max_twamm_duration() - Caches the position NFT token ID and advances state to
3 (DistributionStarted)
- Mints the remaining distribution supply (
-
Recycle Proceeds – Ongoing operations after distribution starts:
claim_proceeds(): Withdraws realized payment token sales from the distribution TWAMM orderdistribute_proceeds(end_time): Uses all proceeds to create a new TWAMM buyback order that starts immediately and runs untilend_timeclaim_and_distribute_buybacks(limit): Iterates through matured buyback orders, withdrawing completed buyback tokens and forwarding them to the treasury address
The constructor accepts a BuybackOrderConfig structure that defines constraints for buyback TWAMM orders created
during proceeds distribution. This configuration includes:
min_delay/max_delay: (Currently unused - buyback orders always start immediately) Reserved for future usemin_duration/max_duration: Valid duration range (in seconds) for the buyback order executionfee: The pool fee tier to use for buyback orders (encoded as a Q128 value)
These constraints ensure buyback orders are created with parameters that match the protocol's operational requirements
and prevent invalid TWAMM order configurations. Note that all buyback orders start immediately (start_time = 0)
upon calling distribute_proceeds(end_time).
The contract implements dynamic issuance throttling that responds to market conditions:
enable_low_issuance_mode()checks the average price over the configured lookback period (specified byissuance_reduction_price_durationin seconds, owner-configurable) returned by Ekubo's on-chain oracle. When the average price drops below the configured Q128 threshold (issuance_reduction_price_x128), the function reduces the active distribution sale rate byissuance_reduction_bips(basis points) and holds the reclaimed tokens on the contract. Returns the number of tokens returned from the TWAMM order.disable_low_issuance_mode()performs the inverse operation: once the average price climbs back above the threshold over the same lookback period (querying Ekubo's on-chain oracle), the stored tokens are re-supplied to the TWAMM position and the original sale rate is restored. Returns the new distribution rate.force_enable_low_issuance_mode()andforce_disable_low_issuance_mode()(owner-only) allow emergency override of the oracle-driven checks, enabling manual control during oracle failures or extreme market conditions.- The contract exposes
is_low_issuance_mode(),get_low_issuance_returned_tokens(),get_issuance_reduction_price_x128(),get_issuance_reduction_price_duration(), andget_issuance_reduction_bips()so off-chain monitoring can track throttle state and configuration.
This mechanism protects against oversupply during unfavorable market conditions while maintaining flexibility to resume normal distribution rates when conditions improve. The force functions provide emergency controls for the contract owner to respond to unforeseen circumstances.
The on-chain interface (ITicketMaster) exposes:
- Lifecycle actions:
init_distribution_pool,provide_initial_liquidity,start_token_distribution,claim_proceeds,claim_and_distribute_buybacks,distribute_proceeds - Issuance controls:
enable_low_issuance_mode,disable_low_issuance_mode,force_enable_low_issuance_mode,force_disable_low_issuance_mode - Pool & order metadata:
get_distribution_pool_key,get_distribution_pool_key_hash,get_distribution_order_key,get_pool_id,get_distribution_fee,get_buyback_order_config,get_position_token_id,get_liquidity_position_id - Distribution telemetry:
get_token_distribution_rate,get_tokens_for_distribution,get_distribution_end_time,get_distribution_initial_tick,get_dungeon_ticket_price_x128 - Issuance telemetry:
is_low_issuance_mode,get_issuance_reduction_price_x128,get_issuance_reduction_price_duration,get_issuance_reduction_bips - Administrative controls:
set_treasury_address,set_issuance_reduction_price_x128,set_issuance_reduction_price_duration,set_issuance_reduction_bips,set_buyback_order_config,withdraw_erc721,withdraw_erc20 - Deployment helpers:
get_deployed_at,get_payment_token,get_buyback_token,get_extension_address,get_core_dispatcher,get_positions_dispatcher,get_registry_dispatcher,get_oracle_address,get_treasury_address,is_pool_initialized,get_deployment_state
src/utils.cairo contains the shared helpers that power TWAMM alignment and fee validation:
get_buyback_endtime– aligns a timestamp to the closest valid TWAMM bucket (rounds to nearest bucket instead of always rounding up)time_difference_to_step_size– returns the correct Ekubo step size for a time deltaget_max_twamm_duration– global upper bound enforced bystart_token_distribution
- Scarb v2.12.2+
- Starknet Foundry v0.49.0+
- Cairo compiler 2.12.x
- Access to Ekubo core, positions, TWAMM extension and registry addresses for your target chain
# Clone the repository
git clone <repo-url>
cd ticket-master
# Create your environment file from the example
cp .env.example .env
# Then edit .env to fill in your account, RPC, token config, and initial liquidity
# Compile the package
scarb buildscarb build# Run the complete suite
snforge test
# Focus on time rounding helpers
snforge test util_tests::
# Execute against configured forks (see Scarb.toml for RPC details)
snforge test --fork mainnet
snforge test --fork sepolia
# Inspect Cairo resource usage
snforge test --detailed-resourcesscarb fmt- Unit tests live alongside their modules (for example,
src/utils.cairocovers TWAMM time alignment and fee validation) - Integration & fork tests under
tests/deploy TicketMaster, mock Ekubo calls where needed and exercise the full bootstrap flow; the#[fork("mainnet")]scenario turns real Ekubo addresses into regression coverage - Use
snforge test --detailed-resourcesto capture resource deltas whenever distribution logic changes
- State machine guards: Prevent re-entry into lifecycle phases out of order through strict
deployment_stateassertions - Address validation: All external addresses (tokens, Ekubo contracts, treasury) are validated against the zero address during construction
- Distribution supply protection: Distribution supply is only minted when the TWAMM order is opened, preventing stranded balances
- Time alignment: Clamps distribution windows and enforces Ekubo's maximum duration to prevent invalid TWAMM operations
- Issuance throttling safeguards: Validates the configured oracle price floor, lookback duration, and basis-point reduction before mutating the distribution rate. Ensures reduction bips are less than
BIPS_BASIS(10000) to prevent arithmetic errors - Emergency controls: The owner can use
withdraw_erc20andwithdraw_erc721to recover any ERC20 or ERC721 tokens from the contract - Administrative flexibility: The owner can adjust
issuance_reduction_price_durationviaset_issuance_reduction_price_durationto tune the oracle lookback period without redeployment - Revenue distribution: All proceeds are used for buybacks, with the resulting tokens sent to the treasury. The treasury address can be updated via
set_treasury_address - Registry integration: Token registration with Ekubo's registry is part of deployment, ensuring the token metadata is discoverable on-chain
- Format Cairo sources with
scarb fmt - Run
snforge test(add fork or fuzzing runs if behaviour touches Ekubo integrations) - Update documentation and tests alongside code changes
- Follow Conventional Commits (
feat:,fix:,refactor:, …) for git history
This project is released under the MIT License. See LICENSE for the full text.
- Ekubo for the TWAMM infrastructure
- OpenZeppelin for audited Cairo components
- Starknet Foundry for the testing toolkit