mirror of
https://github.com/luxfi/precompile.git
synced 2026-09-24 00:26:21 +00:00
chore: remove .DS_Store, orphaned .sol files, rewrite README
- Remove .DS_Store, add to .gitignore - Remove AIMining.sol, IAllowList.sol, TeleportBridge.sol (orphaned, not referenced from any Go code) - Rewrite README to match actual packages, addresses, and gas costs
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
.DS_Store
|
||||
AGENTS.md
|
||||
CLAUDE.md
|
||||
GEMINI.md
|
||||
|
||||
-333
@@ -1,333 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
/**
|
||||
* @title IAIMining
|
||||
* @notice Interface for the AI Mining precompile at address 0x0300
|
||||
* @dev Enables EVM contracts to interact with the Hanzo AI Mining Protocol
|
||||
*
|
||||
* This precompile provides:
|
||||
* - Mining balance queries for ML-DSA addresses
|
||||
* - ML-DSA (FIPS 204) signature verification
|
||||
* - Teleport transfer claiming from Hanzo L1
|
||||
* - Pending teleport queries
|
||||
*
|
||||
* References:
|
||||
* - LP-2000: AI Mining Standard
|
||||
* - HIP-006: Hanzo AI Mining Protocol
|
||||
* - ZIP-005: Zoo AI Mining Integration
|
||||
* - FIPS 204: Module-Lattice Digital Signature Algorithm (ML-DSA)
|
||||
*/
|
||||
interface IAIMining {
|
||||
// ============ Events ============
|
||||
|
||||
/// @notice Emitted when mining rewards are claimed via Teleport
|
||||
event TeleportClaimed(
|
||||
bytes32 indexed teleportId,
|
||||
address indexed recipient,
|
||||
uint256 amount
|
||||
);
|
||||
|
||||
/// @notice Emitted when ML-DSA signature verification is performed
|
||||
event MLDSAVerified(
|
||||
bytes32 indexed publicKeyHash,
|
||||
bytes32 indexed messageHash,
|
||||
bool success
|
||||
);
|
||||
|
||||
// ============ View Functions ============
|
||||
|
||||
/**
|
||||
* @notice Get the mining balance for an address
|
||||
* @param miner The address to query (derived from ML-DSA public key)
|
||||
* @return The mining balance in AI token atomic units
|
||||
*/
|
||||
function miningBalance(address miner) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice Verify an ML-DSA signature (FIPS 204)
|
||||
* @param publicKey The ML-DSA public key (1312-4627 bytes depending on security level)
|
||||
* @param message The message that was signed
|
||||
* @param signature The ML-DSA signature (2420-4627 bytes depending on security level)
|
||||
* @return True if signature is valid, false otherwise
|
||||
*
|
||||
* @dev Supported security levels:
|
||||
* - Level 2 (ML-DSA-44): 1312 byte pk, 2420 byte sig
|
||||
* - Level 3 (ML-DSA-65): 1952 byte pk, 3309 byte sig
|
||||
* - Level 5 (ML-DSA-87): 2592 byte pk, 4627 byte sig
|
||||
*/
|
||||
function verifyMLDSA(
|
||||
bytes calldata publicKey,
|
||||
bytes calldata message,
|
||||
bytes calldata signature
|
||||
) external view returns (bool);
|
||||
|
||||
/**
|
||||
* @notice Get the security level of an ML-DSA public key
|
||||
* @param publicKey The ML-DSA public key
|
||||
* @return level The security level (2, 3, or 5)
|
||||
*/
|
||||
function getSecurityLevel(bytes calldata publicKey) external pure returns (uint8 level);
|
||||
|
||||
/**
|
||||
* @notice Derive an address from an ML-DSA public key
|
||||
* @param publicKey The ML-DSA public key
|
||||
* @return The derived 20-byte address (BLAKE3 hash truncated)
|
||||
*/
|
||||
function deriveAddress(bytes calldata publicKey) external pure returns (address);
|
||||
|
||||
/**
|
||||
* @notice Get pending teleport transfers for a recipient
|
||||
* @param recipient The recipient address
|
||||
* @return Array of pending teleport IDs
|
||||
*/
|
||||
function pendingTeleports(address recipient) external view returns (bytes32[] memory);
|
||||
|
||||
/**
|
||||
* @notice Get details of a specific teleport transfer
|
||||
* @param teleportId The unique teleport identifier
|
||||
* @return sender The sender's ML-DSA public key hash
|
||||
* @return recipient The recipient address
|
||||
* @return amount The transfer amount
|
||||
* @return sourceChain The source chain ID (always Hanzo L1)
|
||||
* @return status The transfer status (0=pending, 1=claimed, 2=expired)
|
||||
*/
|
||||
function getTeleportDetails(bytes32 teleportId)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
bytes32 sender,
|
||||
address recipient,
|
||||
uint256 amount,
|
||||
uint256 sourceChain,
|
||||
uint8 status
|
||||
);
|
||||
|
||||
// ============ State-Changing Functions ============
|
||||
|
||||
/**
|
||||
* @notice Claim teleported AI rewards from Hanzo L1
|
||||
* @param teleportId The unique teleport transfer identifier
|
||||
* @return The amount of AI tokens claimed
|
||||
*
|
||||
* @dev Requirements:
|
||||
* - Teleport must exist and be in pending status
|
||||
* - Caller must be the designated recipient
|
||||
* - Teleport must not be expired (24 hour window)
|
||||
*/
|
||||
function claimTeleport(bytes32 teleportId) external returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice Batch claim multiple teleport transfers
|
||||
* @param teleportIds Array of teleport IDs to claim
|
||||
* @return totalAmount Total AI tokens claimed
|
||||
*/
|
||||
function batchClaimTeleports(bytes32[] calldata teleportIds) external returns (uint256 totalAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @title AIMiningPrecompile
|
||||
* @notice Implementation contract that wraps calls to the precompile at 0x0300
|
||||
* @dev This contract provides a convenient wrapper for calling the precompile
|
||||
* with proper error handling and gas estimation
|
||||
*/
|
||||
contract AIMiningPrecompile {
|
||||
/// @notice The precompile address for AI Mining operations
|
||||
address public constant PRECOMPILE_ADDRESS = address(0x0300);
|
||||
|
||||
/// @notice Chain IDs supported by Teleport
|
||||
uint256 public constant HANZO_EVM_CHAIN_ID = 36963;
|
||||
uint256 public constant ZOO_EVM_CHAIN_ID = 200200;
|
||||
uint256 public constant LUX_CCHAIN_CHAIN_ID = 96369;
|
||||
|
||||
/// @notice ML-DSA security levels
|
||||
uint8 public constant SECURITY_LEVEL_2 = 2;
|
||||
uint8 public constant SECURITY_LEVEL_3 = 3;
|
||||
uint8 public constant SECURITY_LEVEL_5 = 5;
|
||||
|
||||
/// @notice ML-DSA public key sizes per security level
|
||||
uint256 public constant PK_SIZE_LEVEL_2 = 1312;
|
||||
uint256 public constant PK_SIZE_LEVEL_3 = 1952;
|
||||
uint256 public constant PK_SIZE_LEVEL_5 = 2592;
|
||||
|
||||
/// @notice ML-DSA signature sizes per security level
|
||||
uint256 public constant SIG_SIZE_LEVEL_2 = 2420;
|
||||
uint256 public constant SIG_SIZE_LEVEL_3 = 3309;
|
||||
uint256 public constant SIG_SIZE_LEVEL_5 = 4627;
|
||||
|
||||
// ============ Errors ============
|
||||
|
||||
error PrecompileCallFailed();
|
||||
error InvalidPublicKeySize();
|
||||
error InvalidSignatureSize();
|
||||
error TeleportNotFound();
|
||||
error TeleportAlreadyClaimed();
|
||||
error TeleportExpired();
|
||||
error NotTeleportRecipient();
|
||||
|
||||
// ============ Events ============
|
||||
|
||||
event TeleportClaimedViaWrapper(
|
||||
bytes32 indexed teleportId,
|
||||
address indexed claimer,
|
||||
uint256 amount
|
||||
);
|
||||
|
||||
// ============ External Functions ============
|
||||
|
||||
/**
|
||||
* @notice Get mining balance for an address
|
||||
* @param miner The miner address to query
|
||||
* @return balance The mining balance
|
||||
*/
|
||||
function getMiningBalance(address miner) external view returns (uint256 balance) {
|
||||
(bool success, bytes memory result) = PRECOMPILE_ADDRESS.staticcall(
|
||||
abi.encodeWithSelector(IAIMining.miningBalance.selector, miner)
|
||||
);
|
||||
|
||||
if (!success) revert PrecompileCallFailed();
|
||||
return abi.decode(result, (uint256));
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Verify an ML-DSA signature
|
||||
* @param publicKey The signer's public key
|
||||
* @param message The signed message
|
||||
* @param signature The ML-DSA signature
|
||||
* @return isValid True if signature is valid
|
||||
*/
|
||||
function verifySignature(
|
||||
bytes calldata publicKey,
|
||||
bytes calldata message,
|
||||
bytes calldata signature
|
||||
) external view returns (bool isValid) {
|
||||
// Validate public key size
|
||||
if (publicKey.length != PK_SIZE_LEVEL_2 &&
|
||||
publicKey.length != PK_SIZE_LEVEL_3 &&
|
||||
publicKey.length != PK_SIZE_LEVEL_5) {
|
||||
revert InvalidPublicKeySize();
|
||||
}
|
||||
|
||||
// Validate signature size matches public key level
|
||||
uint8 level = _getSecurityLevelFromPKSize(publicKey.length);
|
||||
uint256 expectedSigSize = _getSignatureSizeForLevel(level);
|
||||
if (signature.length != expectedSigSize) {
|
||||
revert InvalidSignatureSize();
|
||||
}
|
||||
|
||||
(bool success, bytes memory result) = PRECOMPILE_ADDRESS.staticcall(
|
||||
abi.encodeWithSelector(
|
||||
IAIMining.verifyMLDSA.selector,
|
||||
publicKey,
|
||||
message,
|
||||
signature
|
||||
)
|
||||
);
|
||||
|
||||
if (!success) revert PrecompileCallFailed();
|
||||
return abi.decode(result, (bool));
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Claim a teleport transfer
|
||||
* @param teleportId The teleport to claim
|
||||
* @return amount The claimed amount
|
||||
*/
|
||||
function claim(bytes32 teleportId) external returns (uint256 amount) {
|
||||
(bool success, bytes memory result) = PRECOMPILE_ADDRESS.call(
|
||||
abi.encodeWithSelector(IAIMining.claimTeleport.selector, teleportId)
|
||||
);
|
||||
|
||||
if (!success) revert PrecompileCallFailed();
|
||||
amount = abi.decode(result, (uint256));
|
||||
|
||||
emit TeleportClaimedViaWrapper(teleportId, msg.sender, amount);
|
||||
return amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Get all pending teleports for caller
|
||||
* @return teleportIds Array of pending teleport IDs
|
||||
*/
|
||||
function getMyPendingTeleports() external view returns (bytes32[] memory teleportIds) {
|
||||
(bool success, bytes memory result) = PRECOMPILE_ADDRESS.staticcall(
|
||||
abi.encodeWithSelector(IAIMining.pendingTeleports.selector, msg.sender)
|
||||
);
|
||||
|
||||
if (!success) revert PrecompileCallFailed();
|
||||
return abi.decode(result, (bytes32[]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Derive address from ML-DSA public key
|
||||
* @param publicKey The public key bytes
|
||||
* @return addr The derived address
|
||||
*/
|
||||
function addressFromPublicKey(bytes calldata publicKey) external view returns (address addr) {
|
||||
(bool success, bytes memory result) = PRECOMPILE_ADDRESS.staticcall(
|
||||
abi.encodeWithSelector(IAIMining.deriveAddress.selector, publicKey)
|
||||
);
|
||||
|
||||
if (!success) revert PrecompileCallFailed();
|
||||
return abi.decode(result, (address));
|
||||
}
|
||||
|
||||
// ============ Internal Functions ============
|
||||
|
||||
function _getSecurityLevelFromPKSize(uint256 size) internal pure returns (uint8) {
|
||||
if (size == PK_SIZE_LEVEL_2) return SECURITY_LEVEL_2;
|
||||
if (size == PK_SIZE_LEVEL_3) return SECURITY_LEVEL_3;
|
||||
if (size == PK_SIZE_LEVEL_5) return SECURITY_LEVEL_5;
|
||||
revert InvalidPublicKeySize();
|
||||
}
|
||||
|
||||
function _getSignatureSizeForLevel(uint8 level) internal pure returns (uint256) {
|
||||
if (level == SECURITY_LEVEL_2) return SIG_SIZE_LEVEL_2;
|
||||
if (level == SECURITY_LEVEL_3) return SIG_SIZE_LEVEL_3;
|
||||
if (level == SECURITY_LEVEL_5) return SIG_SIZE_LEVEL_5;
|
||||
revert InvalidPublicKeySize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @title AIMiningHelper
|
||||
* @notice Helper library for AI Mining integration
|
||||
*/
|
||||
library AIMiningHelper {
|
||||
address constant PRECOMPILE = address(0x0300);
|
||||
|
||||
/**
|
||||
* @notice Quick check if an address has mining balance
|
||||
* @param miner The address to check
|
||||
* @return hasFunds True if balance > 0
|
||||
*/
|
||||
function hasMiningFunds(address miner) internal view returns (bool hasFunds) {
|
||||
(bool success, bytes memory result) = PRECOMPILE.staticcall(
|
||||
abi.encodeWithSelector(IAIMining.miningBalance.selector, miner)
|
||||
);
|
||||
|
||||
if (!success) return false;
|
||||
return abi.decode(result, (uint256)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Verify ML-DSA signature (returns false on failure instead of reverting)
|
||||
*/
|
||||
function safeVerifyMLDSA(
|
||||
bytes memory publicKey,
|
||||
bytes memory message,
|
||||
bytes memory signature
|
||||
) internal view returns (bool) {
|
||||
(bool success, bytes memory result) = PRECOMPILE.staticcall(
|
||||
abi.encodeWithSelector(
|
||||
IAIMining.verifyMLDSA.selector,
|
||||
publicKey,
|
||||
message,
|
||||
signature
|
||||
)
|
||||
);
|
||||
|
||||
if (!success) return false;
|
||||
return abi.decode(result, (bool));
|
||||
}
|
||||
}
|
||||
-141
@@ -1,141 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (C) 2025, Lux Industries, Inc. All rights reserved.
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
/**
|
||||
* @title IAllowList
|
||||
* @dev Base interface for allow-list managed precompiles
|
||||
*
|
||||
* The AllowList is a permission system used across multiple Lux EVM precompiles.
|
||||
* It defines four roles with different permission levels:
|
||||
*
|
||||
* Roles:
|
||||
* - None (0): No permissions
|
||||
* - Enabled (1): Can use the precompile functionality
|
||||
* - Admin (2): Can modify roles for any address
|
||||
* - Manager (3): Can modify roles for non-admin addresses (added in Durango)
|
||||
*
|
||||
* Role Hierarchy:
|
||||
* - Admin > Manager > Enabled > None
|
||||
* - Admins can set any role for any address
|
||||
* - Managers can set roles for Enabled and None addresses only
|
||||
*
|
||||
* Events:
|
||||
* - RoleSet: Emitted when a role is changed
|
||||
*/
|
||||
interface IAllowList {
|
||||
/**
|
||||
* @notice Emitted when a role is set
|
||||
* @param role The new role being set
|
||||
* @param account The address receiving the role
|
||||
* @param sender The address setting the role
|
||||
* @param oldRole The previous role of the account
|
||||
*/
|
||||
event RoleSet(uint256 indexed role, address indexed account, address indexed sender, uint256 oldRole);
|
||||
|
||||
/**
|
||||
* @notice Read the allow list role for an address
|
||||
* @param addr The address to check
|
||||
* @return role The role of the address (0=None, 1=Enabled, 2=Admin, 3=Manager)
|
||||
*/
|
||||
function readAllowList(address addr) external view returns (uint256 role);
|
||||
|
||||
/**
|
||||
* @notice Set an address as Admin (role 2)
|
||||
* @dev Only callable by Admin
|
||||
* @param addr The address to set as Admin
|
||||
*/
|
||||
function setAdmin(address addr) external;
|
||||
|
||||
/**
|
||||
* @notice Set an address as Enabled (role 1)
|
||||
* @dev Callable by Admin or Manager
|
||||
* @param addr The address to enable
|
||||
*/
|
||||
function setEnabled(address addr) external;
|
||||
|
||||
/**
|
||||
* @notice Set an address as Manager (role 3)
|
||||
* @dev Only callable by Admin. Added in Durango upgrade.
|
||||
* @param addr The address to set as Manager
|
||||
*/
|
||||
function setManager(address addr) external;
|
||||
|
||||
/**
|
||||
* @notice Remove all permissions from an address (role 0)
|
||||
* @dev Callable by Admin or Manager (for non-admin addresses)
|
||||
* @param addr The address to remove permissions from
|
||||
*/
|
||||
function setNone(address addr) external;
|
||||
}
|
||||
|
||||
/**
|
||||
* @title AllowListLib
|
||||
* @dev Library for working with AllowList precompiles
|
||||
*/
|
||||
library AllowListLib {
|
||||
/// @dev Role constants
|
||||
uint256 constant ROLE_NONE = 0;
|
||||
uint256 constant ROLE_ENABLED = 1;
|
||||
uint256 constant ROLE_ADMIN = 2;
|
||||
uint256 constant ROLE_MANAGER = 3;
|
||||
|
||||
/// @dev Gas costs
|
||||
uint256 constant READ_ALLOWLIST_GAS = 2600;
|
||||
uint256 constant MODIFY_ALLOWLIST_GAS = 20000;
|
||||
|
||||
error NotAdmin();
|
||||
error NotEnabled();
|
||||
error NotManager();
|
||||
|
||||
/**
|
||||
* @notice Check if an address has at least Enabled role
|
||||
* @param allowList The allow list precompile address
|
||||
* @param addr The address to check
|
||||
* @return True if enabled, admin, or manager
|
||||
*/
|
||||
function isEnabled(address allowList, address addr) internal view returns (bool) {
|
||||
uint256 role = IAllowList(allowList).readAllowList(addr);
|
||||
return role >= ROLE_ENABLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Check if an address is Admin
|
||||
* @param allowList The allow list precompile address
|
||||
* @param addr The address to check
|
||||
* @return True if admin
|
||||
*/
|
||||
function isAdmin(address allowList, address addr) internal view returns (bool) {
|
||||
return IAllowList(allowList).readAllowList(addr) == ROLE_ADMIN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Check if an address is Manager
|
||||
* @param allowList The allow list precompile address
|
||||
* @param addr The address to check
|
||||
* @return True if manager
|
||||
*/
|
||||
function isManager(address allowList, address addr) internal view returns (bool) {
|
||||
return IAllowList(allowList).readAllowList(addr) == ROLE_MANAGER;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Require caller to be enabled
|
||||
* @param allowList The allow list precompile address
|
||||
*/
|
||||
function requireEnabled(address allowList) internal view {
|
||||
if (!isEnabled(allowList, msg.sender)) {
|
||||
revert NotEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Require caller to be admin
|
||||
* @param allowList The allow list precompile address
|
||||
*/
|
||||
function requireAdmin(address allowList) internal view {
|
||||
if (!isAdmin(allowList, msg.sender)) {
|
||||
revert NotAdmin();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,508 +1,110 @@
|
||||
# Lux Precompiled Contracts
|
||||
|
||||
This directory contains all precompiled contracts (precompiles) for the Lux blockchain ecosystem. Precompiles are special smart contracts implemented natively in the node software for performance-critical operations that would be too expensive or slow to implement in Solidity.
|
||||
Native EVM precompiles for the Lux blockchain. Each precompile is a Go package that implements `contract.StatefulPrecompiledContract` and registers via `modules.RegisterModule()` in its `init()`.
|
||||
|
||||
## Overview
|
||||
Geth provides `NewPrecompileAdapter()` to wrap these into geth-compatible precompiles. L1 chains select which precompiles to enable via `PrecompileOverrider`.
|
||||
|
||||
Precompiles are located at deterministic addresses starting from `0x0200000000000000000000000000000000000000`. They provide optimized implementations for cryptographic operations, cross-chain messaging, and chain configuration.
|
||||
## Precompiles
|
||||
|
||||
## Precompile Addresses
|
||||
### Post-Quantum Cryptography (baseline — all Lux chains)
|
||||
|
||||
| Address | Name | Description | LP |
|
||||
|---------|------|-------------|-----|
|
||||
| `0x0200000000000000000000000000000000000001` | **DeployerAllowList** | Access control for contract deployment | LP-315 |
|
||||
| `0x0200000000000000000000000000000000000002` | **TxAllowList** | Access control for transaction execution | LP-316 |
|
||||
| `0x0200000000000000000000000000000000000003` | **FeeManager** | Dynamic fee configuration and management | LP-314 |
|
||||
| `0x0200000000000000000000000000000000000004` | **NativeMinter** | Mint and burn native LUX tokens | LP-317 |
|
||||
| `0x0200000000000000000000000000000000000005` | **RewardManager** | Validator reward distribution | LP-318 |
|
||||
| `0x0200000000000000000000000000000000000006` | **ML-DSA** | Post-quantum signature verification (FIPS 204) | LP-311 |
|
||||
| `0x0200000000000000000000000000000000000007` | **SLH-DSA** | Hash-based signature verification (FIPS 205) | LP-312 |
|
||||
| `0x0200000000000000000000000000000000000008` | **Warp** | Cross-chain messaging and attestation | LP-313 |
|
||||
| `0x0200000000000000000000000000000000000009` | **PQCrypto** | General post-quantum cryptography operations | LP-310 |
|
||||
| `0x020000000000000000000000000000000000000A` | **Quasar** | Advanced consensus operations | LP-99 |
|
||||
| `0x020000000000000000000000000000000000000B` | **Corona** | Lattice-based threshold signatures (LWE) | LP-320 |
|
||||
| `0x020000000000000000000000000000000000000C` | **FROST** | Schnorr/EdDSA threshold signatures | LP-321 |
|
||||
| `0x020000000000000000000000000000000000000D` | **CGGMP21** | ECDSA threshold signatures with aborts | LP-322 |
|
||||
| `0x020000000000000000000000000000000000000E` | **Bridge** | Cross-chain bridge verification | LP-323 (Reserved) |
|
||||
| Package | Address | Description | Gas |
|
||||
|---------|---------|-------------|-----|
|
||||
| `mldsa` | `0x0200...0006` | ML-DSA-65 signature verify (FIPS 204) | 100k + 10/byte |
|
||||
| `slhdsa` | `0x0600...0001` | SLH-DSA signature verify (FIPS 205) | 15k–250k by mode |
|
||||
| `pqcrypto` | `0x9003` | ML-KEM key encapsulation + hybrid PQ ops | variable |
|
||||
| `mlkem` | `0x0200...0007` | ML-KEM-768 encapsulate/decapsulate | 50k base |
|
||||
|
||||
### Hashing & Commitment Precompiles
|
||||
### Threshold Signatures
|
||||
|
||||
| Address | Name | Description | LP |
|
||||
|---------|------|-------------|-----|
|
||||
| `0x0000000000000000000000000000000000000501` | **Poseidon2** | PQ-safe hash commitment | - |
|
||||
| `0x0000000000000000000000000000000000000502` | **Pedersen** | Elliptic curve commitment (BN254) | - |
|
||||
| `0x0000000000000000000000000000000000000504` | **Blake3** | Fast hashing (6-17x faster than SHA-3) | - |
|
||||
| Package | Address | Description | Gas |
|
||||
|---------|---------|-------------|-----|
|
||||
| `frost` | `0x0800...0002` | FROST Schnorr threshold verify (secp256k1/Ed25519) | 50k + 5k/signer |
|
||||
| `cggmp21` | `0x0800...0003` | CGGMP21 threshold ECDSA verify (secp256k1) | 75k + 10k/signer |
|
||||
| `corona` | `0x0200...000B` | Ring-LWE lattice threshold verify (post-quantum) | 150k + 10k/party |
|
||||
|
||||
### Zero-Knowledge Precompiles
|
||||
### Curves & Signatures
|
||||
|
||||
| Address | Name | Description | Gas |
|
||||
|---------|------|-------------|-----|
|
||||
| `0x0000000000000000000000000000000000000900` | **ZKVerifier** | Generic ZK proof verification | Variable |
|
||||
| `0x0000000000000000000000000000000000000901` | **Groth16** | Groth16 SNARK verification | ~200,000 |
|
||||
| `0x0000000000000000000000000000000000000902` | **PLONK** | PLONK proof verification | ~250,000 |
|
||||
| `0x0000000000000000000000000000000000000903` | **fflonk** | Optimized PLONK variant | ~180,000 |
|
||||
| `0x0000000000000000000000000000000000000904` | **Halo2** | Recursive proof verification | ~300,000 |
|
||||
| `0x0000000000000000000000000000000000000910` | **KZG** | Polynomial commitment (EIP-4844) | ~50,000 |
|
||||
| `0x0000000000000000000000000000000000000912` | **IPA** | Inner product arguments | ~30,000 |
|
||||
| `0x0000000000000000000000000000000000000920` | **PrivacyPool** | Confidential transaction pool | ~100,000 |
|
||||
| `0x0000000000000000000000000000000000000921` | **Nullifier** | Double-spend prevention | ~5,000 |
|
||||
| `0x0000000000000000000000000000000000000922` | **Commitment** | Commitment verification | ~10,000 |
|
||||
| `0x0000000000000000000000000000000000000923` | **RangeProof** | Bulletproofs range verification | ~100,000 |
|
||||
| `0x0000000000000000000000000000000000000930` | **RollupVerify** | ZK rollup batch verification | ~500,000 |
|
||||
| `0x0000000000000000000000000000000000000931` | **StateRoot** | State root verification | ~50,000 |
|
||||
| `0x0000000000000000000000000000000000000932` | **BatchProof** | Proof aggregation | ~200,000 |
|
||||
|
||||
## Categories
|
||||
|
||||
### 1. Access Control Precompiles
|
||||
|
||||
These precompiles manage permissions for critical blockchain operations:
|
||||
|
||||
#### DeployerAllowList (`0x...0001`)
|
||||
- **Purpose**: Control which addresses can deploy smart contracts
|
||||
- **Use Case**: Enterprise/private chains with deployment restrictions
|
||||
- **Gas Cost**: Minimal (configuration reads)
|
||||
- **Documentation**: [deployerallowlist/](./deployerallowlist/)
|
||||
|
||||
#### TxAllowList (`0x...0002`)
|
||||
- **Purpose**: Control which addresses can submit transactions
|
||||
- **Use Case**: Permissioned blockchains, compliance requirements
|
||||
- **Gas Cost**: Minimal (configuration reads)
|
||||
- **Documentation**: [txallowlist/](./txallowlist/)
|
||||
|
||||
### 2. Economic Precompiles
|
||||
|
||||
These precompiles manage blockchain economics and tokenomics:
|
||||
|
||||
#### FeeManager (`0x...0003`)
|
||||
- **Purpose**: Configure gas fees, base fees, and EIP-1559 parameters
|
||||
- **Use Case**: Dynamic fee adjustment, custom fee models
|
||||
- **Gas Cost**: Varies by operation
|
||||
- **Documentation**: [feemanager/](./feemanager/)
|
||||
- **LP**: [LP-314](../../lps/LPs/lp-314.md)
|
||||
|
||||
#### NativeMinter (`0x...0004`)
|
||||
- **Purpose**: Mint and burn native LUX tokens
|
||||
- **Use Case**: Bridging, wrapping/unwrapping, supply management
|
||||
- **Gas Cost**: Proportional to amount
|
||||
- **Documentation**: [nativeminter/](./nativeminter/)
|
||||
|
||||
#### RewardManager (`0x...0005`)
|
||||
- **Purpose**: Distribute staking and validation rewards
|
||||
- **Use Case**: Validator compensation, staking yields
|
||||
- **Gas Cost**: Proportional to recipient count
|
||||
- **Documentation**: [rewardmanager/](./rewardmanager/)
|
||||
|
||||
### 3. Post-Quantum Cryptography Precompiles
|
||||
|
||||
These precompiles provide quantum-resistant cryptographic operations per NIST FIPS standards:
|
||||
|
||||
#### ML-DSA (`0x...0006`)
|
||||
- **Purpose**: Verify ML-DSA-65 signatures (FIPS 204 - Dilithium)
|
||||
- **Security Level**: NIST Level 3 (192-bit equivalent)
|
||||
- **Key Sizes**:
|
||||
- Public Key: 1,952 bytes
|
||||
- Signature: 3,309 bytes
|
||||
- **Performance**: ~108μs verification on Apple M1
|
||||
- **Gas Cost**: 100,000 base + 10 gas/byte of message
|
||||
- **Use Cases**:
|
||||
- Quantum-safe transaction authorization
|
||||
- Cross-chain message authentication
|
||||
- Post-quantum multisig wallets
|
||||
- **Documentation**: [mldsa/](./mldsa/)
|
||||
- **LP**: [LP-311](../../lps/LPs/lp-311.md)
|
||||
- **Solidity Interface**: [mldsa/IMLDSA.sol](./mldsa/IMLDSA.sol)
|
||||
|
||||
#### SLH-DSA (`0x...0007`)
|
||||
- **Purpose**: Verify SLH-DSA signatures (FIPS 205 - SPHINCS+)
|
||||
- **Security Level**: NIST Level 1-5 (128-256 bit)
|
||||
- **Key Sizes** (SLH-DSA-128s):
|
||||
- Public Key: 32 bytes
|
||||
- Signature: 7,856 bytes
|
||||
- **Performance**: ~286μs verification on Apple M1
|
||||
- **Gas Cost**: 15,000 base + 10 gas/byte of message
|
||||
- **Use Cases**:
|
||||
- Hash-based quantum-safe signatures
|
||||
- Long-term signature validity (archival)
|
||||
- Conservative post-quantum security
|
||||
- Firmware update verification
|
||||
- **Documentation**: [slhdsa/](./slhdsa/)
|
||||
- **LP**: [LP-312](../../lps/LPs/lp-312.md)
|
||||
- **Solidity Interface**: [slhdsa/ISLHDSA.sol](./slhdsa/ISLHDSA.sol)
|
||||
|
||||
#### PQCrypto (`0x...0009`)
|
||||
- **Purpose**: General post-quantum cryptography operations
|
||||
- **Operations**:
|
||||
- ML-KEM-768 key encapsulation (FIPS 203)
|
||||
- Hybrid classical+PQ operations
|
||||
- Quantum-safe key exchange
|
||||
- **Documentation**: [pqcrypto/](./pqcrypto/)
|
||||
- **LP**: [LP-310](../../lps/LPs/lp-310.md) *(to be created)*
|
||||
|
||||
### 4. Interoperability Precompiles
|
||||
|
||||
These precompiles enable cross-chain communication and messaging:
|
||||
|
||||
#### Warp (`0x...0008`)
|
||||
- **Purpose**: Cross-chain message signing and verification
|
||||
- **Features**:
|
||||
- BLS signature aggregation
|
||||
- Validator attestations
|
||||
- Cross-chain asset transfers
|
||||
- **Performance**: ~1.5ms per BLS verification
|
||||
- **Gas Cost**: Variable based on validator set size
|
||||
- **Use Cases**:
|
||||
- Cross-chain token transfers
|
||||
- Multi-chain contract calls
|
||||
- Subnet synchronization
|
||||
- **Documentation**: [warp/](./warp/)
|
||||
- **LP**: [LP-313](../../lps/LPs/lp-313.md) *(to be created)*
|
||||
|
||||
### 5. Threshold Signature Precompiles
|
||||
|
||||
Multi-party computation and threshold signatures for custody and consensus:
|
||||
|
||||
#### Corona (`0x...000B`)
|
||||
- **Purpose**: Lattice-based threshold signature verification
|
||||
- **Algorithm**: LWE-based two-round threshold scheme
|
||||
- **Security**: Post-quantum (Ring Learning With Errors)
|
||||
- **Gas Cost**: 150,000 base + 10,000 per party
|
||||
- **Use Cases**:
|
||||
- Quantum-safe threshold wallets
|
||||
- Distributed validator signing
|
||||
- Post-quantum consensus
|
||||
- Multi-party custody
|
||||
- **Documentation**: [corona/](./corona/)
|
||||
- **LP**: [LP-320](../../lps/LPs/lp-320.md)
|
||||
|
||||
#### FROST (`0x...000C`)
|
||||
- **Purpose**: Schnorr/EdDSA threshold signature verification
|
||||
- **Algorithm**: FROST (Flexible Round-Optimized Schnorr Threshold)
|
||||
- **Standards**: IETF FROST, BIP-340/341 (Taproot)
|
||||
- **Gas Cost**: 50,000 base + 5,000 per signer
|
||||
- **Signature Size**: 64 bytes (compact Schnorr)
|
||||
- **Use Cases**:
|
||||
- Bitcoin Taproot multisig
|
||||
- Ed25519 threshold (Solana, Cardano, TON)
|
||||
- Schnorr aggregate signatures
|
||||
- Lightweight threshold custody
|
||||
- **Documentation**: [frost/](./frost/)
|
||||
- **LP**: [LP-321](../../lps/LPs/lp-321.md)
|
||||
|
||||
#### CGGMP21 (`0x...000D`)
|
||||
- **Purpose**: Modern ECDSA threshold signature verification
|
||||
- **Algorithm**: CGGMP21 with identifiable aborts
|
||||
- **Security**: Detects malicious parties
|
||||
- **Gas Cost**: 75,000 base + 10,000 per signer
|
||||
- **Signature Size**: 65 bytes (standard ECDSA)
|
||||
- **Use Cases**:
|
||||
- Ethereum threshold wallets
|
||||
- Bitcoin threshold multisig
|
||||
- MPC custody solutions
|
||||
- Enterprise key management
|
||||
- **Documentation**: [cggmp21/](./cggmp21/)
|
||||
- **LP**: [LP-322](../../lps/LPs/lp-322.md)
|
||||
|
||||
### 6. Hashing Precompiles
|
||||
|
||||
Fast cryptographic hashing for Merkle trees and commitments:
|
||||
|
||||
#### Blake3 (`0x0504`)
|
||||
- **Purpose**: High-performance hashing (6-17x faster than SHA-3)
|
||||
- **Operations**:
|
||||
- `hash256`: Standard 256-bit hash
|
||||
- `hash512`: Extended 512-bit hash
|
||||
- `hashXOF`: Extensible output function (arbitrary length)
|
||||
- `hashWithDomain`: Domain-separated hashing
|
||||
- `merkleRoot`: Batch Merkle tree computation
|
||||
- `deriveKey`: KDF key derivation
|
||||
- **Gas Cost**: 100 base + 3-5 gas/word
|
||||
- **Use Cases**:
|
||||
- ZK Merkle trees
|
||||
- Content addressing
|
||||
- Key derivation
|
||||
- **GPU Acceleration**: Metal shaders available
|
||||
- **Documentation**: [blake3/](./blake3/)
|
||||
- **Solidity Interface**: [blake3/IBlake3.sol](./blake3/IBlake3.sol)
|
||||
|
||||
#### Poseidon2 (`0x0501`)
|
||||
- **Purpose**: ZK-friendly hash function (post-quantum safe)
|
||||
- **Gas Cost**: ~5,000 per hash
|
||||
- **Use Cases**: ZK circuits, commitments
|
||||
|
||||
#### Pedersen (`0x0502`)
|
||||
- **Purpose**: Elliptic curve commitment on BN254
|
||||
- **Gas Cost**: ~10,000 per commitment
|
||||
- **Note**: NOT post-quantum safe (discrete log)
|
||||
- **GPU Acceleration**: Metal shaders available
|
||||
|
||||
### 7. Zero-Knowledge Precompiles
|
||||
|
||||
Comprehensive ZK proof verification and privacy operations:
|
||||
|
||||
#### ZK Verifier (`0x0900`)
|
||||
- **Purpose**: Generic ZK proof verification router
|
||||
- **Features**:
|
||||
- Verifying key registration
|
||||
- Multi-proof-system support
|
||||
- Verification statistics
|
||||
- **Documentation**: [zk/](./zk/)
|
||||
- **Solidity Interface**: [zk/IZK.sol](./zk/IZK.sol)
|
||||
|
||||
#### Groth16 (`0x0901`)
|
||||
- **Purpose**: Groth16 SNARK verification
|
||||
- **Gas Cost**: ~200,000 per verification
|
||||
- **Proof Size**: 128 bytes (2 G1 + 1 G2)
|
||||
- **Trusted Setup**: Circuit-specific
|
||||
- **GPU Acceleration**: BN254 pairing via Metal
|
||||
|
||||
#### PLONK (`0x0902`)
|
||||
- **Purpose**: Universal PLONK verification
|
||||
- **Gas Cost**: ~250,000 per verification
|
||||
- **Proof Size**: ~1KB (variable)
|
||||
- **Trusted Setup**: Universal (one-time)
|
||||
|
||||
#### fflonk (`0x0903`)
|
||||
- **Purpose**: Optimized PLONK variant
|
||||
- **Gas Cost**: ~180,000 per verification
|
||||
- **Improvements**: Faster verification, smaller proofs
|
||||
|
||||
#### Halo2 (`0x0904`)
|
||||
- **Purpose**: Recursive proof composition
|
||||
- **Gas Cost**: ~300,000 per verification
|
||||
- **Trusted Setup**: None required
|
||||
- **Use Cases**: IVC, recursive rollups
|
||||
|
||||
#### KZG (`0x0910`)
|
||||
- **Purpose**: Polynomial commitments (EIP-4844)
|
||||
- **Gas Cost**: ~50,000 per evaluation
|
||||
- **Use Cases**: Blob commitments, data availability
|
||||
- **GPU Acceleration**: FFT and MSM via Metal
|
||||
|
||||
#### Privacy Pool (`0x0920`)
|
||||
- **Purpose**: Confidential transaction pool
|
||||
- **Features**: Merkle tree, deposit/withdraw
|
||||
- **Gas Cost**: ~100,000 per operation
|
||||
|
||||
#### Nullifier (`0x0921`)
|
||||
- **Purpose**: Double-spend prevention
|
||||
- **Gas Cost**: ~5,000 per lookup
|
||||
|
||||
#### RangeProof (`0x0923`)
|
||||
- **Purpose**: Bulletproofs range verification
|
||||
- **Gas Cost**: ~100,000 per proof
|
||||
- **Use Cases**: Confidential amounts
|
||||
|
||||
#### RollupVerify (`0x0930`)
|
||||
- **Purpose**: ZK rollup batch verification
|
||||
- **Gas Cost**: ~500,000 per batch
|
||||
- **Features**:
|
||||
- Rollup registration
|
||||
- Batch verification
|
||||
- State root tracking
|
||||
- Challenge support
|
||||
|
||||
### 8. Consensus Precompiles
|
||||
|
||||
Advanced consensus and validation operations:
|
||||
|
||||
#### Quasar (`0x...000A`)
|
||||
- **Purpose**: Advanced consensus operations for Quasar hybrid consensus
|
||||
- **Features**:
|
||||
- Dual certificate verification (classical + PQ)
|
||||
- BLS signature aggregation
|
||||
- Hybrid BLS+ML-DSA verification
|
||||
- Verkle witness verification
|
||||
- **Documentation**: [quasar/](./quasar/)
|
||||
- **LP**: [LP-99](../../lps/LPs/lp-99.md)
|
||||
|
||||
## Implementation Structure
|
||||
|
||||
Each precompile directory contains:
|
||||
|
||||
```
|
||||
<precompile-name>/
|
||||
├── module.go # Precompile module registration
|
||||
├── contract.go # Core precompile implementation
|
||||
├── contract_test.go # Go test suite
|
||||
├── config.go # Configuration structures (if applicable)
|
||||
├── config_test.go # Configuration tests
|
||||
├── I<Name>.sol # Solidity interface
|
||||
├── contract.abi # ABI definition (if applicable)
|
||||
└── README.md # Detailed documentation
|
||||
```
|
||||
|
||||
## Development Guidelines
|
||||
|
||||
### Adding a New Precompile
|
||||
|
||||
1. **Choose an Address**: Select next available address in sequence
|
||||
2. **Create Directory**: `mkdir -p src/precompiles/<name>`
|
||||
3. **Implement Interface**: Must implement `StatefulPrecompiledContract`
|
||||
4. **Write Tests**: Minimum 80% code coverage
|
||||
5. **Create Solidity Interface**: Include full documentation
|
||||
6. **Write LP**: Document specification in lps/LPs/
|
||||
7. **Update This README**: Add to address table and category
|
||||
|
||||
### Required Interfaces
|
||||
|
||||
All precompiles must implement:
|
||||
|
||||
```go
|
||||
type StatefulPrecompiledContract interface {
|
||||
// Address returns the precompile address
|
||||
Address() common.Address
|
||||
|
||||
// RequiredGas calculates gas cost for input
|
||||
RequiredGas(input []byte) uint64
|
||||
|
||||
// Run executes the precompile logic
|
||||
Run(
|
||||
accessibleState AccessibleState,
|
||||
caller common.Address,
|
||||
addr common.Address,
|
||||
input []byte,
|
||||
suppliedGas uint64,
|
||||
readOnly bool,
|
||||
) ([]byte, uint64, error)
|
||||
}
|
||||
```
|
||||
|
||||
### Module Registration
|
||||
|
||||
Each precompile must provide a module for registration:
|
||||
|
||||
```go
|
||||
type module struct {
|
||||
address common.Address
|
||||
contract StatefulPrecompiledContract
|
||||
}
|
||||
|
||||
func (m *module) Address() common.Address {
|
||||
return m.address
|
||||
}
|
||||
|
||||
func (m *module) Contract() StatefulPrecompiledContract {
|
||||
return m.contract
|
||||
}
|
||||
```
|
||||
|
||||
### Gas Calculation Guidelines
|
||||
|
||||
Gas costs should reflect:
|
||||
1. **Computational complexity**: Higher for crypto operations
|
||||
2. **Memory usage**: Larger for big inputs/outputs
|
||||
3. **State access**: More for state reads/writes
|
||||
4. **Benchmarks**: Based on real performance measurements
|
||||
|
||||
Example gas formulas:
|
||||
- **Simple state read**: ~2,000 gas
|
||||
- **Cryptographic verification**: 50,000 - 500,000 gas
|
||||
- **Per-byte processing**: 10 - 50 gas/byte
|
||||
- **State writes**: ~20,000 gas per slot
|
||||
|
||||
## Testing Requirements
|
||||
|
||||
All precompiles must have:
|
||||
|
||||
1. **Unit Tests** (`contract_test.go`):
|
||||
- Valid input cases
|
||||
- Invalid input cases
|
||||
- Edge cases
|
||||
- Gas calculation verification
|
||||
|
||||
2. **Solidity Tests**:
|
||||
- Interface usage examples
|
||||
- Integration with other contracts
|
||||
- Gas benchmarks
|
||||
|
||||
3. **Benchmarks**:
|
||||
- Performance measurements
|
||||
- Gas cost validation
|
||||
- Comparison with pure Solidity implementation
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Input Validation
|
||||
- **Always** validate input length before parsing
|
||||
- Check for buffer overflows
|
||||
- Validate all parameters against constraints
|
||||
|
||||
### Gas Limits
|
||||
- Ensure gas costs prevent DoS attacks
|
||||
- Test with maximum-size inputs
|
||||
- Verify gas calculations don't overflow
|
||||
|
||||
### State Access
|
||||
- Only modify state in non-read-only calls
|
||||
- Validate caller permissions for privileged operations
|
||||
- Ensure atomic state updates
|
||||
|
||||
### Cryptographic Operations
|
||||
- Use constant-time implementations when possible
|
||||
- Validate all cryptographic inputs
|
||||
- Check signature/key sizes match expected values
|
||||
- Test against known attack vectors
|
||||
|
||||
## Performance Benchmarks
|
||||
|
||||
Performance targets on Apple M1 (reference hardware):
|
||||
|
||||
### Signature Verification
|
||||
|
||||
| Operation | Target | Current |
|
||||
|-----------|--------|---------|
|
||||
| ML-DSA-65 Verify | < 150μs | ~108μs ✓ |
|
||||
| SLH-DSA-192s Verify | < 20ms | ~15ms ✓ |
|
||||
| BLS Signature Verify | < 2ms | ~1.5ms ✓ |
|
||||
| FROST (3-of-5) | < 100μs | ~55μs ✓ |
|
||||
| CGGMP21 (3-of-5) | < 150μs | ~80μs ✓ |
|
||||
|
||||
### ZK Proof Verification
|
||||
|
||||
| Operation | CPU | GPU (Metal) | Speedup |
|
||||
|-----------|-----|-------------|---------|
|
||||
| Groth16 Verify | 12ms | 1.5ms | 8x |
|
||||
| PLONK Verify | 18ms | 2ms | 9x |
|
||||
| KZG Point Eval | 3ms | 0.4ms | 7.5x |
|
||||
| Range Proof (64-bit) | 8ms | 1ms | 8x |
|
||||
| MSM (256 points) | 45ms | 3ms | 15x |
|
||||
| FFT (2^16) | 120ms | 8ms | 15x |
|
||||
| Package | Address | Description | Gas |
|
||||
|---------|---------|-------------|-----|
|
||||
| `sr25519` | `0x0A00...0001` | Schnorrkel verify for Substrate→EVM migration | 9k + 3/byte |
|
||||
| `ed25519` | `0x3211...0000` | Ed25519 signature verify | 3k |
|
||||
| `secp256r1` | `0x0100` | P-256 ECDSA verify (WebAuthn/passkeys) | 3.5k |
|
||||
|
||||
### Hashing
|
||||
|
||||
| Operation | Target | Current |
|
||||
|-----------|--------|---------|
|
||||
| Blake3 256-bit | < 1μs/KB | ~0.3μs/KB ✓ |
|
||||
| Blake3 Merkle (1K leaves) | < 100μs | ~45μs ✓ |
|
||||
| Poseidon2 | < 10μs | ~5μs ✓ |
|
||||
| Package | Address | Description | Gas |
|
||||
|---------|---------|-------------|-----|
|
||||
| `blake3` | `0x0500...0004` | Blake3 hash, Merkle root, KDF, XOF | 100 + 3–5/word |
|
||||
| `kzg4844` | `0xB002` | KZG polynomial commitment (EIP-4844) | 50k |
|
||||
|
||||
### State Operations
|
||||
### Privacy & ZK
|
||||
|
||||
| Operation | Target | Current |
|
||||
|-----------|--------|---------|
|
||||
| State Read | < 5μs | ~2μs ✓ |
|
||||
| State Write | < 10μs | ~5μs ✓ |
|
||||
| Package | Address | Description | Gas |
|
||||
|---------|---------|-------------|-----|
|
||||
| `zk` | `0x0900` | ZK proof verification (Groth16, PLONK, fflonk, Halo2) | 180k–500k |
|
||||
| `fhe` | — | Fully homomorphic encryption ops | variable |
|
||||
| `ring` | `0x9202` | Ring signature verification | variable |
|
||||
| `ecies` | `0x9201` | ECIES encryption/decryption | variable |
|
||||
| `hpke` | `0x9200` | Hybrid public key encryption | variable |
|
||||
|
||||
## Documentation Standards
|
||||
### DEX
|
||||
|
||||
Each precompile must document:
|
||||
| Package | Address | Description | Gas |
|
||||
|---------|---------|-------------|-----|
|
||||
| `dex` | `0x0400...0000` | Native DEX (PoolManager, Router, Hooks, Lending) | variable |
|
||||
|
||||
1. **Purpose and Use Cases**: Why it exists, when to use it
|
||||
2. **Input/Output Format**: Exact byte layouts with examples
|
||||
3. **Gas Costs**: Formula and examples
|
||||
4. **Error Conditions**: All possible failure modes
|
||||
5. **Security Considerations**: Potential vulnerabilities
|
||||
6. **Examples**: Both Go and Solidity usage
|
||||
### Infrastructure
|
||||
|
||||
## References
|
||||
| Package | Address | Description | Gas |
|
||||
|---------|---------|-------------|-----|
|
||||
| `ai` | `0x0300...0000` | AI mining (ML-DSA verify, TEE attestation, rewards) | variable |
|
||||
| `quasar` | — | Hybrid consensus certificate verification | variable |
|
||||
| `dead` | `0x0000...0000` | Dead address interceptor | minimal |
|
||||
| `graph` | — | GraphQL query precompile | variable |
|
||||
| `bridge` | — | Cross-chain bridge verification | variable |
|
||||
| `threshold` | — | Threshold key management | variable |
|
||||
| `attestation` | — | TEE/GPU attestation | variable |
|
||||
|
||||
- **Lux Precompile Standards (LPS)**: [../lps/](../../lps/)
|
||||
- **EVM Precompiles**: [../evm/](../../evm/)
|
||||
- **Solidity Interfaces**: [./*/I*.sol](.)
|
||||
- **NIST PQC Standards**: https://csrc.nist.gov/projects/post-quantum-cryptography
|
||||
### Support Packages
|
||||
|
||||
| Package | Purpose |
|
||||
|---------|---------|
|
||||
| `contract` | Core interfaces (`StatefulPrecompiledContract`, `AccessibleState`) |
|
||||
| `modules` | Module registration system and reserved address ranges |
|
||||
| `precompileconfig` | Config interfaces (`Upgrade`, `Timestamp`, `IsDisabled`) |
|
||||
| `registry` | Address-to-LP mapping |
|
||||
|
||||
## Structure
|
||||
|
||||
Each precompile follows this pattern:
|
||||
|
||||
```
|
||||
<name>/
|
||||
├── contract.go # Run(), RequiredGas(), Address()
|
||||
├── contract_test.go # Tests with known vectors
|
||||
├── module.go # init() → modules.RegisterModule()
|
||||
└── I<Name>.sol # Solidity interface (optional)
|
||||
```
|
||||
|
||||
## Adding a Precompile
|
||||
|
||||
1. Pick an address in a [reserved range](modules/registerer.go)
|
||||
2. Implement `contract.StatefulPrecompiledContract`
|
||||
3. Register via `modules.RegisterModule()` in `init()`
|
||||
4. Add tests (valid, invalid, gas, edge cases)
|
||||
5. Wire into your L1 via `PrecompileOverrider` or geth's `LuxPrecompiles()`
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
go build ./...
|
||||
go test ./...
|
||||
go test -bench=. ./sr25519/ # benchmark a specific package
|
||||
```
|
||||
|
||||
CGO is required for `sr25519` (sr25519-donna C library). All other packages are pure Go.
|
||||
|
||||
## License
|
||||
|
||||
Copyright (C) 2025, Lux Industries, Inc. All rights reserved.
|
||||
See the file [LICENSE](../../LICENSE) for licensing terms.
|
||||
|
||||
@@ -1,283 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
/**
|
||||
* @title ITeleportBridge
|
||||
* @notice Interface for the Teleport Bridge precompile at address 0x0301
|
||||
* @dev Enables cross-chain AI token transfers from Hanzo L1 to supported EVMs
|
||||
*
|
||||
* Supported destination chains:
|
||||
* - Hanzo EVM: Chain ID 36963
|
||||
* - Zoo EVM: Chain ID 200200
|
||||
* - Lux C-Chain: Chain ID 43114
|
||||
*
|
||||
* References:
|
||||
* - LP-2000: AI Mining Standard
|
||||
* - HIP-006: Hanzo AI Mining Protocol
|
||||
* - ZIP-005: Zoo AI Mining Integration
|
||||
*/
|
||||
interface ITeleportBridge {
|
||||
// ============ Structs ============
|
||||
|
||||
struct TeleportTransfer {
|
||||
bytes32 teleportId; // Unique transfer identifier
|
||||
uint256 sourceChain; // Source chain ID (always Hanzo L1 = 0)
|
||||
uint256 destChain; // Destination chain ID
|
||||
bytes32 senderPkHash; // BLAKE3 hash of sender's ML-DSA public key
|
||||
address recipient; // Recipient address on destination chain
|
||||
uint256 amount; // AI token amount in atomic units
|
||||
uint64 timestamp; // Transfer initiation timestamp
|
||||
TransferStatus status; // Current transfer status
|
||||
}
|
||||
|
||||
enum TransferStatus {
|
||||
Pending, // Awaiting claim on destination
|
||||
Claimed, // Successfully claimed
|
||||
Expired, // Claim window passed (24 hours)
|
||||
Cancelled // Cancelled by sender (L1 only)
|
||||
}
|
||||
|
||||
// ============ Events ============
|
||||
|
||||
/// @notice Emitted when a new teleport is received from Hanzo L1
|
||||
event TeleportReceived(
|
||||
bytes32 indexed teleportId,
|
||||
uint256 indexed sourceChain,
|
||||
address indexed recipient,
|
||||
uint256 amount
|
||||
);
|
||||
|
||||
/// @notice Emitted when a teleport is claimed
|
||||
event TeleportClaimed(
|
||||
bytes32 indexed teleportId,
|
||||
address indexed claimer,
|
||||
uint256 amount
|
||||
);
|
||||
|
||||
/// @notice Emitted when a teleport expires
|
||||
event TeleportExpired(
|
||||
bytes32 indexed teleportId,
|
||||
address indexed recipient,
|
||||
uint256 amount
|
||||
);
|
||||
|
||||
// ============ View Functions ============
|
||||
|
||||
/**
|
||||
* @notice Get the current chain's ID
|
||||
* @return The chain ID
|
||||
*/
|
||||
function getChainId() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice Check if a chain is supported for teleport
|
||||
* @param chainId The chain ID to check
|
||||
* @return True if chain is supported
|
||||
*/
|
||||
function isSupportedChain(uint256 chainId) external view returns (bool);
|
||||
|
||||
/**
|
||||
* @notice Get all supported chain IDs
|
||||
* @return Array of supported chain IDs
|
||||
*/
|
||||
function getSupportedChains() external view returns (uint256[] memory);
|
||||
|
||||
/**
|
||||
* @notice Get teleport transfer details
|
||||
* @param teleportId The transfer ID
|
||||
* @return transfer The transfer details
|
||||
*/
|
||||
function getTeleport(bytes32 teleportId) external view returns (TeleportTransfer memory transfer);
|
||||
|
||||
/**
|
||||
* @notice Get all pending teleports for a recipient
|
||||
* @param recipient The recipient address
|
||||
* @return Array of pending teleport IDs
|
||||
*/
|
||||
function getPendingTeleports(address recipient) external view returns (bytes32[] memory);
|
||||
|
||||
/**
|
||||
* @notice Get total amount of pending teleports for a recipient
|
||||
* @param recipient The recipient address
|
||||
* @return Total pending amount
|
||||
*/
|
||||
function getPendingAmount(address recipient) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice Check if a teleport is claimable
|
||||
* @param teleportId The transfer ID
|
||||
* @return True if transfer can be claimed
|
||||
*/
|
||||
function isClaimable(bytes32 teleportId) external view returns (bool);
|
||||
|
||||
/**
|
||||
* @notice Get the claim deadline for a teleport
|
||||
* @param teleportId The transfer ID
|
||||
* @return Unix timestamp of claim deadline
|
||||
*/
|
||||
function getClaimDeadline(bytes32 teleportId) external view returns (uint256);
|
||||
|
||||
// ============ State-Changing Functions ============
|
||||
|
||||
/**
|
||||
* @notice Claim a teleport transfer
|
||||
* @param teleportId The transfer to claim
|
||||
* @return amount The claimed amount
|
||||
*
|
||||
* Requirements:
|
||||
* - Transfer must exist and be pending
|
||||
* - Caller must be the designated recipient
|
||||
* - Must be within 24-hour claim window
|
||||
*/
|
||||
function claim(bytes32 teleportId) external returns (uint256 amount);
|
||||
|
||||
/**
|
||||
* @notice Batch claim multiple teleports
|
||||
* @param teleportIds Array of transfer IDs
|
||||
* @return totalAmount Total amount claimed
|
||||
*/
|
||||
function batchClaim(bytes32[] calldata teleportIds) external returns (uint256 totalAmount);
|
||||
|
||||
/**
|
||||
* @notice Claim all pending teleports for caller
|
||||
* @return totalAmount Total amount claimed
|
||||
* @return claimedCount Number of teleports claimed
|
||||
*/
|
||||
function claimAll() external returns (uint256 totalAmount, uint256 claimedCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @title TeleportBridgePrecompile
|
||||
* @notice Wrapper contract for the Teleport Bridge precompile
|
||||
*/
|
||||
contract TeleportBridgePrecompile {
|
||||
/// @notice The precompile address
|
||||
address public constant PRECOMPILE_ADDRESS = address(0x0301);
|
||||
|
||||
/// @notice Hanzo L1 chain identifier (source of all teleports)
|
||||
uint256 public constant HANZO_L1_CHAIN_ID = 0;
|
||||
|
||||
/// @notice Supported destination chain IDs
|
||||
uint256 public constant HANZO_EVM_CHAIN_ID = 36963;
|
||||
uint256 public constant ZOO_EVM_CHAIN_ID = 200200;
|
||||
uint256 public constant LUX_CCHAIN_CHAIN_ID = 96369;
|
||||
|
||||
/// @notice Claim window duration (24 hours)
|
||||
uint256 public constant CLAIM_WINDOW = 24 hours;
|
||||
|
||||
// ============ Errors ============
|
||||
|
||||
error PrecompileCallFailed();
|
||||
error TeleportNotFound();
|
||||
error TeleportNotClaimable();
|
||||
error NotRecipient();
|
||||
error ClaimWindowExpired();
|
||||
|
||||
// ============ Events ============
|
||||
|
||||
event ClaimedViaWrapper(
|
||||
bytes32 indexed teleportId,
|
||||
address indexed claimer,
|
||||
uint256 amount
|
||||
);
|
||||
|
||||
// ============ External Functions ============
|
||||
|
||||
/**
|
||||
* @notice Get current chain ID
|
||||
*/
|
||||
function chainId() external view returns (uint256) {
|
||||
return block.chainid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Check if running on a supported chain
|
||||
*/
|
||||
function onSupportedChain() external view returns (bool) {
|
||||
return block.chainid == HANZO_EVM_CHAIN_ID ||
|
||||
block.chainid == ZOO_EVM_CHAIN_ID ||
|
||||
block.chainid == LUX_CCHAIN_CHAIN_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Claim teleport with validation
|
||||
*/
|
||||
function claimTeleport(bytes32 teleportId) external returns (uint256 amount) {
|
||||
(bool success, bytes memory result) = PRECOMPILE_ADDRESS.call(
|
||||
abi.encodeWithSelector(ITeleportBridge.claim.selector, teleportId)
|
||||
);
|
||||
|
||||
if (!success) revert PrecompileCallFailed();
|
||||
amount = abi.decode(result, (uint256));
|
||||
|
||||
emit ClaimedViaWrapper(teleportId, msg.sender, amount);
|
||||
return amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Get all pending teleports for caller
|
||||
*/
|
||||
function myPendingTeleports() external view returns (bytes32[] memory) {
|
||||
(bool success, bytes memory result) = PRECOMPILE_ADDRESS.staticcall(
|
||||
abi.encodeWithSelector(ITeleportBridge.getPendingTeleports.selector, msg.sender)
|
||||
);
|
||||
|
||||
if (!success) revert PrecompileCallFailed();
|
||||
return abi.decode(result, (bytes32[]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Get total pending amount for caller
|
||||
*/
|
||||
function myPendingAmount() external view returns (uint256) {
|
||||
(bool success, bytes memory result) = PRECOMPILE_ADDRESS.staticcall(
|
||||
abi.encodeWithSelector(ITeleportBridge.getPendingAmount.selector, msg.sender)
|
||||
);
|
||||
|
||||
if (!success) revert PrecompileCallFailed();
|
||||
return abi.decode(result, (uint256));
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Claim all pending teleports
|
||||
*/
|
||||
function claimAllPending() external returns (uint256 totalAmount, uint256 count) {
|
||||
(bool success, bytes memory result) = PRECOMPILE_ADDRESS.call(
|
||||
abi.encodeWithSelector(ITeleportBridge.claimAll.selector)
|
||||
);
|
||||
|
||||
if (!success) revert PrecompileCallFailed();
|
||||
return abi.decode(result, (uint256, uint256));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @title TeleportReceiver
|
||||
* @notice Abstract contract for receiving teleported AI tokens
|
||||
* @dev Inherit this contract to add teleport receiving capabilities
|
||||
*/
|
||||
abstract contract TeleportReceiver {
|
||||
ITeleportBridge public immutable teleportBridge;
|
||||
|
||||
constructor(address _bridge) {
|
||||
teleportBridge = ITeleportBridge(_bridge);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Called after a teleport is claimed
|
||||
* @dev Override to implement custom logic
|
||||
*/
|
||||
function onTeleportReceived(
|
||||
bytes32 teleportId,
|
||||
uint256 amount
|
||||
) internal virtual;
|
||||
|
||||
/**
|
||||
* @notice Claim teleport and trigger callback
|
||||
*/
|
||||
function receiveTeleport(bytes32 teleportId) external returns (uint256 amount) {
|
||||
amount = teleportBridge.claim(teleportId);
|
||||
onTeleportReceived(teleportId, amount);
|
||||
return amount;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user