Manage Tickets
This page gives the procedures to buy, check, and redeem the tickets of a ciphernode. It is for the bond owner of a registered operator. At the end, you can change the ticket balance with the CLI or with contract calls, and you know which errors stop each step.
For the concepts behind tickets, read Tickets and sortition. For
every flag, see interfold ciphernode tickets.
Before you start
You need these items:
- A registered operator.
addTicketBalanceForreverts withNotRegisteredbefore registration. See Registration. - The bond owner wallet, with the ticket collateral and ETH for gas.
- For the CLI: an interfold configuration whose wallet is the bond owner. The examples use
/path/to/owner.yaml. The ticket commands send each transaction from the wallet of the configuration. The--operatorflag selects the operator position.
If the operator is its own bond owner, use the node configuration and omit --operator. The CLI
then uses the address of the configured wallet. If the bond owner is a Safe, use the
contract calls through the Safe interface.
On Sepolia, the fee token and the ticket collateral are the same token: MockUSDC, a test USDC that
anyone can mint. The faucet sends tokens to the wallet of the configuration, so use the bond-owner
configuration: interfold --config /path/to/owner.yaml faucet --chain sepolia. One call gives 1000
USDC and 1000 FOLD, which is enough for the 100 FOLD Sepolia bond. You can also call faucet() on
the Faucet contract from the bond owner, or call mint on MockUSDC.
The --amount values are token amounts, not ticket counts. tickets buy takes an amount of
ticket collateral. tickets burn takes an amount of tFOLD. The CLI converts the value with the
decimals of the token, so --amount 1000 means 1,000 whole tokens.
Check the ticket balance
Run the status command for the operator:
interfold ciphernode status --operator 0xOPERATORAdd --chain <name> when the configuration has more than one chain. Without --chain, the CLI uses
the first chain entry. The output has this format:
Ciphernode status on mainnet:
Operator key: 0xOPERATOR
Bond owner: 0xBOND_OWNER
Registered: true
Active: true
Exit pending: false
Ticket balance: 2000 (2 available)
Ciphernode bond: 32000
Pending exits: tickets=0, bond=0
Requirements: minTickets=1, ticketPrice=1000 tFOLD, ciphernodeBond=32000 FOLD
Committees: none| Field | Meaning |
|---|---|
Ticket balance | The tFOLD balance in token units. The number in parentheses is availableTickets. |
Active | The result of isActive(operator). See When a ciphernode is active. |
Exit pending | true while a deregistration waits for its exit delay. |
Pending exits | Ticket collateral and FOLD in the exit queue that the bond owner did not claim yet. |
Requirements | The live minTicketBalance, ticketPrice, and requiredCiphernodeBond. |
Committees | The committees that hold the collateral until releaseCommittee(e3Id). Each line shows the E3 ID, the membership, and the E3 stage. |
The ticket and exit values are also available from BondingRegistry with
getTicketBalance(operator), availableTickets(operator), pendingExits(operator), and
previewClaimable(operator). For the balance that an E3 used, call
getTicketBalanceAtBlock(operator, timepoint) with the requestBlock - 1 timepoint of that E3.
Buy tickets
To calculate the deposit, multiply the number of tickets by ticketPrice. For example, 2 tickets on
mainnet at 1,000 sUSDS shares each need a deposit of 2,000 sUSDS shares. A remainder below one
ticketPrice stays in the balance but does not give a ticket.
Read the ticket price
Run interfold ciphernode status --operator 0xOPERATOR.
Read ticketPrice in the Requirements line.
Deposit the collateral
Run the buy command from the bond owner configuration:
interfold --config /path/to/owner.yaml ciphernode tickets \
--operator 0xOPERATOR buy --amount 2000The CLI reads the ticket token and its collateral token from BondingRegistry. If the allowance is
too low, the CLI first approves the ticket token contract for the amount. Then it calls
addTicketBalanceFor(operator, amount). The output shows the new ticket count, read back from the
chain:
Deposited 2000 <SYMBOL> for operator 0xOPERATOR. Ticket balance is now 2 tickets (tx: 0x…)Verify the status
Run interfold ciphernode status --operator 0xOPERATOR.
Make sure that Active is true and that the available ticket count is correct.
Redeem tickets
A redemption has three parts. The burn removes the tickets at once. The collateral then waits in the
exit queue for exitDelay. After the delay, a claim pays the collateral to the bond owner.
A burn takes effect in the same transaction and you cannot cancel it. If the balance drops below
minTicketBalance, the operator becomes inactive and cannot enter new committees. The collateral
in the exit queue stays slashable until the claim.
Burn the tickets
Run the burn command from the bond owner configuration. The amount is in tFOLD units:
interfold --config /path/to/owner.yaml ciphernode tickets \
--operator 0xOPERATOR burn --amount 1000The CLI calls removeTicketBalanceFor(operator, amount). The registry burns the tFOLD and queues
the same amount of collateral for exitDelay seconds. The output shows the new ticket count:
Burned 1000 tFOLD from operator 0xOPERATOR. Ticket balance is now 1 tickets (tx: 0x…)interfold ciphernode deactivate --tickets <amount> sends the same transaction.
Wait for the exit delay
Run interfold ciphernode status --operator 0xOPERATOR to see the Pending exits amounts.
To see the amount that is ready now, call previewClaimable(operator) on BondingRegistry.
Claim the collateral
Run the claim command:
interfold --config /path/to/owner.yaml ciphernode bond \
--operator 0xOPERATOR claim --max-bond 0--max-bond 0 claims only ticket collateral. Any account can send this claim, and the collateral
always goes to the bond owner. Without --max-ticket and --max-bond, the command claims all the
unlocked ticket collateral and FOLD, and only the bond owner can send it. The output is
Claimed exits for operator 0xOPERATOR (tx: 0x…).
The contract call for the claim is
claimExitsFor(operator, maxTicketAmount, maxCiphernodeBondAmount) on BondingRegistry. To claim
everything with a contract call, the bond owner sets both maximums to the largest uint256 value.
The Manage the position section of the hosted operator guide (opens in a new tab) burns tickets and claims the collateral from a browser wallet.
Keep the balance healthy
- Deposit before demand. An E3 uses the balance at
requestBlock - 1. A deposit counts only for E3s that are requested after the deposit block. - Keep a margin above the minimum. A ticket slash burns tFOLD from the active balance first. A
governance increase of
ticketPricealso reduces the ticket count of the same collateral. Either change can make the operator inactive. - Match tickets to capacity. The node takes part in at most one E3 for each ticket at the same time. More tickets let the node serve more E3s in parallel, so the host needs the resources for them. See Requirements.
- Watch the events.
TicketBalanceUpdatedreports each balance change, andOperatorActivationChangedreports each change of the active status.
Errors
| Error | Cause | Action |
|---|---|---|
NotRegistered | The operator is not registered. | Register the operator first. |
NotBondOwner(caller, operator) | The wallet that sent the transaction is not the bond owner. | Use the bond owner configuration or wallet. |
ExitInProgress | A deregistration waits for its exit delay. | Wait until the exit delay ends. |
OperatorUnderSlash | A slash proposal against the operator is open. | Wait until the proposal is executed, cancelled, or expired. |
InsufficientBalance | The burn amount is larger than the tFOLD balance. | Burn a smaller amount. |
ZeroAmount | The amount is 0. | Use an amount larger than 0. |
ExitNotReady | No queued amount is unlocked yet. | Wait for the exit delay, then claim again. |
OperatorInActiveCommittee | The operator is on a committee whose E3 is not terminal yet. | Wait until the E3 completes or fails and the committee is released. |
Fractional precision exceeds token decimals | The CLI amount has more decimal places than the token. | Use fewer decimal places. |