Launchpad & payout contracts
Deploy the whole economy in one click: a fixed-supply token launchpad whose fees land in an exploit-hardened vault, which auto-buys the on-chain company shares and pays the day's winners. The owner keeps manual deposit/withdraw; every other account reaches funds only through the daily autopayout.
One-click deploy
Compiles the bundle in your browser and sends every transaction in order — you just confirm in your wallet.
Testnets are free — start there.
Vault console
Runs the daily payout loop on your deployed contracts: queue winners, trigger the autopayout, adjust the stock split, and use the owner-only deposit and withdraw.
Your wallet confirms every transaction — nothing is signed without you. Deploying costs real gas on a live network; start on a testnet. Prefer doing it by hand? The sources below still work in Remix or with the script.
One-click bundle — token, launchpad & vault
SpaceTycoonOneClick.sol · 339 lines
Everything the deploy wizard sends, in one self-contained file: the ERC-1155 company shares with permanent caps, the fixed-supply game token, the ETH launchpad and the exploit-hardened payout vault with the daily autopayout.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/*
Space Tycoon — one-click deployment bundle
==========================================
TycoonShareToken — the on-chain company stocks (ERC-1155). Every company has a
fixed, permanent supply cap; only minters can mint and never
past the cap, so the total supply can never grow.
SpaceTycoonCore — the fixed-supply game token, the ETH launchpad and the payout
vault in one contract. Launchpad proceeds land in the vault;
once a day the vault auto-buys company shares for the
submitted winners and credits the cash part for claim.
The owner has manual deposit/withdraw. Every other account
…Share token
TycoonShareToken.sol · 61 lines
One ERC-1155 token id per listed company, each with a fixed supply minted once at deploy into the payout vault.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
/// @title TycoonShareToken
/// @notice Company shares for the Space Tycoon board: one token id per listed company.
contract TycoonShareToken is ERC1155, AccessControl {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant COMPANY_ADMIN_ROLE = keccak256("COMPANY_ADMIN_ROLE");
struct Company {
string ticker;
…Payout vault
TycoonPayoutVault.sol · 77 lines
Holds the entire fixed supply of every company token. Winners are paid by release from the vault, and no new shares can ever be minted.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/// @title TycoonPayoutVault
/// @notice Receives the whole fixed supply of every company token at deploy and
/// releases grants to winners. Holds the supply, never mints it.
contract TycoonPayoutVault is AccessControl, IERC1155Receiver {
bytes32 public constant PAYOUT_ROLE = keccak256("PAYOUT_ROLE");
…Dividend distributor
TycoonDividendDistributor.sol · 61 lines
Holds the dividend pot and pays every holder their share of each deposit. Claim-based, so a holder takes the money when they want it.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/access/Ownable.sol";
interface IERC20 {
function transfer(address to, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
interface ITycoonShareToken {
function balanceOf(address account, uint256 id) external view returns (uint256);
function totalSupply(uint256 id) external view returns (uint256);
}
…Game registry
TycoonGameRegistry.sol · 56 lines
Records a finished game and releases the winner's grant from the payout vault in one transaction. A game id can only ever be recorded once.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/access/AccessControl.sol";
interface ITycoonPayoutVault {
function releaseGrants(
bytes32 gameId,
address winner,
uint256[] calldata companyIds,
uint256[] calldata amounts
) external;
}
…One-command deploy script
deploy-tycoon.js · 68 lines
Hardhat script: deploys the four contracts, registers the ten companies, mints every company's fixed supply into the vault and locks the minter for good.
// One command: npx hardhat run scripts/deploy-tycoon.js --network <network>
const { ethers } = require("hardhat");
// Company ids are fixed by the board: 1..8 are the colour groups, 9 rail, 10 utility.
const COMPANIES = [
{ id: 1, ticker: "BRWN", name: "Brownstone Holdings", cap: 5000000 },
{ id: 2, ticker: "AQUA", name: "Aqua Marine Group", cap: 5000000 },
{ id: 3, ticker: "ROSE", name: "Rosewood Estates", cap: 5000000 },
{ id: 4, ticker: "ORNG", name: "Orange Grid Energy", cap: 5000000 },
{ id: 5, ticker: "REDX", name: "Redline Transit", cap: 5000000 },
{ id: 6, ticker: "GOLD", name: "Gold Coast Ventures", cap: 5000000 },
{ id: 7, ticker: "EMRD", name: "Emerald Parks", cap: 5000000 },
{ id: 8, ticker: "BLUX", name: "Bluechip Prime", cap: 5000000 },
{ id: 9, ticker: "RAIL", name: "Continental Rail", cap: 5000000 },
…Deploy order
Option A — Remix, no setup
Open remix.ethereum.org, create a file per contract below, paste the source. Remix fetches the OpenZeppelin imports on its own. Pick a compiler of 0.8.24 or newer, turn the optimiser on, then deploy in order: share token, payout vault, game registry, dividend distributor.
Option B — one command
In a Hardhat project with OpenZeppelin installed, drop the deploy script into scripts/, set PAYOUT_TOKEN to the ERC-20 your dividend pot pays in, then run the single command in the script's first line. It deploys all four, registers the ten companies, mints every company's fixed supply into the vault and renounces the minter so the supply can never grow.
Then wire the payouts
The script has already funded the vault and locked the supply. Grant RECORDER_ROLE to whichever address settles games, then record a game with recordGame(gameId, winner, netWorth, companyIds, amounts) and the vault pays the winner. Deposit the dividend pot with depositDividend(companyId, amount); holders claim with claim(companyId).