CeosCompanyNFT
The CeosCompanyNFT contract is the access gate to the ceos.run economy. Each NFT represents one AI company slot. Holding a CeosCard NFT is the prerequisite for deploying a company with its 7-agent C-Suite team.
Deployed at: 0xffC3994DfCf1F0ee6D30F41D8F8AaB73bd0aEB61 (Base Sepolia)
Key Properties
| Property | Value |
|---|---|
| Token Standard | ERC-721 (Enumerable) |
| Max Supply | 10,000 |
| Payment Token | USDC (6 decimals) |
| Tranches | 3 (1K / 3K / 6K) |
| Max Batch Size | 5 per transaction |
| Token IDs | Start at 1 |
Tranche System
The 10,000 total supply is divided into three tranches, each activated manually by the contract owner:
| Tranche | Supply | Token IDs | Staking Boost |
|---|---|---|---|
| CeosCard Black (T1) | 1,000 | 1 — 1,000 | 5x $CEO yield |
| CeosCard Gold (T2) | 3,000 | 1,001 — 4,000 | 3x $CEO yield |
| CeosCard Silver (T3) | 6,000 | 4,001 — 10,000 | 2x $CEO yield |
Earlier tranches grant higher staking multipliers in StakingRewardsV2. The tranche is determined by the tokenId range, not a stored property.
Interface
Minting
/// @notice Mint a single CeosCard NFT with USDC payment.
/// Caller must approve USDC spend before calling.
function mint() external;
/// @notice Batch mint multiple CeosCard NFTs (max 5 per tx).
/// @param quantity Number of NFTs to mint (1-5)
function mintBatch(uint256 quantity) external;Both functions pull USDC from the caller via SafeERC20.safeTransferFrom. The mint price is set per-tranche by the owner.
Company Deploy Gate
/// @notice Check if an address has an unused NFT available for deploy.
/// @param account The address to check
/// @return tokenId The first unused token ID (0 if none)
function canDeploy(address account) external view returns (uint256 tokenId);
/// @notice Mark an NFT as having deployed its company (platform-only).
/// @param tokenId The NFT token ID
function markCompanyDeployed(uint256 tokenId) external;
/// @notice Get the current CEO of a company (NFT owner).
/// @param tokenId The NFT token ID
/// @return The address of the NFT owner
function companyOwner(uint256 tokenId) external view returns (address);The deploy gate ensures each NFT can only deploy one company. The platform contract calls markCompanyDeployed after successful company creation. Transferring the NFT transfers company ownership — agents, wallets, and decision history stay with the company, but the new holder gains strategic control.
Tranche Management (Owner Only)
/// @notice Activate a new mint tranche with price.
/// @param tranche Tranche number (1, 2, or 3)
/// @param price USDC price per NFT (6 decimals, e.g. 100e6 = $100)
function activateTranche(uint256 tranche, uint256 price) external;
/// @notice Pause or unpause minting.
/// @param active True to enable, false to pause
function setMintActive(bool active) external;
/// @notice Update mint price mid-tranche.
/// @param price New USDC price (6 decimals)
function setMintPrice(uint256 price) external;
/// @notice Set platform contract for company deploy gate.
/// @param _platform New platform contract address
function setPlatform(address _platform) external;
/// @notice Withdraw accumulated USDC to a specified address.
/// @param to Recipient address
function withdraw(address to) external;View Functions
/// @notice Total NFTs minted across all tranches.
function totalMinted() external view returns (uint256);
/// @notice Remaining NFTs in the current tranche.
function trancheRemaining() external view returns (uint256);
/// @notice Current active tranche (0 = not started, 1-3).
function currentTranche() external view returns (uint256);
/// @notice USDC mint price (6 decimals).
function mintPrice() external view returns (uint256);
/// @notice Whether minting is currently active.
function mintActive() external view returns (bool);Events
event Minted(address indexed to, uint256 indexed tokenId, uint256 tranche, uint256 price);
event CompanyDeployed(uint256 indexed tokenId, address indexed owner);
event TrancheActivated(uint256 tranche, uint256 price, uint256 supply);
event PlatformUpdated(address indexed oldPlatform, address indexed newPlatform);
event FundsWithdrawn(address indexed to, uint256 amount);Errors
error MaxSupplyReached(); // 10K cap hit
error TrancheNotActive(); // Minting paused or no tranche activated
error TrancheSoldOut(); // Current tranche fully minted
error CompanyAlreadyDeployed(uint256 tokenId); // NFT already used
error InvalidTranche(); // Tranche not 1, 2, or 3
error TrancheAlreadyActive(); // Cannot go backwards
error OnlyPlatform(); // Caller is not platform contract
error InvalidQuantity(); // Batch size 0 or > 5Mint Flow
- Owner calls
activateTranche(1, 100e6)to start Tranche 1 at $100 USDC. - User approves USDC spend:
usdc.approve(ceosCompanyNFT, 100e6). - User calls
mint(). Contract pulls 100 USDC and mints token ID to caller. - User now holds a CeosCard. Platform checks
canDeploy(user)and finds the unused token. - After company creation, platform calls
markCompanyDeployed(tokenId). - That NFT is permanently bound to the deployed company. Transfer = M&A.
Security
ReentrancyGuardonmint()andmintBatch()SafeERC20for all USDC transfers- Owner-only tranche activation, platform setting, and fund withdrawal
- Platform-only
markCompanyDeployedprevents unauthorized company creation - Sequential token IDs prevent gaps