Download contracts/FORGE.sol from Snapkitty/forge-token: direct link, hf CLI and curl.
- Browser
- Download file 11.7 kB
-
https://huggingface.co/Snapkitty/forge-token/resolve/main/contracts/FORGE.sol
- Command line
-
hf download hf://Snapkitty/forge-token/contracts/FORGE.sol
-
curl -L -o FORGE.sol https://huggingface.co/Snapkitty/forge-token/resolve/main/contracts/FORGE.sol
11.7 kB
| // SPDX-License-Identifier: MIT | |
| pragma solidity ^0.8.24; | |
| /** | |
| * @title FORGE Token (FRG) | |
| * @author CIPHER (Cryptographic Agent) — co-architecting with NOVA | |
| * @notice FORGE is the native inter-agent protocol token of the SnapKitty | |
| * Stochastic Autonomous Compute Mesh (SACM). It is a UTILITY TOKEN only. | |
| * It is NOT a security, investment contract, or financial instrument. | |
| * No public sale has occurred. All distributions are subject to legal | |
| * review by Jessica Lee Westerhoff, CPA, and applicable counsel before | |
| * any public offering. This token confers no ownership, equity, dividends, | |
| * or profit-sharing rights in SnapKitty Collective LLC or any affiliated | |
| * entity. | |
| * | |
| * @dev ERC-20 implementation built on OpenZeppelin 5.x base contracts. | |
| * Key mechanics: | |
| * - Hard cap: 21,000,000 FRG (twenty-one million, 18 decimals) — VAULT ruling 2026-05-21 | |
| * - Mint gated to WORM-verified work events via the treasury multisig | |
| * - Burn mechanic for SEALFORGE tier upgrades | |
| * - Governance weight: 1 FRG = 1 vote, capped at 1% of supply per address | |
| * - Emergency pause controlled by the Architect role | |
| * | |
| * @custom:security-contact legal@snapkitty.io | |
| * @custom:deployed-by SnapKitty Collective LLC — EIN 41-5105572 | |
| * @custom:holding-entity Bel Esprit D'Accord Trust — EIN 41-6630640 | |
| */ | |
| import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | |
| import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; | |
| import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol"; | |
| import "@openzeppelin/contracts/access/AccessControl.sol"; | |
| import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; | |
| contract FORGE is ERC20, ERC20Burnable, ERC20Pausable, AccessControl, ReentrancyGuard { | |
| // ========================================================================= | |
| // ROLES | |
| // ========================================================================= | |
| /// @notice ARCHITECT_ROLE: highest privilege — pause/unpause, role management | |
| bytes32 public constant ARCHITECT_ROLE = keccak256("ARCHITECT_ROLE"); | |
| /// @notice MINTER_ROLE: granted exclusively to the SnapKitty Treasury multisig | |
| /// Minting is triggered only after a WORM-chain entry is verified off-chain | |
| /// and submitted by the treasury. No permissionless minting exists. | |
| bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); | |
| /// @notice BURNER_ROLE: granted to the SEALFORGE upgrade contract | |
| /// Allows programmatic burns on tier-upgrade events | |
| bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE"); | |
| // ========================================================================= | |
| // SUPPLY CONSTANTS | |
| // ========================================================================= | |
| /// @notice Absolute hard cap — 21,000,000 FRG (VAULT supply ruling 2026-05-21) | |
| uint256 public constant MAX_SUPPLY = 21_000_000 * 10 ** 18; | |
| /// @notice Governance vote cap per address: 1% of MAX_SUPPLY | |
| uint256 public constant GOVERNANCE_CAP = MAX_SUPPLY / 100; | |
| // ========================================================================= | |
| // STATE | |
| // ========================================================================= | |
| /// @notice Total FRG burned to date (informational, tracked across all burn paths) | |
| uint256 public totalBurned; | |
| /// @notice WORM entry hash => minted flag — prevents replay of the same | |
| /// WORM-sealed work event being used to mint twice | |
| mapping(bytes32 => bool) public wormEntryMinted; | |
| // ========================================================================= | |
| // EVENTS | |
| // ========================================================================= | |
| /// @notice Emitted on every WORM-gated mint | |
| /// @param recipient Address receiving minted tokens | |
| /// @param amount Amount minted (18-decimal units) | |
| /// @param wormEntryHash HMAC-SHA256 hash of the sealed WORM ledger entry | |
| event WORMMint( | |
| address indexed recipient, | |
| uint256 amount, | |
| bytes32 indexed wormEntryHash | |
| ); | |
| /// @notice Emitted when SEALFORGE upgrade burns tokens | |
| /// @param burner Address whose tokens were burned | |
| /// @param amount Amount burned | |
| /// @param tier SEALFORGE tier purchased ("basic", "pro", "architect") | |
| event SealforgeBurn( | |
| address indexed burner, | |
| uint256 amount, | |
| string tier | |
| ); | |
| /// @notice Emitted on emergency pause | |
| event EmergencyPause(address indexed architect, string reason); | |
| /// @notice Emitted on unpause | |
| event EmergencyUnpause(address indexed architect); | |
| // ========================================================================= | |
| // CONSTRUCTOR | |
| // ========================================================================= | |
| /** | |
| * @notice Deploy MAGMA token. | |
| * @param architect Address of the Architect (multisig recommended — Gnosis Safe) | |
| * @param treasury Address of the SnapKitty Treasury multisig (receives MINTER_ROLE) | |
| */ | |
| constructor(address architect, address treasury) ERC20("FORGE", "FRG") { | |
| require(architect != address(0), "FORGE: zero architect address"); | |
| require(treasury != address(0), "FORGE: zero treasury address"); | |
| // Grant roles | |
| _grantRole(DEFAULT_ADMIN_ROLE, architect); | |
| _grantRole(ARCHITECT_ROLE, architect); | |
| _grantRole(MINTER_ROLE, treasury); | |
| // No tokens minted at construction — all distribution is WORM-event driven | |
| // Team / ecosystem allocations are minted by the treasury against | |
| // pre-scheduled WORM entries at genesis. | |
| } | |
| // ========================================================================= | |
| // MINT — WORM-GATED | |
| // ========================================================================= | |
| /** | |
| * @notice Mint MGM tokens to `recipient` for a verified WORM work event. | |
| * @dev Only callable by an address holding MINTER_ROLE (treasury multisig). | |
| * The `wormEntryHash` is the HMAC-SHA256 of the sealed WORM ledger entry | |
| * and acts as a nonce — each entry can only be redeemed once. | |
| * The function reverts if minting would exceed MAX_SUPPLY. | |
| * | |
| * @param recipient Address to receive minted tokens | |
| * @param amount Amount to mint (18-decimal units) | |
| * @param wormEntryHash HMAC-SHA256 bytes32 digest of the WORM ledger entry | |
| */ | |
| function wormMint( | |
| address recipient, | |
| uint256 amount, | |
| bytes32 wormEntryHash | |
| ) | |
| external | |
| nonReentrant | |
| whenNotPaused | |
| onlyRole(MINTER_ROLE) | |
| { | |
| require(recipient != address(0), "FORGE: mint to zero address"); | |
| require(amount > 0, "FORGE: zero mint amount"); | |
| require(!wormEntryMinted[wormEntryHash], "FORGE: WORM entry already redeemed"); | |
| require(totalSupply() + amount <= MAX_SUPPLY, "FORGE: hard cap exceeded"); | |
| wormEntryMinted[wormEntryHash] = true; | |
| _mint(recipient, amount); | |
| emit WORMMint(recipient, amount, wormEntryHash); | |
| } | |
| // ========================================================================= | |
| // BURN — SEALFORGE TIER UPGRADES | |
| // ========================================================================= | |
| /** | |
| * @notice Burn MGM from `burner` for a SEALFORGE tier upgrade. | |
| * @dev Callable by BURNER_ROLE (SEALFORGE upgrade contract) OR by the | |
| * token holder themselves (standard ERC20Burnable.burn also works). | |
| * This route records the tier string in the event for analytics. | |
| * | |
| * @param burner Address whose tokens are burned | |
| * @param amount Amount to burn (18-decimal units) | |
| * @param tier Human-readable SEALFORGE tier label | |
| */ | |
| function sealforgeBurn( | |
| address burner, | |
| uint256 amount, | |
| string calldata tier | |
| ) | |
| external | |
| nonReentrant | |
| whenNotPaused | |
| onlyRole(BURNER_ROLE) | |
| { | |
| require(burner != address(0), "FORGE: burn from zero address"); | |
| require(amount > 0, "FORGE: zero burn amount"); | |
| require(balanceOf(burner) >= amount, "FORGE: insufficient balance"); | |
| _burn(burner, amount); | |
| emit SealforgeBurn(burner, amount, tier); | |
| } | |
| // ========================================================================= | |
| // GOVERNANCE WEIGHT | |
| // ========================================================================= | |
| /** | |
| * @notice Returns governance voting weight for `account`. | |
| * @dev Weight equals token balance, capped at 1% of MAX_SUPPLY (GOVERNANCE_CAP). | |
| * This prevents whale capture of governance decisions. | |
| * Integrate this function in any on-chain governance module (Governor.sol). | |
| * | |
| * @param account Address to query | |
| * @return weight Effective governance votes (capped) | |
| */ | |
| function governanceWeight(address account) external view returns (uint256 weight) { | |
| uint256 balance = balanceOf(account); | |
| weight = balance > GOVERNANCE_CAP ? GOVERNANCE_CAP : balance; | |
| } | |
| // ========================================================================= | |
| // EMERGENCY PAUSE — ARCHITECT ONLY | |
| // ========================================================================= | |
| /** | |
| * @notice Pause all token transfers, mints, and burns. | |
| * @dev Only the Architect role may pause. Emits reason for transparency. | |
| * @param reason Human-readable reason for the pause (stored in event log) | |
| */ | |
| function emergencyPause(string calldata reason) | |
| external | |
| onlyRole(ARCHITECT_ROLE) | |
| { | |
| _pause(); | |
| emit EmergencyPause(msg.sender, reason); | |
| } | |
| /** | |
| * @notice Unpause the contract after an emergency. | |
| * @dev Only the Architect role may unpause. | |
| */ | |
| function emergencyUnpause() | |
| external | |
| onlyRole(ARCHITECT_ROLE) | |
| { | |
| _unpause(); | |
| emit EmergencyUnpause(msg.sender); | |
| } | |
| // ========================================================================= | |
| // SUPPLY INSPECTION | |
| // ========================================================================= | |
| /** | |
| * @notice Returns the remaining mintable supply. | |
| * @return Tokens that can still be minted before hitting MAX_SUPPLY | |
| */ | |
| function remainingMintable() external view returns (uint256) { | |
| return MAX_SUPPLY - totalSupply(); | |
| } | |
| // ========================================================================= | |
| // OVERRIDES REQUIRED BY SOLIDITY | |
| // ========================================================================= | |
| /// @dev Resolves diamond inheritance conflict. Tracks totalBurned for all | |
| /// burn paths — burns are _update calls where `to == address(0)`. | |
| function _update( | |
| address from, | |
| address to, | |
| uint256 value | |
| ) | |
| internal | |
| override(ERC20, ERC20Pausable) | |
| { | |
| if (to == address(0)) { | |
| totalBurned += value; | |
| } | |
| super._update(from, to, value); | |
| } | |
| // ========================================================================= | |
| // INTERFACE SUPPORT | |
| // ========================================================================= | |
| /** | |
| * @dev Returns true for ERC-20, AccessControl, and ERC-165 interfaces. | |
| */ | |
| function supportsInterface(bytes4 interfaceId) | |
| public | |
| view | |
| override(AccessControl) | |
| returns (bool) | |
| { | |
| return super.supportsInterface(interfaceId); | |
| } | |
| } | |