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
gameConfigis locked intogameConfigRecord[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:
- (Optional) Call
setNextGameConfig(...)if any parameters need to change. The change is queued innextGameConfiguntil you start the next game. - Send ETH from the host wallet. The contract:
- Confirms
isGameOver()for the current game (orgameId == 0for the very first game) - Increments
gameId - Snapshots
nextGameConfigintogameConfigRecord[gameId] - Treats the host's ETH as the seeding entry
- Emits
GameStartedwith the locked-in config
- Confirms
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
OnlyHostif called by anyone else - Resets
accruedDepositFeesto0before 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, andAdoptionBonusTransferFailed, 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 withDepositFeeTooHigh. - Setting
minTicketsBeforeEndto 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
setNextGameConfigmid-game and expecting it to take effect. It only writes tonextGameConfig; the active game's parameters are locked. - Calling
clearLeftoverAdoptionBonusbefore the game is over. Reverts withGameNotFinished.