Host Guide

The host is the contract's only privileged role. This page collects every action a host can take, in roughly the order they're needed across a deployment's lifetime.

Privileges (full list)

Action Function Effect
Open the next game send ETH (any time gameId == 0 or current game is over) Locks nextGameConfig into gameConfigRecord[newGameId] and seeds entry 1
Update next-game config setNextGameConfig(...) Writes nextGameConfig; takes effect when next game starts
Withdraw accrued deposit fees withdrawDepositFees() Sweeps accruedDepositFees to the host; works any time, survives across games
Sweep last-cohort leftover clearLeftoverAdoptionBonus(gameId) One-time, after the game is over; sends Pool[C] to the host
Initiate host transfer initiateHostTransfer(newAddress) Step 1 of two-step transfer
Cancel host transfer cancelHostTransfer() Aborts a pending transfer
(Pending host) accept transfer acceptHostTransfer() Step 2 โ€” finalizes the role swap

The host has no ability to:

  • Change parameters of an active game (every field of gameConfig is locked into gameConfigRecord[gameId] at game start)
  • Withdraw player ETH from prize pools or adoption-bonus pools (only the last cohort's pool is sweepable, and only after the game ends)
  • Reverse or block a player's claim

Starting game N+1

After a game ends, the host opens the next game by simply sending ETH to the contract. Specifically:

  1. (Optional) Call setNextGameConfig(...) if any parameters need to change. The change is queued in nextGameConfig until you start the next game.
  2. Send ETH from the host wallet. The contract:
    • Confirms isGameOver() for the current game (or gameId == 0 for the very first game)
    • Increments gameId
    • Snapshots nextGameConfig into gameConfigRecord[gameId]
    • Treats the host's ETH as the seeding entry
    • Emits GameStarted with the locked-in config

The host's seeding entry is a normal entry โ€” it gets entrant ID 1 and is eligible to win prizes like any other.

Withdrawing accrued fees

accruedDepositFees accumulates across all games. The host pulls it via:

withdrawDepositFees()

This:

  • Reverts with OnlyHost if called by anyone else
  • Resets accruedDepositFees to 0 before the transfer (CEI pattern)
  • Emits DepositFeesWithdrawn(host, amount)
  • Is a no-op-with-event if accruedDepositFees == 0

Accrued fees follow the host role: after a host transfer, the new host withdraws fees that accrued under the old host. The contract never sends fees to a stale address.

Sweeping the last cohort's adoption-bonus pool

After the game ends, call clearLeftoverAdoptionBonus(gameId). This is a one-time action per game and sends adoptionBonusPrizePool[gameId][C] (the last cohort's pool, which is otherwise unclaimable) to the host.

For a discussion of why the last cohort's pool is host revenue, see Adoption Bonus & Cohorts โ†’ Leftover handling.

Two-step host transfer

Host transfer is two-step with zero-address validation: the current host nominates a successor, and the successor must accept before the role moves. This prevents a typo or compromised key from permanently bricking the contract.

// 1. Current host nominates a successor
initiateHostTransfer(newHostAddress);

// 2. Successor accepts (must be called by the pending address)
acceptHostTransfer();

// (alternative) Current host aborts
cancelHostTransfer();

Until step 2 is called by the pending address, the current host is unchanged. initiateHostTransfer(address(0)) reverts with InvalidHostAddress.

Operational hardening recommendations

The contract guards the mechanics of the host role, but the host's key itself is your responsibility. We recommend:

  • Use a multisig (e.g. 2-of-3 Safe) as the host. Even a small multisig dramatically reduces key-compromise risk.
  • Don't reuse the deployer EOA for ongoing operations. Transfer the host role to your operational signer immediately after deploy.
  • Document an incident-response plan: who has the host key, how to communicate to users, what can be done post-game-start.
  • Monitor on-chain events: index GameStarted, GameEntered, GameConfigUpdated, and AdoptionBonusTransferFailed, and alert on unusual patterns.
  • Verify the contract on Etherscan so users can read source. (Not done automatically by the deploy script.)

Common mistakes to avoid

  • Setting both proportions to zero. Reverts at config time with ZeroProportions, but be aware: this would also revert every entry.
  • Setting depositFeeBps > 1000. Reverts with DepositFeeTooHigh.
  • Setting minTicketsBeforeEnd to a number you can't reach. A game stuck below its floor can never end, which also blocks every future game (a new game can only start once the current one is over). The only recovery is for the host to top the game up to the floor and then let the deadline elapse. See Minimum Tickets Before End.
  • Calling setNextGameConfig mid-game and expecting it to take effect. It only writes to nextGameConfig; the active game's parameters are locked.
  • Calling clearLeftoverAdoptionBonus before the game is over. Reverts with GameNotFinished.

results matching ""

    No results matching ""