Keyboard shortcuts

Press โ† or โ†’ to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Deshare Protocol

Tests Coverage Security Checks

A comprehensive blockchain-based ecosystem management protocol built on Solidity 0.8.24, providing secure, upgradeable smart contracts for managing partner ecosystems, merchant onboarding, device management, and transaction processing through the Deshare contract.

๐Ÿ“š Documentation

๐Ÿ“– Auto-Generated Contract Documentation - Complete API documentation auto-generated from NatSpec comments using Foundry's forge doc command. Includes detailed contract interfaces, function signatures, parameter descriptions, and usage examples extracted directly from the source code.

Generate Documentation Locally

# Generate documentation from NatSpec comments
forge doc

# Serve documentation locally
forge doc --serve --port 3000

# Build documentation for deployment
forge doc --build

The documentation includes:

  • Contract APIs: Auto-generated from NatSpec comments in source code
  • Function Signatures: Complete interface documentation with parameters and return values
  • Integration Examples: Code samples extracted from contract comments
  • Deployment Guides: Based on the deployment scripts and configurations

๐Ÿ—๏ธ Architecture Overview

The Deshare Protocol is built around the Deshare contract with a secure, upgradeable proxy architecture:

โ”œโ”€โ”€ Deshare.sol                  # Core Deshare Protocol contract
โ”œโ”€โ”€ PowerPass.sol                # ERC721 NFT contract for access tokens
โ”œโ”€โ”€ ShareXWallet.sol             # User wallet contract for token & NFT operations
โ”œโ”€โ”€ ShareXWalletManager.sol      # Wallet management system (upgradeable)
โ”œโ”€โ”€ interfaces/                  # Interface definitions
โ”‚   โ”œโ”€โ”€ IDeshare.sol             # Main contract interface
โ”‚   โ”œโ”€โ”€ IShareXWallet.sol        # Wallet interface
โ”‚   โ””โ”€โ”€ IShareXWalletManager.sol # Wallet manager interface
โ”œโ”€โ”€ libraries/                   # Shared utilities
โ”‚   โ”œโ”€โ”€ DataTypes.sol            # Data structures for protocol entities
โ”‚   โ”œโ”€โ”€ Errors.sol               # Custom error definitions
โ”‚   โ””โ”€โ”€ Events.sol               # Event definitions for tracking
โ”œโ”€โ”€ script/                      # Deployment and upgrade scripts
โ”‚   โ””โ”€โ”€ Deploy.s.sol             # Foundry deployment script
โ””โ”€โ”€ deploy-config/               # Network-specific configurations
    โ”œโ”€โ”€ local.json               # Local development config
    โ”œโ”€โ”€ bsc-testnet.json         # BSC Testnet config
    โ””โ”€โ”€ devnet.json              # Development network config

๐Ÿš€ Key Features

Upgradeable Proxy Architecture

  • TransparentUpgradeableProxy: Secure upgrade mechanism with role separation
  • Proxy Admin Owner: Controls proxy upgrades and admin functions
  • Deshare Admin: Controls business logic and operational functions
  • Implementation Contract: Upgradeable Deshare business logic

Partner Ecosystem Management

  • Partner Registration: Complete partner onboarding with verification codes
  • Partner Profiles: Business type classification and country tracking
  • Partner Analytics: Business type statistics and reporting
  • Verification System: Built-in compliance and verification tracking

Merchant Management System

  • Merchant Onboarding: Streamlined merchant registration process
  • Geographic Organization: Location-based merchant management
  • Merchant Categories: Support for various business types
  • Regional Analytics: Location-based merchant statistics

Device Registration & Tracking

  • Device Management: Registration and tracking of various device types
  • Device Association: Link devices to partners and merchants
  • Device Validation: Ensure device dependencies exist before registration
  • Status Monitoring: Track device registration and operational status

Transaction Processing

  • Batch Transaction Processing: High-throughput transaction batch handling with compressed data storage
  • Transaction Validation: Comprehensive data validation and verification
  • Event-Driven Architecture: Real-time transaction tracking through events
  • Data Integrity: Immutable transaction records on blockchain
  • Compression Support: Automatic compression/decompression for efficient storage using LibZip

Enhanced Statistics System

  • User-Friendly Stats: New getDetailedStats() method returns descriptive, labeled statistics instead of anonymous tuples
  • Backward Compatibility: Original getStats() method remains unchanged for existing integrations
  • Rich Metadata: Includes metric names, descriptions, timestamps, and contract version information
  • Self-Documenting: Each statistic includes a human-readable description of what it represents

PowerPass NFT System

  • Standard ERC721: OpenZeppelin-based NFT contract with gas optimizations
  • Access Control: Role-based permissions with admin and minter roles
  • Supply Management: Fixed maximum supply of 5000 tokens with enforcement
  • Metadata Support: Full token URI functionality for rich metadata
  • Mint/Burn Operations: Secure token lifecycle management
  • Custodial Minting: ShareX wallet-based custodial minting system that bypasses sales logic

ShareX Wallet System

  • User Wallet Management: Individual wallet creation and management for users with multi-user support
  • Multi-Token Support: Native ETH, ERC20 tokens, and ERC721 NFT operations in a single wallet
  • PowerPass Integration: Direct NFT minting, transferring, and burning capabilities through wallet system
  • Batch Operations: Efficient multiple token transfers to multiple recipients in single transactions
  • Gas Optimization: Advanced gas-saving techniques based on RareSkills optimization patterns
  • Upgradeable Architecture: Proxy-based wallet management system for future enhancements
  • Access Control: Role-based permissions with comprehensive admin-controlled operations
  • Multicall Pattern: Efficient aggregated contract calls for complex operations

Security & Access Control

  • Role-Based Access Control: Multi-tier permission system with admin and operator roles
  • Reentrancy Protection: Comprehensive attack prevention mechanisms
  • Input Validation: Robust parameter checking and data sanitization
  • Upgrade Security: Secure contract upgrade procedures with proper authorization

๐Ÿ”ง Core Data Structures

Partner Management

  • PartnerInfo: Partner ecosystem data with verification codes and business classification
  • Business Classification: Support for various business types with statistical tracking
  • Geographic Coverage: Country-specific partner management with ISO2 codes
  • Partner Analytics: Business type statistics and partner counting

Merchant Infrastructure

  • MerchantInfo: Complete merchant data with geographic organization
  • Location Management: Region-based organization with location IDs
  • Merchant Categories: Flexible business type categorization system
  • Regional Analytics: Location-based merchant statistics and counting

Device Ecosystem

  • DeviceInfo: Device registration data linked to partners and merchants
  • Device Dependencies: Validation of partner and merchant associations
  • Device Types: Support for various device categories and classifications
  • Registration Tracking: Device registration with timestamp tracking

Transaction Processing

  • TransactionBatch: High-level batch information with device association and metadata
  • Transaction Data: JSON-formatted transaction data stored as compressed bytes
  • Batch Processing: Efficient handling of multiple transaction records in a single batch
  • Data Compression: Automatic compression/decompression using LibZip for storage efficiency
  • Data Integrity: Immutable transaction records with comprehensive validation

Geographic Organization

  • CountryInfo: Country registration system with ISO2 code management
  • Regional Statistics: Location-based analytics and merchant distribution
  • Geographic Validation: Country existence verification for registrations

๐Ÿ”ง Usage Examples

Deshare Protocol Integration

// Deploy Deshare with proxy
Deshare deshare = Deshare(proxyAddress);

// Register a protocol partner
PartnerParams memory partner = PartnerParams({
    partnerCode: "DESHARE001",
    partnerName: "Deshare Solutions Inc",
    iso2: "US",
    verification: "KYB12345",
    description: "Blockchain ecosystem infrastructure provider",
    businessType: "Technology"
});
deshare.registerPartner(partner);

// Register merchants in the ecosystem
MerchantParams memory merchant = MerchantParams({
    merchantName: "Coffee Shop Downtown",
    merchantId: "MERCHANT_CS001",
    description: "Coffee and pastry retail shop",
    iso2: "US",
    locationId: "NYC_DOWNTOWN_001",
    location: "123 Main St, New York, NY",
    merchantType: "Retail_Food",
    verification: "MER_VER_001"
});
deshare.registerMerchant(merchant);

// Register devices in the ecosystem
DeviceParams memory device = DeviceParams({
    deviceId: "DEVICE_001",
    deviceType: "Terminal",
    partnerCode: "DESHARE001",
    merchantId: "MERCHANT_CS001"
});
deshare.registerDevice(device);

Transaction Batch Processing

// Prepare transaction data as JSON string
string memory jsonData = '[{"userId":"USER001","amount":100,"timestamp":1234567890,"type":"purchase"},{"userId":"USER002","amount":200,"timestamp":1234567891,"type":"service"}]';

// Compress transaction data for efficient storage
bytes memory compressedData = LibZip.flzCompress(bytes(jsonData));

// Upload transaction batch with compressed data
UploadBatchParams memory batchParams = UploadBatchParams({
    deviceId: "DEVICE_001",
    dateComparable: 20250703,     // Date in YYYYMMDD format
    orderCount: 2,                // Number of transactions in batch
    totalAmount: 300,             // Total amount of all transactions
    transactionData: compressedData // Compressed JSON transaction data
});

deshare.uploadTransactionBatch(batchParams);

// Retrieve transaction data (automatically decompressed)
string memory retrievedData = deshare.getTransactionData(1);
// retrievedData will contain the original JSON string

Contract Upgrade Process

// Deploy new Deshare implementation
Deshare newImplementation = new Deshare(adminAddress);

// Upgrade proxy (only proxy admin can execute)
ITransparentUpgradeableProxy(proxyAddress).upgradeToAndCall(
    address(newImplementation),
    abi.encodeWithSignature("initializeV2()")
);

// Verify upgrade success
Version memory newVersion = Deshare(proxyAddress).getVersion();
require(
    newVersion.major >= previousVersion.major,
    "Upgrade failed"
);

PowerPass NFT Integration

PowerPass is an ERC721 NFT contract with sophisticated whitelist-based sales rounds and discount systems.

Sales Configuration

# Configure two-round sales system with timestamps and pricing
source .env && cast send 0x3d3624D578bf7bF81a76633a355320B3123c70f7 \
  "configureSalesRounds((uint128,uint128,uint128,uint128,uint128,uint128))" \
  "(PRIORITY_START,PRIORITY_END,GENERAL_START,GENERAL_END,50000000,5000000)" \
  --rpc-url $RPC_URL --private-key $PRIVATE_KEY

# Parameters:
# - priorityStartTime/priorityEndTime: Priority round for MAGNA/NOVA holders
# - generalStartTime/generalEndTime: General round for all stakers
# - standardPrice: 50000000 (50 USDT with 6 decimals)
# - discountCodeDiscount: 5000000 (5 USDT discount with 6 decimals)

Whitelist Management

# Set regular whitelist allocations (priority and general rounds)
source .env && cast send 0x3d3624D578bf7bF81a76633a355320B3123c70f7 \
  "batchSetWhitelists(address[],uint256[],uint256[])" \
  "[0xUSER1,0xUSER2]" \
  "[10,5]" \
  "[10,10]" \
  --rpc-url $RPC_URL --private-key $PRIVATE_KEY

# Set Nova discount allocations (80% discount: 40 USDT instead of 50 USDT)
source .env && cast send 0x3d3624D578bf7bF81a76633a355320B3123c70f7 \
  "batchSetNovaDiscounts(address[],uint256[])" \
  "[0xUSER1,0xUSER2]" \
  "[10,5]" \
  --rpc-url $RPC_URL --private-key $PRIVATE_KEY

Discount Code Management

# Generate discount code hashes
python3 -c "
import hashlib
codes = ['POWERPASS2024', 'EARLY_BIRD']
for code in codes:
    hash_val = '0x' + hashlib.sha256(code.encode()).hexdigest()
    print(f'{code} -> {hash_val}')
"

# Add discount codes to contract
source .env && cast send 0x3d3624D578bf7bF81a76633a355320B3123c70f7 \
  "addDiscountCodes(bytes32[])" \
  "[0x76e0436f2bbe1a2ea4010b9baea8f6515e092fba88c16588f111d27cc5651463]" \
  --rpc-url $RPC_URL --private-key $PRIVATE_KEY

Active Discount Codes

The following discount codes are active on both BSC Testnet and BSC Mainnet:

#CodeKeccak256 Hash
1QAHFT0xc586fb63d1c6eede694002bac945e1fc93dffd2bb58ee916addf7b14ebc53005
2RXCKA0xda83a4728c99e658aa25b9019174565c757f00ab1ddb5fa25c587a8367f5682d
3FNAFQ0x9d840d42aac08a8ef2551fb83db5491d83d2b1babfa2b2540402f3844c1d4fa1
4OFPVA0x4c0ddc905489d5ff324a48638cb7034d165f82aef7c86538d0913db2c2fe30d2
5USIEY0x0b0a596055a60540ef37a00515d938965e3ca609278e2387b35590f668dc4434
6ICCWP0xbad4092fdc31d6e358f15bd4da34d67b0266eab4cf9749008dadcac56c160bbe
7USNZJ0x80130976afa8b115b22dae9f3122248e84806b3c8b65c6637a90e0ea0157fc4f
8OVQWP0x83c49292403faf660a2d1ca7ac696f72c94958324ad6a389e09ba910d5fa2586
9SBFHC0xa7640a297eaa636ab8864b56800d221207008f6bceb3d7915650e15a85c86720
10GCHQJ0xe6f44e784405546578b03c652654c1f7c27ff7781f8f2c08edfec70b78f03e03
11JFGYQ0xfeb647b6cef20e8a742702a0667f50fc0ca65971d679fb28b1ebb63bc669b14a
12PESEJ0x37ad281a3597a41957fc2d4a2878392f2cb75ae07e2b1945bbe02d885c4ac1a3
13ZQORV0xfc3d350f702796b652699a7e5edae75fb0cbca6868d91c1de24cc7ba2496dd7f
14UFAIG0xa7555d840a22bfecbd6dc1868182cbe52940501667319e7328388f5a20c318a8
15FYWIR0x915ee928322569b80fdcd85e200de2a88d08bb2ab4637380fe58199641844199
16KXLGG0x05e5849e61f4a1374283123dae6bdd9fd594c1e9f3a0714bcadde1d4e7f390c2
17OGPXK0x71d2db0ec70669a052c3a80dacc2bfd02cb285d90e320d93a5a4ec8294e4796b
18FZNCB0xd9eaa46f1629ada38b47e110ccd027fd5b32deb4c3bddf34479fb5b8d4dfc605
19CQUKB0xf1130c4946f2b15f872eda6003028a464c3cd78bf621b0cc671c6e1136524cb2
20JZNZW0xdadad1a5d5550d72260f7c7ae168b82e73b254e6d4af7a3bbbd1d2ba38be53f4
21SHARE0x6ecee827156c952a04f57a0610c4ec267270d7865b010b3163aa1d3657d9a421

Query discount code usage count:

# Check usage count for a specific discount code (e.g., SHARE)
cast call $POWERPASS_PROXY "getDiscountCodeUsageCount(bytes32)" \
  0x6ecee827156c952a04f57a0610c4ec267270d7865b010b3163aa1d3657d9a421 \
  --rpc-url $RPC_URL

Minting Process

# 1. Check user's mint status and eligibility
source .env && cast call 0x3d3624D578bf7bF81a76633a355320B3123c70f7 \
  "getMintStatus(address)" 0xUSER_ADDRESS --rpc-url $RPC_URL

# 2. Approve USDT spending (example: 80 USDT for 2 NFTs with Nova discount)
source .env && cast send 0x6350a32a4406469608B5D93A77572e140b5F3D73 \
  "approve(address,uint256)" \
  0x3d3624D578bf7bF81a76633a355320B3123c70f7 \
  80000000 \
  --rpc-url $RPC_URL --private-key $PRIVATE_KEY

# 3. Mint PowerPass NFTs
# With Nova discount (automatic 80% discount)
source .env && cast send 0x3d3624D578bf7bF81a76633a355320B3123c70f7 \
  "mint(uint256,string)" 2 "" \
  --rpc-url $RPC_URL --private-key $PRIVATE_KEY

# With discount code (5 USDT discount)
source .env && cast send 0x3d3624D578bf7bF81a76633a355320B3123c70f7 \
  "mint(uint256,string)" 1 "POWERPASS2024" \
  --rpc-url $RPC_URL --private-key $PRIVATE_KEY

# 4. Verify minting results
source .env && cast call 0x3d3624D578bf7bF81a76633a355320B3123c70f7 \
  "balanceOf(address)" 0xUSER_ADDRESS --rpc-url $RPC_URL

PowerPass Pricing Structure

ScenarioPrice per NFTTotal for 2 NFTsSavings
Standard50 USDT100 USDT0 USDT
Nova Discount40 USDT80 USDT20 USDT
Discount Code45 USDT90 USDT10 USDT

Key Features:

  • Maximum Supply: 5000 NFTs
  • Payment Token: ShareXUSDT (6 decimals)
  • Nova Discount: 80% of standard price (20% savings)
  • Discount Codes: 5 USDT reduction per NFT
  • Two Sales Rounds: Priority (MAGNA/NOVA holders) and General (all stakers)
  • Channel Tracking: Web3 and Web2 mint counts via getChannelMintedCounts()
// Contract integration example
PowerPass powerPass = PowerPass(0x3d3624D578bf7bF81a76633a355320B3123c70f7);

// Check user's mint status
PowerPass.MintStatus memory status = powerPass.getMintStatus(userAddress);
// status.priorityRemaining, status.generalRemaining, status.novaDiscountRemaining
// status.standardPrice (50 USDT), status.novaDiscountPrice (40 USDT)

// Get whitelist information
PowerPass.WhitelistInfo memory info = powerPass.getWhitelistInfo(userAddress);
// info.priorityAllocation, info.generalAllocation, info.priorityMinted, etc.

Enhanced Statistics Usage

// Traditional stats (backward compatible)
StatsInfo memory basicStats = deshare.getStats();
// Returns tuple: (partnersCount, merchantsCount, devicesCount, batchesCount, countriesCount)

// Enhanced stats with user-friendly labels
DetailedStatsInfo memory detailedStats = deshare.getDetailedStats();

// Access descriptive information
console.log("Metric: %s", detailedStats.metricNames[0]);          // "Partners"
console.log("Count: %d", detailedStats.basicStats.partnersCount); // 0
console.log("Description: %s", detailedStats.metricDescriptions[0]);
// "Total number of registered business partners in the ecosystem"

// Access metadata
console.log("Last Updated: %d", detailedStats.lastUpdated);       // 1753155363
console.log("Contract Version: v%d.%d.%d",
    detailedStats.contractVersion.major,    // 1
    detailedStats.contractVersion.minor,    // 0
    detailedStats.contractVersion.patch);   // 0

ShareX Wallet System Usage

// Deploy ShareX Wallet Manager with proxy
ShareXWalletManager manager = ShareXWalletManager(proxyAddress);

// Create wallet for a user
(uint256 walletId, address walletAddr) = manager.createWallet(userId);

// Deposit native tokens (ETH)
manager.deposit{value: 1 ether}(userId, walletId, address(0), 1 ether);

// Deposit ERC20 tokens
IERC20(token).approve(address(manager), 100e18);
manager.deposit(userId, walletId, address(token), 100e18);

// Withdraw tokens to external address
manager.withdraw(userId, walletId, payable(recipient), address(token), 50e18);

// Transfer tokens between wallets
manager.transfer(
    fromUserId, fromWalletId,
    toUserId, toWalletId,
    address(token), 25e18
);

// Batch transfer to multiple recipients
address[] memory tokens = [address(tokenA), address(0), address(tokenB)];
address[] memory recipients = [user1, user2, user3];
uint256[] memory amounts = [100e18, 1e18, 50e18];
manager.batchTransfer(userId, walletId, tokens, recipients, amounts);

ShareX Wallet + PowerPass Integration

// Setup: Grant MINTER_ROLE to user's wallet
address walletAddr = manager.getWalletAddr(userId, walletId);
powerPass.grantRole(powerPass.MINTER_ROLE(), walletAddr);

// Mint PowerPass NFT through wallet system
uint256 tokenId = manager.mintPowerPass(
    userId,
    walletId,
    address(powerPass),
    recipient,
    "https://metadata.example.com/token/1"
);

// Transfer PowerPass NFT (requires approval first)
powerPass.approve(walletAddr, tokenId); // Approve from current owner
manager.transferPowerPass(
    userId,
    walletId,
    address(powerPass),
    currentOwner,
    newOwner,
    tokenId
);

// Burn PowerPass NFT
manager.burnPowerPass(userId, walletId, address(powerPass), tokenId);

Custodial PowerPass Minting

The ShareX Wallet system supports custodial PowerPass minting, allowing the platform to mint PowerPass NFTs on behalf of users through ShareX wallets. This system bypasses normal sales rounds and pricing logic using custodial whitelist allocations.

Key Concepts

  • Custodial Whitelist: Separate allocation system for platform-controlled minting
  • MINTER_ROLE: Individual ShareX wallets need MINTER_ROLE to mint PowerPass NFTs
  • Recipient-Based: Custodial whitelist must be set for the NFT recipient, not the minting wallet
  • Sales Bypass: Custodial minting ignores sales rounds, pricing, and payment requirements

Complete Custodial Workflow

Step 1: Create ShareX Wallet

# Create wallet for user through ShareXWalletManager
source .env && cast send 0x5dC5Fdb90E57A5390c6524414f3d6da0b3Ef0f48 \
  "createWallet(uint256)" 13 \
  --rpc-url $RPC_URL --private-key $PRIVATE_KEY

# Get wallet address
WALLET_ADDR=$(cast call 0x5dC5Fdb90E57A5390c6524414f3d6da0b3Ef0f48 \
  "getWalletAddr(uint256,uint256)" 13 1 \
  --rpc-url $RPC_URL | cut -c 27-66)
WALLET_ADDR="0x$WALLET_ADDR"
# Example result: 0x7C4B5e96B336A60387CadeBa717Ae9859D61576B

Step 2: Grant MINTER_ROLE to Wallet

# Grant MINTER_ROLE to the ShareX wallet (required for custodial minting)
MINTER_ROLE=$(cast call 0x3d3624D578bf7bF81a76633a355320B3123c70f7 \
  "MINTER_ROLE()" --rpc-url $RPC_URL)

source .env && cast send 0x3d3624D578bf7bF81a76633a355320B3123c70f7 \
  "grantRole(bytes32,address)" $MINTER_ROLE $WALLET_ADDR \
  --rpc-url $RPC_URL --private-key $PRIVATE_KEY

Step 3: Set Custodial Whitelist for NFT Recipient

# Set custodial whitelist for the NFT recipient (NOT the wallet!)
source .env && cast send 0x3d3624D578bf7bF81a76633a355320B3123c70f7 \
  "batchSetCustodialWhitelists(address[],uint256[])" \
  "[$WALLET_ADDR]" "[5]" \
  --rpc-url $RPC_URL --private-key $PRIVATE_KEY

# Verify custodial whitelist
cast call 0x3d3624D578bf7bF81a76633a355320B3123c70f7 \
  "getCustodialWhitelistInfo(address)" $WALLET_ADDR --rpc-url $RPC_URL

Step 4: Mint PowerPass NFT Through ShareX Wallet

# Mint PowerPass NFT through ShareXWalletManager to the ShareX wallet
source .env && cast send 0x5dC5Fdb90E57A5390c6524414f3d6da0b3Ef0f48 \
  "mintPowerPass(uint256,uint256,address,address,string)" \
  13 1 0x3d3624D578bf7bF81a76633a355320B3123c70f7 $WALLET_ADDR \
  "https://api.sharex.network/powerpass/metadata/custodial-1" \
  --rpc-url $RPC_URL --private-key $PRIVATE_KEY

# Verify minting results
cast call 0x3d3624D578bf7bF81a76633a355320B3123c70f7 \
  "balanceOf(address)" $WALLET_ADDR --rpc-url $RPC_URL
cast call 0x3d3624D578bf7bF81a76633a355320B3123c70f7 \
  "totalSupply()" --rpc-url $RPC_URL

Contract Addresses (BSC Testnet)

export POWERPASS_PROXY=0x3d3624D578bf7bF81a76633a355320B3123c70f7
export WALLET_MANAGER=0x5dC5Fdb90E57A5390c6524414f3d6da0b3Ef0f48

Integration Script

For a complete workflow demonstration, use the included script:

# Execute complete custodial minting workflow
source .env && ./tools/custodial_powerpass_workflow.sh

Key Advantages

  • Gas Efficiency: No USDT payments or approvals required
  • Flexible Distribution: Platform can distribute NFTs to any address with custodial allocation
  • Sales Independence: Operates independently of regular sales rounds and timing
  • Role-Based Security: Controlled through PowerPass MINTER_ROLE system
  • Audit Trail: All operations logged with comprehensive events

For detailed implementation and troubleshooting, see CUSTODIAL_POWERPASS_WORKFLOW.md.

๐Ÿงช Testing

The Deshare Protocol includes comprehensive test suites covering all Deshare functionality:

# Run all tests with optimization
make foundry-test

# Run specific test contracts
forge test --match-contract Deshare -vvv

# Run ShareX Wallet tests
forge test --match-contract ShareX -v

# Run with gas reporting
forge test --gas-report

# Generate coverage reports
forge coverage

# Test specific ShareX functionality
forge test --match-test testMintPowerPass -vvv
forge test --match-test testBatchTransfer -vvv

Test Structure

test/
โ”œโ”€โ”€ unit/                           # Unit tests for specific functionality
โ”‚   โ”œโ”€โ”€ Country.t.sol              # Country registration tests
โ”‚   โ”œโ”€โ”€ Partner.t.sol              # Partner management tests
โ”‚   โ”œโ”€โ”€ Merchant.t.sol             # Merchant management tests
โ”‚   โ”œโ”€โ”€ Device.t.sol               # Device management tests
โ”‚   โ”œโ”€โ”€ Transaction.t.sol          # Transaction and core tests
โ”‚   โ”œโ”€โ”€ PowerPass.t.sol            # PowerPass ERC721 NFT tests
โ”‚   โ”œโ”€โ”€ ShareXWallet.t.sol         # ShareX Wallet tests
โ”‚   โ””โ”€โ”€ ShareXWalletManager.t.sol  # ShareX Wallet Manager tests
โ””โ”€โ”€ integration/                   # Integration tests
    โ””โ”€โ”€ Deshare.t.sol               # End-to-end workflow tests

Test Categories

  • Unit Tests: Individual Deshare, PowerPass, and ShareX Wallet function validation
  • Integration Tests: Multi-component workflow testing across all systems
  • Access Control Tests: Role-based permission validation for all contracts
  • Security Tests: Input validation and error handling across all components
  • Edge Case Testing: Boundary conditions and error scenarios
  • Gas Optimization Tests: Performance and efficiency validation
  • NFT Tests: ERC721 compliance and metadata functionality
  • Wallet Tests: Multi-token operations and wallet management functionality
  • Batch Operation Tests: Efficient multi-transfer and multi-call validations

Comprehensive test coverage of all Deshare Protocol functionality including PowerPass NFT system and ShareX Wallet management.

๐Ÿ”’ Security Considerations

Access Control Roles

Deshare Roles

  • DEFAULT_ADMIN_ROLE: Complete system administration and role management
  • OPERATOR_ROLE: Day-to-day protocol operations and entity registration

PowerPass Roles

  • DEFAULT_ADMIN_ROLE: PowerPass administration and token URI management
  • MINTER_ROLE: PowerPass minting operations

Proxy Security Architecture

  • Initializable Pattern: Secure initialization with disable guards for implementation
  • Implementation Security: Storage layout protection and initialization guards
  • Role Separation: Clear boundaries between proxy and business logic control

Risk Management

  • Input Validation: Comprehensive parameter validation and bounds checking
  • Reentrancy Protection: ReentrancyGuard on transaction batch uploads
  • Data Integrity: Immutable transaction records and audit trails
  • Access Control: Role-based permissions with proper inheritance
  • Counter Management: Secure incrementing counters for unique ID generation
  • Batch Processing Security: Transaction validation and data consistency checks

๐Ÿ“Š Performance Metrics

Gas Optimization

  • Efficient Data Structures: Optimized struct packing and storage patterns
  • Batch Operations: Reduced transaction costs through bulk processing
  • Data Compression: LibZip compression reduces storage costs by 30%+
  • Minimal External Calls: Streamlined contract interactions
  • Strategic Storage: Cost-effective state variable management

Scalability Features

  • High-Throughput Processing: Efficient batch transaction handling with compression
  • Optimized Queries: Fast data retrieval and partner/merchant lookups
  • Event-Driven Architecture: Comprehensive event emission for off-chain analytics
  • Upgradeable Design: Future-proof architecture for continuous improvements

Expected Performance (Network Dependent)

  • Transaction Processing: 100+ transactions per batch (MAX_BATCH_SIZE limit)
  • Partner Onboarding: Sub-second registration with verification
  • Device Management: Real-time registration and dependency validation
  • Query Performance: Efficient data retrieval across all entity types
  • Compression Efficiency: 30%+ reduction in storage costs through LibZip compression

Note: Performance metrics vary based on network congestion, gas prices, and batch sizes. The system is optimized for high-throughput protocol operations with compressed data storage.

๐Ÿ› ๏ธ Deployment

Prerequisites

# Install Foundry
curl -L https://foundry.paradigm.xyz | bash
foundryup

# Clone and setup project
git clone <repository-url>
cd sharex-evm-contracts
forge install

Build and Test

# Clean and build contracts
make clean && make build

# Run comprehensive tests
make foundry-test

# Generate ABI files
make abi

Local Development

# Start local Anvil node
anvil

# Deploy to local network (dry run first)
DEPLOYMENT_CONTEXT=local forge script script/Deploy.s.sol:Deploy --ffi -vvv

# Deploy with broadcast
DEPLOYMENT_CONTEXT=local forge script script/Deploy.s.sol:Deploy \
  --rpc-url http://localhost:8545 \
  --private-key $PRIVATE_KEY \
  --broadcast --ffi -vvv

BSC Testnet Deployment

Environment Setup

Create a .env file in the project root:

# BSC Testnet Configuration
PRIVATE_KEY=your_private_key_without_0x_prefix
CHAIN_ID=97
RPC_URL=https://data-seed-prebsc-1-s1.binance.org:8545
VERIFIER=etherscan
VERIFIER_URL=https://api.etherscan.io/v2/api
ETHERSCAN_API_KEY=your_bscscan_api_key_here
DEPLOYMENT_CONTEXT=bsc-testnet

Deployment Commands (All Contracts)

# 1. Build contracts
forge build

# 2. Deploy all contracts at once (legacy approach)
source .env && DEPLOYMENT_CONTEXT="bsc-testnet" forge script script/Deploy.s.sol:Deploy \
  --rpc-url $RPC_URL \
  --private-key $PRIVATE_KEY \
  --broadcast --ffi -vvv

Deploy contracts individually for better control and flexibility:

# 1. Build contracts
forge build

# 2a. Deploy Deshare contract only
source .env && DEPLOYMENT_CONTEXT="bsc-testnet" forge script script/DeployDeshare.s.sol:DeployDeshare \
  --rpc-url $RPC_URL \
  --private-key $PRIVATE_KEY \
  --broadcast --ffi -vvv

# 2b. Deploy ShareX USDT (test token) first
source .env && DEPLOYMENT_CONTEXT="bsc-testnet" forge script script/DeployShareXUSDT.s.sol:DeployShareXUSDT \
  --rpc-url $RPC_URL \
  --private-key $PRIVATE_KEY \
  --broadcast --verify --etherscan-api-key $ETHERSCAN_API_KEY --ffi -vvv

# 2c. Deploy PowerPass contract only (requires payment token in config)
source .env && DEPLOYMENT_CONTEXT="bsc-testnet" forge script script/DeployPowerPass.s.sol:DeployPowerPass \
  --rpc-url $RPC_URL \
  --private-key $PRIVATE_KEY \
  --broadcast --verify --etherscan-api-key $ETHERSCAN_API_KEY --ffi -vvv

# 2d. Deploy ShareX Wallet Manager contract only
source .env && DEPLOYMENT_CONTEXT="bsc-testnet" forge script script/DeployShareXWalletManager.s.sol:DeployShareXWalletManager \
  --rpc-url $RPC_URL \
  --private-key $PRIVATE_KEY \
  --broadcast --ffi -vvv

# 2e. Deploy ShareX Keys Series contract only
source .env && DEPLOYMENT_CONTEXT="bsc-testnet" forge script script/DeployShareXKeysSeries.s.sol:DeployShareXKeysSeries \
  --rpc-url $RPC_URL \
  --private-key $PRIVATE_KEY \
  --broadcast --verify --etherscan-api-key $ETHERSCAN_API_KEY --ffi -vvv

# 3. Verify contracts manually (if needed)
source .env && forge verify-contract <CONTRACT_ADDRESS> src/Deshare.sol:Deshare \
  --chain-id 97 \
  --etherscan-api-key $ETHERSCAN_API_KEY \
  --constructor-args $(cast abi-encode "constructor(address)" 0xd559c7e581233F19cD4E3F2Ce969ddE01D3dEEC4)

Post-Deployment Validation

# Validate deployment
source .env
export PROXY_ADDRESS=$(jq -r '.DeshareProxy' deployments/bsc-testnet/.deploy)
cast call $PROXY_ADDRESS "getVersion()" --rpc-url $RPC_URL
cast call $PROXY_ADDRESS "hasRole(bytes32,address)" \
  0x0000000000000000000000000000000000000000000000000000000000000000 \
  0xd559c7e581233F19cD4E3F2Ce969ddE01D3dEEC4 --rpc-url $RPC_URL

Deployed Contracts (BSC Testnet)

ContractAddressBSCScan Link
Deshare (Implementation)0x09D3E9d08348b22AB5E03158Dc1927da4646EB79View on BSCScan
DeshareProxy (Main Contract)0x23E89f8aC6e7751095fD5DbC71B89Bd1C60f23C7View on BSCScan
PowerPass (Implementation)0x40635E6f3D1F4f3311E0Bc892A4Ee38fD7fd4ce3View on BSCScan
PowerPassProxy (Main Contract)0x3d3624D578bf7bF81a76633a355320B3123c70f7View on BSCScan
PowerPassProxyAdmin0x734b8EbAe5992d4795D6b919aAfFA17Edd1ED099View on BSCScan
PowerPassStaking (Implementation)0xcDA6366b624D4Fe52f25469912E3c788F0D19024View on BSCScan
PowerPassStakingProxy (Main Contract)0x5560e8CD017D2BD8474601D682731a807a66654BView on BSCScan
PowerPassStakingProxyAdmin0x2c56854aaf4d483b85f0580dad5ae4eec8fc4148View on BSCScan
ShareXUSDT (Test Token)0x6350a32a4406469608B5D93A77572e140b5F3D73View on BSCScan
ShareXWalletManager (Implementation)0x0e0517EF0c011757Ea71FeeB2766481F440bB3DdView on BSCScan
ShareXWalletManagerProxy (Main Contract)0x5dC5Fdb90E57A5390c6524414f3d6da0b3Ef0f48View on BSCScan
ShareXWalletManagerProxyAdmin0xe86657f17b8d155b06cba4481bd3391be9d2886fView on BSCScan
ShareXKeysSeries (ERC1155 NFT)0x5F8044C7Acf488C359EB1c8afDfc4e57c8E1733aView on BSCScan
ShareXKeysStaking (Implementation)0x5e2a4C4D0fe6b1aa871bB7EBfeA54ea6f0439850View on BSCScan
ShareXKeysStakingProxy (Main Contract)0xfCb95edFBEB8e47492558c6E36db7B8F6766D220View on BSCScan
ProxyAdmin0x606ad7a222bdcc5a43a1927794c29122d708e289View on BSCScan

Network Details:

  • Chain ID: 97 (BSC Testnet)
  • RPC URL: https://data-seed-prebsc-1-s1.binance.org:8545
  • Explorer: BSCScan Testnet
  • Admin Address: 0xd559c7e581233F19cD4E3F2Ce969ddE01D3dEEC4
  • ProxyAdmin Owner: 0xd559c7e581233F19cD4E3F2Ce969ddE01D3dEEC4
  • PowerPass Admin/Minter: 0xd559c7e581233F19cD4E3F2Ce969ddE01D3dEEC4

PowerPassStaking Configuration:

  • PowerPass Contract: 0x3d3624D578bf7bF81a76633a355320B3123c70f7
  • Payment Token: ShareXUSDT (0x6350a32a4406469608B5D93A77572e140b5F3D73)
  • Default Reward Percentage: 25% (2500 BPS)

Environment Variables (BSC Testnet):

export POWERPASS_PROXY=0x3d3624D578bf7bF81a76633a355320B3123c70f7
export POWERPASS_STAKING=0x5560e8CD017D2BD8474601D682731a807a66654B
export POWERPASS_STAKING_IMPL=0xcDA6366b624D4Fe52f25469912E3c788F0D19024
export POWERPASS_STAKING_PROXY_ADMIN=0x2c56854aaf4d483b85f0580dad5ae4eec8fc4148
export WALLET_MANAGER=0x5dC5Fdb90E57A5390c6524414f3d6da0b3Ef0f48
export USDT_TOKEN=0x6350a32a4406469608B5D93A77572e140b5F3D73
export ADMIN_ADDRESS=0xd559c7e581233F19cD4E3F2Ce969ddE01D3dEEC4

Deployed Contracts (BSC Mainnet)

ContractAddressBSCScan Link
PowerPass (Implementation)0x4a0A3da46f0adF8491F9134f2FaeA880115C4949View on BSCScan
PowerPassProxy (Main Contract)0xdF9A38E920902022eF54B5F05bD28C8ca4eFD961View on BSCScan
PowerPassProxyAdmin0xed4c0d0c1815c5ed4e03487655e8550bcac244caView on BSCScan
ShareXWalletManager (Implementation)0x517D18cE441D8B249eB40b6dc363Df13B8D01451View on BSCScan
ShareXWalletManagerProxy (Main Contract)0x371c05B0CC9B6Fc3794A911DdD2DfbB266db5b38View on BSCScan
ShareXWalletManagerProxyAdmin0x4cdb3d86e876c714f691021418e62bd3e7b18210View on BSCScan
ShareXKeysSeries (ERC1155 NFT)0x28e3889A3bc57D4421a5041E85Df8b516Ab683F8View on BSCScan
ShareXKeysStaking (Implementation)0x75a487bE463431F96765f2007e45b9C9bA3BED38View on BSCScan
ShareXKeysStakingProxy (Main Contract)0xC7e54532ea427b7Bcf682dc0BEF24CD1338b3026View on BSCScan
ShareXMomentumBadge (ERC721 NFT)0x7184dCdFEBEE6D3910782FBEEE5Ea1470692eb21View on BSCScan
ProxyAdmin (Keys)0x84D27c82B5191E8CdDE5772d42657A39e55333C3View on BSCScan

Network Details:

  • Chain ID: 56 (BSC Mainnet)
  • RPC URL: https://bsc-dataseed.bnbchain.org
  • Explorer: BSCScan
  • Admin Address: 0x3047dB262c4e142B2C7927BB7df5cC86A0f6EE78
  • ProxyAdmin Owner: 0x3047dB262c4e142B2C7927BB7df5cC86A0f6EE78
  • PowerPass Payment Token: BSC USDT (0x55d398326f99059fF775485246999027B3197955) - 18 decimals
  • PowerPass Base URI: https://f004.backblazeb2.com/file/sharex-powerpass/metadata/
  • PowerPass MAX_SUPPLY: 5000
  • ShareXMomentumBadge: Symbol "SMB", Metadata URI: https://rwa.sharex.network/metadata/momentum-badge.json

PowerPass Sales Schedule (UTC):

  • Priority Whitelist: Dec 22, 2025, 10:00 - 14:00
  • General Whitelist: Dec 22, 2025, 14:00 - Dec 23, 2025, 14:00

PowerPass Pricing:

  • Standard Price: 50 USDT
  • Discount Code: 5 USDT discount (45 USDT final)
  • Nova Discount: 80% (40 USDT)

Deployed Contracts (opBNB Mainnet)

ContractAddressopBNBScan Link
Deshare (Implementation)0xD81B9c15dE92D9A5e373d3E0817B648987079c37View on opBNBScan
DeshareProxy (Main Contract)0x28e3889A3bc57D4421a5041E85Df8b516Ab683F8View on opBNBScan
ProxyAdmin0xdfd3c8bf6dad595293ecdce4c0e1b485f072119aView on opBNBScan

Network Details:

  • Chain ID: 204 (opBNB Mainnet)
  • RPC URL: https://opbnb-mainnet-rpc.bnbchain.org
  • Explorer: opBNBScan
  • Admin Address: 0x3047dB262c4e142B2C7927BB7df5cC86A0f6EE78
  • ProxyAdmin Owner: 0x3047dB262c4e142B2C7927BB7df5cC86A0f6EE78

Contract Verification on opBNBScan

Command-Line Verification using NodeReal API:

# Set environment variables
export NODEREAL_API_KEY=051d517322704e9aba88993bd8e2555b
export RPC_URL=https://opbnb-mainnet-rpc.bnbchain.org

# Method 1: Direct verification with NodeReal URL
forge verify-contract 0xD81B9c15dE92D9A5e373d3E0817B648987079c37 src/Deshare.sol:Deshare \
  --chain-id 204 \
  --verifier-url "https://open-platform.nodereal.io/$NODEREAL_API_KEY/op-bnb-mainnet/contract/" \
  --constructor-args $(cast abi-encode "constructor(address)" 0x3047dB262c4e142B2C7927BB7df5cC86A0f6EE78)

# Method 2: Using etherscan verifier with NodeReal endpoint
forge verify-contract 0xD81B9c15dE92D9A5e373d3E0817B648987079c37 src/Deshare.sol:Deshare \
  --chain-id 204 \
  --verifier etherscan \
  --etherscan-api-key $NODEREAL_API_KEY \
  --verifier-url "https://open-platform.nodereal.io/$NODEREAL_API_KEY/op-bnb-mainnet/contract/" \
  --constructor-args $(cast abi-encode "constructor(address)" 0x3047dB262c4e142B2C7927BB7df5cC86A0f6EE78)

Manual Verification via opBNBScan Web Interface:

If command-line verification encounters issues, verify manually:

  1. Visit Verification Page: opBNBScan Contract Verification
  2. Enter Contract Details:
    • Contract Address: 0xD81B9c15dE92D9A5e373d3E0817B648987079c37
    • Compiler Type: Solidity (Single file) or Standard JSON Input
  3. Compiler Settings:
    • Compiler Version: 0.8.24
    • Optimization: Yes (999999 runs)
    • EVM Version: Paris
  4. Constructor Arguments: 0x0000000000000000000000003047db262c4e142b2c7927bb7df5cC86A0f6EE78
  5. Contract Source: Upload flattened contract or standard JSON input

Getting ProxyAdmin Address Programmatically:

# Get ProxyAdmin address from proxy storage slot
export PROXY_ADDRESS=0x28e3889A3bc57D4421a5041E85Df8b516Ab683F8
cast storage $PROXY_ADDRESS 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103 --rpc-url $RPC_URL
# Returns: 0x000000000000000000000000dfd3c8bf6dad595293ecdce4c0e1b485f072119a (ProxyAdmin)

Usage Notes:

  • Use the DeshareProxy address (0x28e3889A3bc57D4421a5041E85Df8b516Ab683F8) for all Deshare interactions
  • The ProxyAdmin (0xdfd3c8bf6dad595293ecdce4c0e1b485f072119a) controls proxy upgrades
  • NodeReal API Key: Get from NodeReal Platform
  • Verification Guide: BNB Chain opBNB Verification Documentation

Important Deployment Notes:

  • Environment Variables: Always use source .env to load environment variables before deployment
  • Private Key Format: Use raw private key without 0x prefix in .env file
  • RPC Endpoint: Use the stable BSC testnet RPC endpoint for reliable connections
  • Verification: Manual verification may be required if automatic verification fails

Usage Notes (BSC Testnet):

  • Use the DeshareProxy address (0x23E89f8aC6e7751095fD5DbC71B89Bd1C60f23C7) for all Deshare interactions
  • Use the PowerPassProxy address (0x3d3624D578bf7bF81a76633a355320B3123c70f7) for all PowerPass NFT operations
  • Use the ShareXUSDT address (0x6350a32a4406469608B5D93A77572e140b5F3D73) for PowerPass payment token operations
  • Use the ShareXWalletManagerProxy address (0x5dC5Fdb90E57A5390c6524414f3d6da0b3Ef0f48) for all wallet management operations
  • Use the ShareXKeysSeries address (0x5F8044C7Acf488C359EB1c8afDfc4e57c8E1733a) for all Keys Series NFT operations
  • Use the ShareXKeysStakingProxy address (0xfCb95edFBEB8e47492558c6E36db7B8F6766D220) for all Keys staking operations

Usage Notes (BSC Mainnet):

  • Use the PowerPassProxy address (0xdF9A38E920902022eF54B5F05bD28C8ca4eFD961) for all PowerPass NFT operations on BSC mainnet
  • Use the ShareXWalletManagerProxy address (0x371c05B0CC9B6Fc3794A911DdD2DfbB266db5b38) for all wallet management operations on BSC mainnet
  • Use the ShareXKeysSeries address (0x28e3889A3bc57D4421a5041E85Df8b516Ab683F8) for all Keys Series NFT operations on BSC mainnet
  • Use the ShareXKeysStakingProxy address (0xC7e54532ea427b7Bcf682dc0BEF24CD1338b3026) for all Keys staking operations on BSC mainnet
  • Use the ShareXMomentumBadge address (0x7184dCdFEBEE6D3910782FBEEE5Ea1470692eb21) for all Momentum Badge NFT operations on BSC mainnet

opBNB Mainnet Deployment

Environment Setup

Create a .env file in the project root:

# opBNB Mainnet Configuration
PRIVATE_KEY=your_private_key_without_0x_prefix
CHAIN_ID=204
RPC_URL=https://opbnb-mainnet-rpc.bnbchain.org
VERIFIER=etherscan
VERIFIER_URL=https://open-platform.nodereal.io/YOUR_NODEREAL_API_KEY/op-bnb-mainnet/contract/
ETHERSCAN_API_KEY=your_nodereal_api_key_here
NODEREAL_API_KEY=your_nodereal_api_key_here
DEPLOYMENT_CONTEXT=opbnb-mainnet

Deployment Commands

# 1. Build contracts
forge build

# 2. Deploy Deshare contract only
source .env && DEPLOYMENT_CONTEXT="opbnb-mainnet" forge script script/DeployDeshare.s.sol:DeployDeshare \
  --rpc-url $RPC_URL \
  --private-key $PRIVATE_KEY \
  --broadcast --ffi -vvv

# 3. Verify contract (using NodeReal API)
source .env && forge verify-contract 0xD81B9c15dE92D9A5e373d3E0817B648987079c37 src/Deshare.sol:Deshare \
  --chain-id 204 \
  --verifier-url "https://open-platform.nodereal.io/$NODEREAL_API_KEY/op-bnb-mainnet/contract/" \
  --constructor-args $(cast abi-encode "constructor(address)" 0x3047dB262c4e142B2C7927BB7df5cC86A0f6EE78)

Supported Networks

  • Local: Anvil development network for testing
  • BSC Testnet: Binance Smart Chain testnet (Chain ID: 97)
  • BSC Mainnet: Production deployment target
  • opBNB Mainnet: opBNB Layer 2 mainnet (Chain ID: 204)
  • Devnet: Custom development network for staging

Deployment Artifacts

  • Contract addresses stored in deployments/[network]/.deploy
  • Chain ID configuration in deployments/[network]/.chainId
  • Network-specific configs in deploy-config/[network].json

๐Ÿ”„ Contract Upgrades

Upgrade Architecture

The Deshare Protocol uses OpenZeppelin's TransparentUpgradeableProxy pattern with clear role separation:

  • ProxyAdmin Contract: 0x606ad7a222bdcc5a43a1927794c29122d708e289
  • ProxyAdmin Owner: 0xd559c7e581233F19cD4E3F2Ce969ddE01D3dEEC4 (controls proxy upgrades)
  • Deshare Admin: 0xd559c7e581233F19cD4E3F2Ce969ddE01D3dEEC4 (controls business logic)

Step-by-Step Upgrade Process

# 1. Deploy new implementation
source .env && forge script script/DeployNewImplementation.s.sol:DeployNewImplementation \
  --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast -vvv

# 2. Get ProxyAdmin address from storage slot
export PROXY_ADMIN=$(cast storage 0x23E89f8aC6e7751095fD5DbC71B89Bd1C60f23C7 \
  0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103 \
  --rpc-url $RPC_URL)

# 3. Upgrade proxy to new implementation (ProxyAdmin owner only)
source .env && cast send $PROXY_ADMIN "upgradeAndCall(address,address,bytes)" \
  0x23E89f8aC6e7751095fD5DbC71B89Bd1C60f23C7 \
  <NEW_IMPLEMENTATION_ADDRESS> \
  0x \
  --rpc-url $RPC_URL --private-key $PRIVATE_KEY

# 4. Verify upgrade success
cast storage 0x23E89f8aC6e7751095fD5DbC71B89Bd1C60f23C7 \
  0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc \
  --rpc-url $RPC_URL

# 5. Test functionality (both old and new methods)
cast call 0x23E89f8aC6e7751095fD5DbC71B89Bd1C60f23C7 "getVersion()" --rpc-url $RPC_URL
cast call 0x23E89f8aC6e7751095fD5DbC71B89Bd1C60f23C7 "getStats()" --rpc-url $RPC_URL
cast call 0x23E89f8aC6e7751095fD5DbC71B89Bd1C60f23C7 "getDetailedStats()" --rpc-url $RPC_URL

# 6. Verify new implementation on BSCScan
source .env && forge verify-contract <NEW_IMPLEMENTATION_ADDRESS> src/Deshare.sol:Deshare \
  --chain-id 97 --etherscan-api-key $ETHERSCAN_API_KEY \
  --constructor-args $(cast abi-encode "constructor(address)" 0xd559c7e581233F19cD4E3F2Ce969ddE01D3dEEC4)

Recent Upgrade Example (Enhanced Stats)

Upgrade Transaction: 0xeb375b644110da420ec9278423a16052349fb84ae118eb2737035e13c766c460

  • From Implementation: 0x70E027Ce8B5a9FEdaE0fa04ED95d03214cCEcE25
  • To Implementation: 0x09D3E9d08348b22AB5E03158Dc1927da4646EB79
  • New Feature: Enhanced getDetailedStats() method with user-friendly labels
  • Verification: View on BSCScan
  • Status: โœ… Successfully deployed and verified

Upgrade Safety Guidelines

  • Storage Layout: Never modify existing storage variable order or types
  • Initialization: Use separate initializeV2(), initializeV3() functions for new versions
  • Testing: Always test upgrades on local/testnet before mainnet
  • Multi-sig: Use multi-signature wallets for production upgrades
  • Verification: Always verify new implementation contracts on BSCScan
  • Documentation: Update all relevant documentation after upgrades

๐Ÿค Contributing

We welcome contributions to the Deshare Protocol! Please follow our development guidelines:

Development Workflow

  1. Fork the repository and create a feature branch
  2. Write comprehensive tests for new functionality
  3. Ensure all tests pass (make foundry-test)
  4. Follow Solidity coding standards and security best practices
  5. Update documentation and examples as needed
  6. Submit a pull request with detailed description

Coding Standards

  • Follow Solidity 0.8.24 best practices
  • Use NatSpec documentation for all public functions
  • Implement proper access control and input validation
  • Write comprehensive unit and integration tests
  • Maintain gas efficiency and optimization

Security Guidelines

  • Never modify storage layout in upgrades
  • Always validate inputs and check access controls
  • Use established patterns for reentrancy protection
  • Test upgrade scenarios on testnet before mainnet

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


โš ๏ธ Disclaimer: This software is provided as-is for ecosystem management purposes. While designed with security best practices, users should conduct thorough testing and audits before production deployment. Use at your own risk and ensure compliance with applicable regulations.

Contents

IDeshare

Git Source

Title: IDeshare

Interface for the Deshare contract

Functions

registerPartner

Register a new partner

function registerPartner(PartnerParams calldata params) external;

Parameters

NameTypeDescription
paramsPartnerParamsPartner registration parameters

registerMerchant

Register a new merchant

function registerMerchant(MerchantParams calldata params) external;

Parameters

NameTypeDescription
paramsMerchantParamsMerchant registration parameters

registerDevice

Register a new device

function registerDevice(DeviceParams calldata params) external;

Parameters

NameTypeDescription
paramsDeviceParamsDevice registration parameters

uploadTransactionBatch

Upload a transaction batch

function uploadTransactionBatch(UploadBatchParams calldata params) external;

Parameters

NameTypeDescription
paramsUploadBatchParamsUpload batch parameters

registerCountry

Register a country

function registerCountry(bytes2 iso2) external;

Parameters

NameTypeDescription
iso2bytes2The ISO2 country code

getVersion

Get the contract version

function getVersion() external view returns (Version memory);

Returns

NameTypeDescription
<none>Versionversion The current version

getStats

Get statistics information

function getStats() external view returns (StatsInfo memory);

Returns

NameTypeDescription
<none>StatsInfostats The current statistics

getDetailedStats

Get detailed statistics information with descriptive labels

function getDetailedStats() external view returns (DetailedStatsInfo memory);

Returns

NameTypeDescription
<none>DetailedStatsInfodetailedStats The detailed statistics with labels and metadata

getPartner

Get partner information by ID

function getPartner(uint256 partnerId) external view returns (PartnerInfo memory);

Parameters

NameTypeDescription
partnerIduint256The partner ID

Returns

NameTypeDescription
<none>PartnerInfopartner The partner information

getPartnerByCode

Get partner information by partner code

function getPartnerByCode(string calldata partnerCode)
    external
    view
    returns (PartnerInfo memory);

Parameters

NameTypeDescription
partnerCodestringThe partner code

Returns

NameTypeDescription
<none>PartnerInfopartner The partner information

partnerExists

Check if a partner exists by code

function partnerExists(string calldata partnerCode) external view returns (bool);

Parameters

NameTypeDescription
partnerCodestringThe partner code

Returns

NameTypeDescription
<none>boolexists Whether the partner exists

getMerchant

Get merchant information by ID

function getMerchant(uint256 merchantId) external view returns (MerchantInfo memory);

Parameters

NameTypeDescription
merchantIduint256The merchant ID

Returns

NameTypeDescription
<none>MerchantInfomerchant The merchant information

getMerchantById

Get merchant information by merchant ID

function getMerchantById(string calldata merchantId) external view returns (MerchantInfo memory);

Parameters

NameTypeDescription
merchantIdstringThe merchant ID (string)

Returns

NameTypeDescription
<none>MerchantInfomerchant The merchant information

merchantExists

Check if a merchant exists by ID

function merchantExists(string calldata merchantId) external view returns (bool);

Parameters

NameTypeDescription
merchantIdstringThe merchant ID

Returns

NameTypeDescription
<none>boolexists Whether the merchant exists

getDevice

Get device information by ID

function getDevice(uint256 deviceId) external view returns (DeviceInfo memory);

Parameters

NameTypeDescription
deviceIduint256The device ID

Returns

NameTypeDescription
<none>DeviceInfodevice The device information

getDeviceById

Get device information by device ID

function getDeviceById(string calldata deviceId) external view returns (DeviceInfo memory);

Parameters

NameTypeDescription
deviceIdstringThe device ID (string)

Returns

NameTypeDescription
<none>DeviceInfodevice The device information

deviceExists

Check if a device exists by ID

function deviceExists(string calldata deviceId) external view returns (bool);

Parameters

NameTypeDescription
deviceIdstringThe device ID

Returns

NameTypeDescription
<none>boolexists Whether the device exists

getTransactionBatch

Get transaction batch by ID

function getTransactionBatch(uint256 batchId) external view returns (TransactionBatch memory);

Parameters

NameTypeDescription
batchIduint256The batch ID

Returns

NameTypeDescription
<none>TransactionBatchbatch The transaction batch

getCountry

Get country information

function getCountry(bytes2 iso2) external view returns (CountryInfo memory);

Parameters

NameTypeDescription
iso2bytes2The ISO2 country code

Returns

NameTypeDescription
<none>CountryInfocountry The country information

countryExists

Check if a country is registered

function countryExists(bytes2 iso2) external view returns (bool);

Parameters

NameTypeDescription
iso2bytes2The ISO2 country code

Returns

NameTypeDescription
<none>boolexists Whether the country is registered

getPartnerCountByBusinessType

Get the number of partners for a given business type

function getPartnerCountByBusinessType(string calldata businessType)
    external
    view
    returns (uint256);

Parameters

NameTypeDescription
businessTypestringThe business type to query

Returns

NameTypeDescription
<none>uint256The count of partners

getMerchantCountByRegion

Get the number of merchants for a given region

function getMerchantCountByRegion(bytes2 iso2, string calldata locationId)
    external
    view
    returns (uint256);

Parameters

NameTypeDescription
iso2bytes2The ISO2 country code
locationIdstringThe location ID (e.g., city identifier)

Returns

NameTypeDescription
<none>uint256The count of merchants

getTransactionData

Retrieves transaction data for a batch

function getTransactionData(uint256 batchId) external view returns (string memory jsonData);

Parameters

NameTypeDescription
batchIduint256The batch ID to retrieve data for

Returns

NameTypeDescription
jsonDatastringThe transaction data as JSON string

IPowerPass

Git Source

Inherits: IERC721

Title: PowerPass Interface

Author: ShareX Team

ERC721 interface for ShareX ecosystem access NFTs with whitelist-based sales rounds PowerPass serves as the premium access token for the ShareX ecosystem, providing holders with exclusive privileges and early access to ecosystem features. The contract implements sophisticated time-based sales rounds with whitelist eligibility determined by ShareX Keys Series staking activity. Key Features:

  • Time-based sales rounds (Priority and General) with UTC+8 scheduling
  • Snapshot-based whitelist eligibility tied to ShareX Keys Series staking
  • Gas-optimized operations using RareSkills patterns
  • Upgradeable proxy pattern for future enhancements
  • Batch operations for efficient multi-user management
  • Off-chain whitelist ingestion; no on-chain staking dependency Sales Round Structure:
  • Priority Round: MAGNA/NOVA stakers get exclusive access (+5 per token, max 10 NFTs)
  • General Round: All stakers get access (+2 per ESSENTIA, +5 per MAGNA/NOVA, max 10 NFTs)
  • Admin-configurable timestamps and pricing
  • Snapshot-based allocation should be computed off-chain and ingested via whitelist Security Considerations:
  • All administrative functions require DEFAULT_ADMIN_ROLE
  • Whitelist allocations are snapshot-based and immutable once set
  • Time-based validations prevent early/late minting
  • Payment validation ensures correct pricing
  • Reentrancy protection on all state-changing functions Usage Example:
// User checks their status during sales rounds
MintStatus memory status = powerPass.getMintStatus(user);
// status.priorityRemaining, status.generalRemaining, status.standardPrice
// User mints during active sales round
powerPass.mint(amount, discountCode);

Functions

startNewRound

Start a new sales round with configuration and supply limit

Admin function to create a new round; increments roundId automatically

function startNewRound(SalesConfig calldata config, uint256 supplyLimit) external;

Parameters

NameTypeDescription
configSalesConfigSales configuration including timestamps and pricing
supplyLimituint256Maximum NFTs for this round (0 = no limit, still capped by MAX_SUPPLY) Requirements: - Caller must have DEFAULT_ADMIN_ROLE - Priority round must end before or when general round starts - All timestamps must be future timestamps (> block.timestamp) - Standard price must be greater than 0 Emits: PowerPassNewRoundStarted event

mint

Mint PowerPass NFTs during active sales rounds

Gas-optimized minting with comprehensive validation

function mint(uint256 amount, string calldata discountCode) external payable;

Parameters

NameTypeDescription
amountuint256Number of NFTs to mint
discountCodestringOptional discount code string; ignored when empty or Nova discount applies Validation includes: - Active sales round verification (priority or general) - Whitelist allocation and remaining balance checks - Payment in ERC20 payment token (e.g., USDT) equals applicable discounted price * amount - Maximum supply limit enforcement Requirements: - Active sales round (priority or general) must be ongoing - Amount must not exceed remaining allocation for current round - Payment must be provided via ERC20 approve + transferFrom - User must have whitelist allocation for current round Emits: PowerPassBatchMinted event

batchSetWhitelists

Batch set whitelist allocations for multiple users

Admin function for efficient whitelist management. Preserves already minted counts and clamps new allocations to be >= minted so far for each round.

function batchSetWhitelists(
    address[] calldata accounts,
    uint256[] calldata priorityAmounts,
    uint256[] calldata generalAmounts
) external;

Parameters

NameTypeDescription
accountsaddress[]Array of addresses to set allocations for
priorityAmountsuint256[]Array of priority allocations corresponding to accounts
generalAmountsuint256[]Array of total (priority + general) allocations corresponding to accounts Requirements: - Caller must have DEFAULT_ADMIN_ROLE - All arrays must have equal length - No account can be zero address - Never reduces effective allocation below already minted amounts - Gas-optimized with unchecked arithmetic for large batches Emits: PowerPassBatchWhitelistSet event

batchSetNovaDiscounts

Batch set Nova discount allocations for multiple users

Admin function to configure 80% pricing eligibility per address

function batchSetNovaDiscounts(
    address[] calldata accounts,
    uint256[] calldata discountAllocations
) external;

Parameters

NameTypeDescription
accountsaddress[]Array of addresses to configure
discountAllocationsuint256[]Array of discount allocations corresponding to accounts

batchSetCustodialWhitelists

Batch set custodial mint allocations for ShareX wallet users

Separate whitelist for web2 custodial flow; amounts represent direct mint allowance

function batchSetCustodialWhitelists(
    address[] calldata accounts,
    uint256[] calldata allocations
) external;

Parameters

NameTypeDescription
accountsaddress[]Custodial wallet addresses (ShareX wallet addresses or end-user custodial addrs)
allocationsuint256[]Total NFTs each address may receive via custodial mint

setBaseURI

Set the base URI for token metadata

Admin function to configure NFT metadata URIs

function setBaseURI(string calldata baseURI) external;

Parameters

NameTypeDescription
baseURIstringThe new base URI for all tokens Requirements: - Caller must have DEFAULT_ADMIN_ROLE - BaseURI should point to valid metadata endpoint Emits: PowerPassBaseURIUpdated event

withdrawFunds

Withdraw payment tokens to admin

Admin function to withdraw accumulated ERC20 (USDT) from sales Requirements:

  • Caller must have DEFAULT_ADMIN_ROLE
  • Contract must have token balance > 0 Emits: PowerPassFundsWithdrawn event
function withdrawFunds() external;

setPaymentToken

Set ERC20 payment token address (e.g., USDT on BSC)

Admin function; price is interpreted in this token's decimals

function setPaymentToken(address token) external;

Parameters

NameTypeDescription
tokenaddressERC20 token address used for payments

setDiscountCodeDiscount

Set global discount amount applied when using a valid code

function setDiscountCodeDiscount(uint256 discountAmount) external;

Parameters

NameTypeDescription
discountAmountuint256Amount deducted per NFT when discount code is used

addDiscountCodes

Register discount code hashes that can be redeemed on-chain

function addDiscountCodes(bytes32[] calldata codeHashes) external;

Parameters

NameTypeDescription
codeHashesbytes32[]Array of keccak256 hashes of discount codes

removeDiscountCodes

Remove discount code hashes

function removeDiscountCodes(bytes32[] calldata codeHashes) external;

Parameters

NameTypeDescription
codeHashesbytes32[]Array of keccak256 hashes of discount codes to remove

burn

Burn a PowerPass NFT token

Allows token owner or approved operator to burn tokens

function burn(uint256 tokenId) external;

Parameters

NameTypeDescription
tokenIduint256The ID of the token to burn Requirements: - Token must exist - Caller must be token owner or approved operator - Updates total supply counter Emits: PowerPassBurned event

setTokenURI

Set token URI for a specific PowerPass NFT

Admin function to update metadata URI for individual tokens

function setTokenURI(uint256 tokenId, string calldata newTokenURI) external;

Parameters

NameTypeDescription
tokenIduint256The ID of the token to update
newTokenURIstringThe new URI for the token metadata Requirements: - Caller must have DEFAULT_ADMIN_ROLE - Token must exist - URI should point to valid metadata Emits: URI update through OpenZeppelin's ERC721URIStorage

getMintStatus

Get current mint status for a user

View function providing complete minting information and round status

function getMintStatus(address account) external view returns (MintStatus memory status);

Parameters

NameTypeDescription
accountaddressThe address to query mint status for

Returns

NameTypeDescription
statusMintStatusComplete mint status including allocations, current price, and round status The MintStatus contains: - priorityRemaining: NFTs remaining in priority allocation - generalRemaining: NFTs remaining in general allocation - standardPrice: Current standard price per NFT based on active round - isPriorityActive: Whether priority round is currently active - isGeneralActive: Whether general round is currently active

getWhitelistInfo

Get whitelist allocations for an account

View function for checking total allocations across both rounds

function getWhitelistInfo(address account) external view returns (WhitelistInfo memory info);

Parameters

NameTypeDescription
accountaddressThe address to query allocations for

Returns

NameTypeDescription
infoWhitelistInfoComplete whitelist information including allocations and minted amounts The WhitelistInfo contains: - priorityAllocation: Total NFTs allocated for priority round - generalAllocation: Total NFTs allocated for general round - priorityMinted: Already minted in priority round - generalMinted: Already minted in general round

getCustodialWhitelistInfo

Get custodial whitelist allocation info for a ShareX wallet address

function getCustodialWhitelistInfo(address account)
    external
    view
    returns (CustodialWhitelistInfo memory info);

getSalesConfig

Get current sales configuration (from current round)

View function for checking sales round parameters and pricing

function getSalesConfig() external view returns (SalesConfig memory config);

Returns

NameTypeDescription
configSalesConfigComplete sales configuration including timestamps and pricing The SalesConfig contains: - priorityStartTime: Priority round start timestamp (UTC+8) - priorityEndTime: Priority round end timestamp (UTC+8) - generalStartTime: General round start timestamp (UTC+8) - generalEndTime: General round end timestamp (UTC+8) - standardPrice: Price per NFT in wei

getCurrentRoundId

Get current round ID

function getCurrentRoundId() external view returns (uint64 roundId);

Returns

NameTypeDescription
roundIduint64Current active round ID (0 = no round started)

getCurrentRoundInfo

Get current round information including supply limit and minted count

function getCurrentRoundInfo() external view returns (RoundInfo memory info);

Returns

NameTypeDescription
infoRoundInfoRoundInfo struct with roundId, supplyLimit, mintedCount, remaining

getRoundConfig

Get configuration for a specific round

function getRoundConfig(uint64 roundId)
    external
    view
    returns (SalesConfig memory config, uint256 supplyLimit, uint256 mintedCount);

Parameters

NameTypeDescription
roundIduint64Round ID to query

Returns

NameTypeDescription
configSalesConfigSales configuration for the round
supplyLimituint256Maximum NFTs for the round
mintedCountuint256NFTs already minted in the round

getWhitelistInfoForRound

Get whitelist info for a user in a specific round

function getWhitelistInfoForRound(uint64 roundId, address account)
    external
    view
    returns (WhitelistInfo memory info);

Parameters

NameTypeDescription
roundIduint64Round ID to query
accountaddressUser address to query

Returns

NameTypeDescription
infoWhitelistInfoWhitelistInfo for the user in the specified round

totalSupply

Get total supply of minted PowerPass NFTs

View function for supply tracking and analytics

function totalSupply() external view returns (uint256 totalSupply);

Returns

NameTypeDescription
totalSupplyuint256Current total supply of minted NFTs

maxSupply

Get maximum supply limit for PowerPass NFTs

View function for supply cap information

function maxSupply() external view returns (uint256 maxSupply);

Returns

NameTypeDescription
maxSupplyuint256Maximum number of NFTs that can ever be minted

paymentToken

Get ERC20 payment token address

function paymentToken() external view returns (address token);

isDiscountCodeValid

Check if discount code hash is currently active

function isDiscountCodeValid(bytes32 codeHash) external view returns (bool isValid);

Parameters

NameTypeDescription
codeHashbytes32keccak256 hash of the off-chain discount code

getDiscountCodeUsageCount

Get the usage count for a specific discount code

Only counts usage when discount code is actually applied (excludes Nova discount cases)

function getDiscountCodeUsageCount(bytes32 codeHash) external view returns (uint256 usageCount);

Parameters

NameTypeDescription
codeHashbytes32keccak256 hash of the discount code

Returns

NameTypeDescription
usageCountuint256Number of NFTs minted using this discount code

setCurrentTokenId

Set the next token ID counter

Admin function to adjust token ID, typically to start from 1 instead of 0

function setCurrentTokenId(uint256 newTokenId) external;

Parameters

NameTypeDescription
newTokenIduint256The next token ID to be minted (must be >= current) Requirements: - Caller must have DEFAULT_ADMIN_ROLE - newTokenId must be >= current token ID counter

currentTokenId

Get the current token ID counter

function currentTokenId() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256The next token ID that will be minted

Structs

SalesConfig

Sales configuration for time-based rounds

Contains UTC+8 timestamps and pricing for both sales rounds

struct SalesConfig {
    uint128 priorityStartTime;
    uint128 priorityEndTime;
    uint128 generalStartTime;
    uint128 generalEndTime;
    uint128 standardPrice;
    uint128 discountCodeDiscount;
}

Properties

NameTypeDescription
priorityStartTimeuint128Priority round start timestamp (UTC+8)
priorityEndTimeuint128Priority round end timestamp (UTC+8)
generalStartTimeuint128General round start timestamp (UTC+8)
generalEndTimeuint128General round end timestamp (UTC+8)
standardPriceuint128Price per NFT in payment token smallest units
discountCodeDiscountuint128Discount amount per NFT when applying a valid code

WhitelistInfo

Whitelist allocation and minting information for a user

Gas-optimized struct packing for efficient storage

struct WhitelistInfo {
    uint64 priorityAllocation;
    uint64 generalAllocation;
    uint64 priorityMinted;
    uint64 generalMinted;
    uint64 novaDiscountAllocation;
    uint64 novaDiscountMinted;
}

Properties

NameTypeDescription
priorityAllocationuint64Total NFTs allocated for priority round
generalAllocationuint64Total NFTs allocated for general round
priorityMinteduint64Already minted in priority round
generalMinteduint64Already minted in general round
novaDiscountAllocationuint64Allocation eligible for Nova 80% pricing
novaDiscountMinteduint64NFTs already purchased with Nova discount

CustodialWhitelistInfo

struct CustodialWhitelistInfo {
    uint64 allocation;
    uint64 minted;
}

MintStatus

Current mint status for user queries

View-optimized struct for frontend integration

struct MintStatus {
    uint256 priorityRemaining;
    uint256 generalRemaining;
    uint256 novaDiscountRemaining;
    uint256 standardPrice;
    uint256 novaDiscountPrice;
    uint256 discountCodeDiscount;
    bool isPriorityActive;
    bool isGeneralActive;
    bool hasNovaDiscount;
}

Properties

NameTypeDescription
priorityRemaininguint256Remaining priority round allocation
generalRemaininguint256Remaining general round allocation (total cap)
novaDiscountRemaininguint256Remaining Nova discount allocation
standardPriceuint256Standard price based on active round
novaDiscountPriceuint256Discounted price for Nova addresses when discount allocation remains
discountCodeDiscountuint256Discount amount applied per NFT when redeeming a code
isPriorityActiveboolWhether priority round is currently active
isGeneralActiveboolWhether general round is currently active
hasNovaDiscountboolWhether user has remaining Nova discount allocation

RoundInfo

Round information for queries

struct RoundInfo {
    uint64 roundId;
    uint256 supplyLimit;
    uint256 mintedCount;
    uint256 remaining;
}

Properties

NameTypeDescription
roundIduint64Current round ID
supplyLimituint256Max NFTs for this round (0 = unlimited)
mintedCountuint256NFTs minted in this round
remaininguint256NFTs remaining in this round

IPowerPassStaking

Git Source

Title: IPowerPassStaking

Author: ShareX Team

Interface for PowerPassStaking contract with claim request/approval workflow

Supports staking PowerPass NFTs and claiming rewards through admin approval process

Functions

stake

Stake a single PowerPass NFT

function stake(uint256 tokenId) external;

Parameters

NameTypeDescription
tokenIduint256NFT token ID to stake

stakeBatch

Stake multiple PowerPass NFTs

function stakeBatch(uint256[] calldata tokenIds) external;

Parameters

NameTypeDescription
tokenIdsuint256[]Array of NFT token IDs to stake

unstake

Unstake a single PowerPass NFT

function unstake(uint256 tokenId) external;

Parameters

NameTypeDescription
tokenIduint256NFT token ID to unstake

unstakeBatch

Unstake multiple PowerPass NFTs

function unstakeBatch(uint256[] calldata tokenIds) external;

Parameters

NameTypeDescription
tokenIdsuint256[]Array of NFT token IDs to unstake

requestClaim

Request to claim rewards

function requestClaim(uint256 amount) external returns (uint256 requestId);

Parameters

NameTypeDescription
amountuint256Amount to claim (must be <= claimable amount)

Returns

NameTypeDescription
requestIduint256The ID of the created claim request

claimRewards

Claim rewards for an approved request

function claimRewards(uint256 requestId) external;

Parameters

NameTypeDescription
requestIduint256The request ID to claim

claimAllApprovedRewards

Claim all approved rewards

function claimAllApprovedRewards() external;

approveClaim

Approve a claim request

function approveClaim(uint256 requestId) external;

Parameters

NameTypeDescription
requestIduint256The request ID to approve

rejectClaim

Reject a claim request

function rejectClaim(uint256 requestId) external;

Parameters

NameTypeDescription
requestIduint256The request ID to reject

batchApproveClaims

Batch approve claim requests

function batchApproveClaims(uint256[] calldata requestIds) external;

Parameters

NameTypeDescription
requestIdsuint256[]Array of request IDs to approve

batchRejectClaims

Batch reject claim requests

function batchRejectClaims(uint256[] calldata requestIds) external;

Parameters

NameTypeDescription
requestIdsuint256[]Array of request IDs to reject

directClaim

Directly claim rewards without USDT transfer (for custodial wallets)

Skips request/approval flow, directly marks amount as claimed without token transfer

function directClaim(uint256 amount) external;

Parameters

NameTypeDescription
amountuint256Amount to claim

uploadOrders

Upload order information by NFT token ID

function uploadOrders(uint256[] calldata tokenIds, OrderInfo[][] calldata orders) external;

Parameters

NameTypeDescription
tokenIdsuint256[]Array of NFT token IDs
ordersOrderInfo[][]Array of order arrays per token

setRewardPercentage

Set reward percentage in basis points

function setRewardPercentage(uint256 rewardBps) external;

Parameters

NameTypeDescription
rewardBpsuint256New reward percentage (e.g. 2500 = 25%)

setPaymentToken

Set payment token for rewards

function setPaymentToken(address token) external;

Parameters

NameTypeDescription
tokenaddressNew payment token address

withdrawExcessRewards

Withdraw excess reward tokens

function withdrawExcessRewards(uint256 amount) external;

Parameters

NameTypeDescription
amountuint256Amount to withdraw

emergencyWithdrawNFT

Emergency withdraw NFT to specified address

function emergencyWithdrawNFT(uint256 tokenId, address to) external;

Parameters

NameTypeDescription
tokenIduint256NFT token ID to withdraw
toaddressRecipient address

getStakingInfo

Get staking information for an NFT

function getStakingInfo(uint256 tokenId) external view returns (StakingInfo memory);

Parameters

NameTypeDescription
tokenIduint256NFT token ID

getUserTotalRewards

Get user's total rewards across all their NFTs

function getUserTotalRewards(address user) external view returns (uint256);

Parameters

NameTypeDescription
useraddressUser address

getClaimableAmount

Get user's claimable amount (available to request)

function getClaimableAmount(address user) external view returns (uint256);

Parameters

NameTypeDescription
useraddressUser address

getUserRewardsSummary

Get comprehensive rewards summary for a user

function getUserRewardsSummary(address user) external view returns (UserRewardsSummary memory);

Parameters

NameTypeDescription
useraddressUser address

getUserClaimInfo

Get user's claim tracking info

function getUserClaimInfo(address user) external view returns (UserClaimInfo memory);

Parameters

NameTypeDescription
useraddressUser address

getUserActiveRequests

Get user's active claim requests (Pending + Approved)

function getUserActiveRequests(address user) external view returns (ClaimRequest[] memory);

Parameters

NameTypeDescription
useraddressUser address

getClaimRequest

Get a specific claim request

function getClaimRequest(uint256 requestId) external view returns (ClaimRequest memory);

Parameters

NameTypeDescription
requestIduint256Request ID

getPendingClaimRequests

Get all pending claim requests (for admin)

function getPendingClaimRequests() external view returns (ClaimRequest[] memory);

getPendingClaimRequestCount

Get pending claim request count

function getPendingClaimRequestCount() external view returns (uint256);

isStaked

Check if NFT is currently staked

function isStaked(uint256 tokenId) external view returns (bool);

Parameters

NameTypeDescription
tokenIduint256NFT token ID

getStaker

Get current staker or claimant of an NFT

function getStaker(uint256 tokenId) external view returns (address);

Parameters

NameTypeDescription
tokenIduint256NFT token ID

powerPassContract

Get PowerPass contract address

function powerPassContract() external view returns (address);

paymentToken

Get payment token address

function paymentToken() external view returns (address);

rewardPercentage

Get current reward percentage

function rewardPercentage() external view returns (uint256);

totalStaked

Get total staked NFT count

function totalStaked() external view returns (uint256);

getStakedTokenIds

Get user's staked token IDs

function getStakedTokenIds(address user) external view returns (uint256[] memory);

Parameters

NameTypeDescription
useraddressUser address

Structs

OrderInfo

Order information from powerbank device

amount can be negative for corrections (e.g., -50 to correct a 100 โ†’ 50 error)

struct OrderInfo {
    bytes32 orderId;
    bytes32 powernowDeviceId;
    uint64 startTimestamp;
    uint64 endTimestamp;
    int128 amount; // Signed to support corrections (negative values)
}

StakingInfo

NFT staking information

struct StakingInfo {
    address owner;
    uint64 stakedAt;
    uint128 totalRewards; // Cumulative rewards (never resets, historical record)
    uint128 rewardsAtStake; // Snapshot when current owner staked (for calculating earned)
    bool isStaked;
}

ClaimRequest

Claim request details

struct ClaimRequest {
    uint256 requestId;
    address user;
    uint128 amount;
    uint64 requestTime;
    ClaimRequestStatus status;
}

UserClaimInfo

User's claim tracking info

struct UserClaimInfo {
    uint128 totalEarned; // Total rewards earned (includes settled from unstaked NFTs)
    uint128 claimed; // Total claimed amount (historical)
    uint128 pendingApproval; // Current pending approval amount
    uint128 approved; // Current approved but not yet claimed amount
}

UserRewardsSummary

User's comprehensive rewards summary for UI display

struct UserRewardsSummary {
    uint256 totalRewards; // Sum of all NFT rewards
    uint256 claimable; // Available to request (totalRewards - claimed - pending - approved)
    uint256 pendingApproval; // Waiting for admin approval
    uint256 approved; // Approved, ready to claim
    uint256 claimed; // Already claimed
}

Enums

ClaimRequestStatus

Claim request status

Only Pending and Approved are stored on-chain; Rejected and Claimed are deleted

enum ClaimRequestStatus {
    Pending, // Awaiting admin approval
    Approved // Approved, waiting for user to claim
}

IShareXKeysSeries

Git Source

Inherits: IERC1155

Title: ShareX Keys Series Interface

Author: ShareX Team

ERC1155 interface for ShareX ecosystem NFT collection with whitelist-based minting The ShareX Keys Series consists of three token types representing different access levels:

  • ESSENTIA (ID: 0): Essential access keys for basic functionality
  • MAGNA (ID: 1): Enhanced access keys with additional privileges
  • NOVA (ID: 2): Premium access keys with full ecosystem access Key Features:
  • Whitelist-based minting with allocation limits per user
  • Batch operations for efficient gas usage across multiple accounts
  • Comprehensive mint status tracking for transparency
  • Role-based access control for administrative functions
  • Gas-optimized operations using RareSkills patterns Security Considerations:
  • All administrative functions require DEFAULT_ADMIN_ROLE
  • Whitelist allocations are immutable once set (must be reset to change)
  • Mint amounts are validated against remaining allocations
  • Zero address checks prevent accidental burns Usage Example:
// Set whitelist allocation for a user
keysSeries.setWhitelists(user, 5, 3, 1); // 5 ESSENTIA, 3 MAGNA, 1 NOVA
// User mints their allocation
keysSeries.mint(0, 2); // Mint 2 ESSENTIA tokens
keysSeries.mintAll();   // Mint all remaining tokens
// Check status
(MintStatus memory essentia,,) = keysSeries.getMintStatus(user);
// essentia.remaining == 3

Functions

setWhitelists

Set whitelist allocation for a single account across all token types

Only callable by DEFAULT_ADMIN_ROLE. Overwrites existing allocations.

function setWhitelists(
    address account,
    uint256 essentiaAmount,
    uint256 magnaAmount,
    uint256 novaAmount
) external;

Parameters

NameTypeDescription
accountaddressThe address to set allocations for
essentiaAmountuint256Number of ESSENTIA tokens to allocate
magnaAmountuint256Number of MAGNA tokens to allocate
novaAmountuint256Number of NOVA tokens to allocate Requirements: - Caller must have DEFAULT_ADMIN_ROLE - Account cannot be zero address Emits: ShareXKeysWhitelistsSet event

batchSetWhitelists

Set whitelist allocations for multiple accounts in a single transaction

Batch operation for gas efficiency. Only callable by DEFAULT_ADMIN_ROLE.

function batchSetWhitelists(
    address[] calldata accounts,
    uint256[] calldata essentiaAmounts,
    uint256[] calldata magnaAmounts,
    uint256[] calldata novaAmounts
) external;

Parameters

NameTypeDescription
accountsaddress[]Array of addresses to set allocations for
essentiaAmountsuint256[]Array of ESSENTIA allocations corresponding to accounts
magnaAmountsuint256[]Array of MAGNA allocations corresponding to accounts
novaAmountsuint256[]Array of NOVA allocations corresponding to accounts Requirements: - Caller must have DEFAULT_ADMIN_ROLE - All arrays must have equal length - No account can be zero address - Gas-optimized with unchecked arithmetic for large batches Emits: ShareXKeysBatchWhitelistsSet event

mint

Mint a specific amount of a specific token type

Gas-optimized minting with allocation validation

function mint(uint256 tokenId, uint256 amount) external;

Parameters

NameTypeDescription
tokenIduint256The token type to mint (0=ESSENTIA, 1=MAGNA, 2=NOVA)
amountuint256Number of tokens to mint Requirements: - tokenId must be valid (0, 1, or 2) - amount must be greater than 0 - Caller must have sufficient whitelist allocation - amount must not exceed remaining allocation Emits: ShareXKeysMinted event

mintAll

Mint all remaining tokens across all types for the caller

Batch mint operation that mints the complete remaining allocation Gas-optimized batch minting that:

  • Automatically detects which tokens have remaining allocation
  • Mints only tokens with remaining > 0
  • Uses efficient batch operations for multiple token types Requirements:
  • Caller must have at least one token with remaining allocation > 0 Emits: ShareXKeysBatchMinted event
function mintAll() external;

getMintStatus

Get detailed minting status for an account across all token types

View function that returns comprehensive allocation and minting statistics

function getMintStatus(address account)
    external
    view
    returns (MintStatus memory essentia, MintStatus memory magna, MintStatus memory nova);

Parameters

NameTypeDescription
accountaddressThe address to query status for

Returns

NameTypeDescription
essentiaMintStatusMint status for ESSENTIA tokens (ID: 0)
magnaMintStatusMint status for MAGNA tokens (ID: 1)
novaMintStatusMint status for NOVA tokens (ID: 2) Each MintStatus contains: - whitelisted: Total allocation for this token type - minted: Already minted amount for this token type - remaining: Available to mint (whitelisted - minted)

getWhitelisted

Get whitelist allocations for an account across all token types

View function for checking total allocations without minting statistics

function getWhitelisted(address account)
    external
    view
    returns (uint256 essentiaAmount, uint256 magnaAmount, uint256 novaAmount);

Parameters

NameTypeDescription
accountaddressThe address to query allocations for

Returns

NameTypeDescription
essentiaAmountuint256Total ESSENTIA tokens allocated
magnaAmountuint256Total MAGNA tokens allocated
novaAmountuint256Total NOVA tokens allocated Note: This returns total allocations, not remaining amounts. Use getMintStatus() for remaining allocation information.

setTokenURI

Set the URI for a specific token type

Only callable by DEFAULT_ADMIN_ROLE. Updates token metadata URI.

function setTokenURI(uint256 tokenId, string calldata tokenURI) external;

Parameters

NameTypeDescription
tokenIduint256The token type to set URI for (0=ESSENTIA, 1=MAGNA, 2=NOVA)
tokenURIstringThe new URI string for the token Requirements: - Caller must have DEFAULT_ADMIN_ROLE - tokenId must be valid (0, 1, or 2) Emits: URI event from ERC1155 standard

Structs

MintStatus

Mint status information for a specific token type

Contains allocation and minting statistics for transparency

struct MintStatus {
    uint256 whitelisted;
    uint256 minted;
    uint256 remaining;
}

Properties

NameTypeDescription
whitelisteduint256Total tokens allocated to the account
minteduint256Total tokens already minted by the account
remaininguint256Tokens remaining to be minted (whitelisted - minted)

IShareXKeysStaking

Git Source

Title: ShareX Keys Staking Interface

Author: ShareX Team

Staking interface for ShareX Keys Series ERC1155 NFTs with reward distribution The ShareX Keys Staking system allows users to stake their ShareX Keys Series NFTs to earn rewards based on staking duration and amount. The system supports three token types:

  • ESSENTIA (ID: 0): Essential access keys for basic functionality
  • MAGNA (ID: 1): Enhanced access keys with additional privileges
  • NOVA (ID: 2): Premium access keys with full ecosystem access Key Features:
  • Individual and batch staking/unstaking operations for gas efficiency
  • Rewards accumulation based on staked amounts and time
  • Emergency functions for admin control and user protection
  • Upgradeable proxy pattern for future enhancements
  • Gas-optimized operations using RareSkills patterns Security Considerations:
  • All administrative functions require DEFAULT_ADMIN_ROLE
  • Reentrancy protection on all state-changing functions
  • Proper reward calculations to prevent over/under-distribution
  • Emergency pause functionality for critical situations
  • Reward debt mechanism prevents reward manipulation Usage Example:
// Stake individual tokens
stakingContract.stake(0, 5);        // Stake 5 ESSENTIA tokens
stakingContract.stake(1, 2);        // Stake 2 MAGNA tokens
// Batch operations for gas efficiency
stakingContract.stakeAll();         // Stake all available tokens
stakingContract.unstakeAll();       // Unstake all staked tokens
// Reward management
stakingContract.claimRewards();     // Claim accumulated rewards
// View staking information
StakingInfo memory info = stakingContract.getStakingInfo(user, 0);
// info.stakedAmount, info.pendingRewards, info.lastStakedTime

Functions

stake

Stake a specific amount of tokens for a specific token type

Gas-optimized staking with comprehensive validation and reward updates

function stake(uint256 tokenId, uint256 amount) external;

Parameters

NameTypeDescription
tokenIduint256The token type to stake (0=ESSENTIA, 1=MAGNA, 2=NOVA)
amountuint256Number of tokens to stake Requirements: - tokenId must be valid (0, 1, or 2) - amount must be greater than 0 - User must own sufficient tokens in ShareX Keys Series contract - Contract must not be paused - Updates rewards before changing stake amounts Emits: ShareXStakingStaked event

unstake

Unstake a specific amount of tokens for a specific token type

Gas-optimized unstaking with reward calculation and token transfer

function unstake(uint256 tokenId, uint256 amount) external;

Parameters

NameTypeDescription
tokenIduint256The token type to unstake (0=ESSENTIA, 1=MAGNA, 2=NOVA)
amountuint256Number of tokens to unstake Requirements: - tokenId must be valid (0, 1, or 2) - amount must be greater than 0 - User must have sufficient staked tokens of the specified type - Contract must not be paused - Updates rewards before changing stake amounts Emits: ShareXStakingUnstaked event

stakeAll

Stake all available tokens across all types for the caller

Batch staking operation for gas efficiency and user convenience Gas-optimized batch staking that:

  • Automatically detects which tokens the user owns
  • Stakes only tokens with balance > 0
  • Uses efficient batch operations for multiple token types
  • Achieves 20-30% gas savings compared to individual calls Requirements:
  • User must own at least one token across all types
  • Contract must not be paused Emits: ShareXStakingBatchStaked event
function stakeAll() external;

unstakeAll

Unstake all staked tokens across all types for the caller

Batch unstaking operation for gas efficiency and user convenience Gas-optimized batch unstaking that:

  • Automatically detects which tokens the user has staked
  • Unstakes only tokens with staked amount > 0
  • Uses efficient batch operations for multiple token types
  • Updates rewards for all affected pools Requirements:
  • User must have at least one staked token across all types
  • Contract must not be paused Emits: ShareXStakingBatchUnstaked event
function unstakeAll() external;

claimRewards

Claim all accumulated rewards for the caller

Calculates and distributes pending rewards across all staked token types Reward calculation includes:

  • Time-based rewards for all staked tokens
  • Accurate reward debt management
  • Gas-optimized calculation across multiple pools Requirements:
  • Contract must not be paused
  • User must have pending rewards > 0 Emits: ShareXStakingRewardsClaimed event
function claimRewards() external;

getStakingInfo

Get comprehensive staking information for a user and token type

View function providing complete staking status including pending rewards

function getStakingInfo(address account, uint256 tokenId)
    external
    view
    returns (StakingInfo memory info);

Parameters

NameTypeDescription
accountaddressThe address to query staking information for
tokenIduint256The token type to query (0=ESSENTIA, 1=MAGNA, 2=NOVA)

Returns

NameTypeDescription
infoStakingInfoComplete staking information including current stake and pending rewards The StakingInfo contains: - stakedAmount: Current tokens staked by the user - rewardDebt: Internal value for reward calculation precision - lastStakedTime: Timestamp of user's last staking action - pendingRewards: Rewards currently available for claiming

getPoolInfo

Get pool configuration and statistics for a specific token type

View function for pool reward parameters and current state

function getPoolInfo(uint256 tokenId) external view returns (PoolInfo memory info);

Parameters

NameTypeDescription
tokenIduint256The token type to query (0=ESSENTIA, 1=MAGNA, 2=NOVA)

Returns

NameTypeDescription
infoPoolInfoComplete pool information including reward rates and total staked The PoolInfo contains: - rewardPerBlock: Rewards distributed per block for this token type - accRewardPerShare: Accumulated rewards per share for precision - lastRewardBlock: Block when rewards were last calculated - totalStaked: Total tokens currently staked in this pool

getTotalPendingRewards

Get total pending rewards across all token types for a user

Aggregated view of all claimable rewards for gas-efficient querying

function getTotalPendingRewards(address account) external view returns (uint256 totalRewards);

Parameters

NameTypeDescription
accountaddressThe address to calculate total pending rewards for

Returns

NameTypeDescription
totalRewardsuint256Sum of pending rewards from all staked token types This is a convenience function that: - Calculates pending rewards from all active stakes - Provides single-call access to total claimable amount - Useful for UI/UX displaying total reward balance

updatePoolRewards

Update reward parameters for a specific token type pool

Admin function to configure reward distribution rates

function updatePoolRewards(uint256 tokenId, uint256 rewardPerBlock) external;

Parameters

NameTypeDescription
tokenIduint256The token type to configure (0=ESSENTIA, 1=MAGNA, 2=NOVA)
rewardPerBlockuint256New reward rate per block for this token type Requirements: - Caller must have DEFAULT_ADMIN_ROLE - tokenId must be valid (0, 1, or 2) - Updates pool state before changing parameters Emits: ShareXStakingPoolUpdated event

emergencyWithdraw

Emergency withdrawal function for users to recover staked tokens

Allows token recovery without reward calculation in emergency situations

function emergencyWithdraw(uint256 tokenId) external;

Parameters

NameTypeDescription
tokenIduint256The token type to emergency withdraw (0=ESSENTIA, 1=MAGNA, 2=NOVA) Emergency withdrawal: - Bypasses normal reward calculations for faster execution - Available even when contract is paused - Users forfeit pending rewards for immediate token recovery - Intended for emergency situations only Requirements: - User must have staked tokens of the specified type - Can be used even when contract is paused Emits: ShareXStakingEmergencyWithdrawal event

burnAllTokens

Burn all tokens (staked and owned) for a specific address

Admin function to burn all tokens belonging to a user

function burnAllTokens(address account) external;

Parameters

NameTypeDescription
accountaddressThe address whose tokens should be burned This function: - Burns all staked tokens from the staking contract - Burns all owned tokens from the user's wallet - Updates pool state and user stakes accordingly - Forfeits any pending rewards for the burned tokens Requirements: - Caller must have DEFAULT_ADMIN_ROLE - Account must have tokens to burn (either staked or owned) Emits: ShareXStakingTokensBurned event

shareXKeys

Get the ShareX Keys Series contract address used for staking

View function to verify contract integration

function shareXKeys() external view returns (address shareXKeys);

Returns

NameTypeDescription
shareXKeysaddressAddress of the ShareX Keys Series ERC1155 contract

Structs

StakingInfo

Staking information for a user and specific token type

Contains all relevant staking data for reward calculations and user queries

struct StakingInfo {
    uint256 stakedAmount;
    uint256 rewardDebt;
    uint256 lastStakedTime;
    uint256 pendingRewards;
}

Properties

NameTypeDescription
stakedAmountuint256Current amount of tokens staked by the user
rewardDebtuint256Accumulated reward debt used for reward calculation precision
lastStakedTimeuint256Timestamp of the user's last staking action
pendingRewardsuint256Currently pending rewards available for claim

PoolInfo

Pool configuration for reward distribution per token type

Contains reward parameters and accumulator state for each staking pool

struct PoolInfo {
    uint128 rewardPerBlock;
    uint128 accRewardPerShare;
    uint64 lastRewardBlock;
    uint128 totalStaked;
}

Properties

NameTypeDescription
rewardPerBlockuint128Rewards distributed per block for this token type
accRewardPerShareuint128Accumulated rewards per share (scaled by precision factor)
lastRewardBlockuint64Block number when rewards were last calculated
totalStakeduint128Total amount of tokens currently staked in this pool

IShareXMomentumBadge

Git Source

Inherits: IERC721

Functions

mint

function mint(address to) external;

batchMint

function batchMint(address[] calldata recipients) external;

burn

function burn(uint256 tokenId) external;

batchBurn

function batchBurn(uint256[] calldata tokenIds) external;

totalSupply

function totalSupply() external view returns (uint256);

tokenURI

function tokenURI(uint256 tokenId) external view returns (string memory);

IShareXWallet

Git Source

Functions

receive

receive() external payable;

fallback

fallback() external payable;

aggregate

function aggregate(Call[] calldata calls)
    external
    payable
    returns (uint256 blockNumber, bytes[] memory returnData);

withdraw

function withdraw(address payable to, uint256 amount) external;

withdrawToken

function withdrawToken(address token, address to, uint256 amount) external;

batchTransfer

function batchTransfer(
    address[] calldata tokens,
    address[] calldata recipients,
    uint256[] calldata amounts
) external;

mintPowerPass

function mintPowerPass(address powerPassContract, address to, string calldata tokenURI)
    external
    returns (uint256 tokenId);

transferPowerPass

function transferPowerPass(address powerPassContract, address from, address to, uint256 tokenId)
    external;

burnPowerPass

function burnPowerPass(address powerPassContract, uint256 tokenId) external;

approvePowerPass

function approvePowerPass(address powerPassContract, address to, uint256 tokenId) external;

setApprovalForAllPowerPass

function setApprovalForAllPowerPass(address powerPassContract, address operator, bool approved)
    external;

getPowerPassBalance

function getPowerPassBalance(address powerPassContract) external view returns (uint256 balance);

getPowerPassApproved

function getPowerPassApproved(address powerPassContract, uint256 tokenId)
    external
    view
    returns (address approved);

stakePowerPass

function stakePowerPass(address stakingContract, uint256 tokenId) external;

stakePowerPassBatch

function stakePowerPassBatch(address stakingContract, uint256[] calldata tokenIds) external;

unstakePowerPass

function unstakePowerPass(address stakingContract, uint256 tokenId) external;

unstakePowerPassBatch

function unstakePowerPassBatch(address stakingContract, uint256[] calldata tokenIds) external;

requestPowerPassClaim

function requestPowerPassClaim(address stakingContract, uint256 amount)
    external
    returns (uint256 requestId);

claimPowerPassReward

function claimPowerPassReward(address stakingContract, uint256 requestId) external;

claimAllApprovedPowerPassRewards

function claimAllApprovedPowerPassRewards(address stakingContract) external;

Structs

Call

struct Call {
    address target;
    bytes callData;
}

IShareXWalletManager

Git Source

Functions

initialize

function initialize(address admin) external;

fund

function fund() external payable;

createWallet

function createWallet(uint256 userId) external returns (uint256 walletId, address walletAddr);

deposit

function deposit(uint256 userId, uint256 walletId, address token, uint256 amount)
    external
    payable;

withdraw

function withdraw(
    uint256 userId,
    uint256 walletId,
    address payable to,
    address token,
    uint256 amount
) external;

transfer

function transfer(
    uint256 fromUserId,
    uint256 fromWalletId,
    uint256 toUserId,
    uint256 toWalletId,
    address token,
    uint256 amount
) external;

batchTransfer

function batchTransfer(
    uint256 userId,
    uint256 walletId,
    address[] calldata tokens,
    address[] calldata recipients,
    uint256[] calldata amounts
) external;

mintPowerPass

function mintPowerPass(
    uint256 userId,
    uint256 walletId,
    address powerPassContract,
    address to,
    string calldata tokenURI
) external returns (uint256 tokenId);

transferPowerPass

function transferPowerPass(
    uint256 userId,
    uint256 walletId,
    address powerPassContract,
    address from,
    address to,
    uint256 tokenId
) external;

burnPowerPass

function burnPowerPass(
    uint256 userId,
    uint256 walletId,
    address powerPassContract,
    uint256 tokenId
) external;

approvePowerPass

function approvePowerPass(
    uint256 userId,
    uint256 walletId,
    address powerPassContract,
    address to,
    uint256 tokenId
) external;

setApprovalForAllPowerPass

function setApprovalForAllPowerPass(
    uint256 userId,
    uint256 walletId,
    address powerPassContract,
    address operator,
    bool approved
) external;

batchApprovePowerPass

function batchApprovePowerPass(
    uint256 userId,
    uint256 walletId,
    address powerPassContract,
    uint256[] calldata tokenIds,
    address[] calldata operators
) external;

approveAndTransferPowerPass

function approveAndTransferPowerPass(
    uint256 fromUserId,
    uint256 fromWalletId,
    address powerPassContract,
    address to,
    uint256 tokenId
) external;

batchTransferPowerPass

function batchTransferPowerPass(
    uint256 userId,
    uint256 walletId,
    address powerPassContract,
    address[] calldata from,
    address[] calldata to,
    uint256[] calldata tokenIds
) external;

getPowerPassBalance

function getPowerPassBalance(uint256 userId, uint256 walletId, address powerPassContract)
    external
    view
    returns (uint256 balance);

getPowerPassApproved

function getPowerPassApproved(
    uint256 userId,
    uint256 walletId,
    address powerPassContract,
    uint256 tokenId
) external view returns (address approved);

isApprovedForAllPowerPass

function isApprovedForAllPowerPass(
    uint256 userId,
    uint256 walletId,
    address powerPassContract,
    address operator
) external view returns (bool approved);

getNativeTokenBalance

function getNativeTokenBalance(uint256 userId, uint256 walletId)
    external
    view
    returns (uint256 nativeBalance);

getTokenBalance

function getTokenBalance(uint256 userId, uint256 walletId, address token)
    external
    view
    returns (uint256 tokenBalance);

getWalletAddr

function getWalletAddr(uint256 userId, uint256 walletId) external view returns (address);

getWalletIndex

function getWalletIndex() external view returns (uint256);

stakePowerPass

function stakePowerPass(
    uint256 userId,
    uint256 walletId,
    address stakingContract,
    uint256 tokenId
) external;

stakePowerPassBatch

function stakePowerPassBatch(
    uint256 userId,
    uint256 walletId,
    address stakingContract,
    uint256[] calldata tokenIds
) external;

unstakePowerPass

function unstakePowerPass(
    uint256 userId,
    uint256 walletId,
    address stakingContract,
    uint256 tokenId
) external;

unstakePowerPassBatch

function unstakePowerPassBatch(
    uint256 userId,
    uint256 walletId,
    address stakingContract,
    uint256[] calldata tokenIds
) external;

requestPowerPassClaim

function requestPowerPassClaim(
    uint256 userId,
    uint256 walletId,
    address stakingContract,
    uint256 amount
) external returns (uint256 requestId);

claimPowerPassReward

function claimPowerPassReward(
    uint256 userId,
    uint256 walletId,
    address stakingContract,
    uint256 requestId
) external;

claimAllApprovedPowerPassRewards

function claimAllApprovedPowerPassRewards(
    uint256 userId,
    uint256 walletId,
    address stakingContract
) external;

directClaimPowerPassReward

function directClaimPowerPassReward(
    uint256 userId,
    uint256 walletId,
    address stakingContract,
    uint256 amount
) external;

Contents

Constants

Git Source

OPERATOR_ROLE

Operator role - can perform standard operations

bytes32 constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE")

MAX_BATCH_SIZE

Maximum number of transaction details allowed in a single batch

uint256 constant MAX_BATCH_SIZE = 100

MAX_PARTNER_NAME_LENGTH

Maximum length for partner name in bytes

uint256 constant MAX_PARTNER_NAME_LENGTH = 100

MAX_PARTNER_DESCRIPTION_LENGTH

Maximum length for partner description in bytes

uint256 constant MAX_PARTNER_DESCRIPTION_LENGTH = 500

Version

Git Source

Version information structure

struct Version {
uint8 major;
uint8 minor;
uint8 patch;
}

CountryInfo

Git Source

Country information structure

struct CountryInfo {
bytes2 iso2; // ISO2 country code
uint32 timestamp; // Registration timestamp
}

PartnerInfo

Git Source

Partner information structure

struct PartnerInfo {
uint64 id; // Internal ID
uint32 timestamp; // Registration timestamp
bytes2 iso2; // ISO2 country code
string partnerCode; // Partner code
string verification; // Verification number issued by ShareX
string partnerName; // Partner name
string description; // Service description
string businessType; // Business type
}

MerchantInfo

Git Source

Merchant information structure

struct MerchantInfo {
uint64 id; // Internal ID
uint32 timestamp; // Registration timestamp
bytes2 iso2; // Country code
string merchantName; // Merchant name
string merchantId; // Merchant ID
string locationId; // City code
string location; // Location
string merchantType; // Scene type
string verification; // Verification number
string description; // Description
}

DeviceInfo

Git Source

Device information structure

struct DeviceInfo {
uint64 id; // Internal ID
uint32 timestamp; // Registration timestamp
string deviceId; // Device ID
string deviceType; // Device type
string partnerCode; // Partner code
string merchantId; // Merchant ID
}

TransactionBatch

Git Source

Transaction batch structure

struct TransactionBatch {
uint64 id; // Internal ID
uint32 orderCount; // Order count
uint32 batchTimestamp; // Batch timestamp
string deviceId; // Device ID
string totalAmount; // Total transaction amount
string dateComparable; // Date in YYYYMMDD format
}

StatsInfo

Git Source

Statistics information structure

struct StatsInfo {
uint64 partnersCount; // Total number of partners
uint64 merchantsCount; // Total number of merchants
uint64 devicesCount; // Total number of devices
uint64 transactionBatchesCount; // Total number of transaction batches
uint64 countriesCount; // Total number of countries
}

DetailedStatsInfo

Git Source

Enhanced statistics information structure with descriptive labels

struct DetailedStatsInfo {
StatsInfo basicStats; // Original numeric statistics
string[] metricNames; // Descriptive names for each metric
string[] metricDescriptions; // Detailed descriptions of each metric
uint256 lastUpdated; // Timestamp when stats were retrieved
Version contractVersion; // Contract version information
}

PartnerParams

Git Source

Parameters structure for registering a partner

struct PartnerParams {
string partnerCode;
string partnerName;
bytes2 iso2;
string verification;
string description;
string businessType;
}

MerchantParams

Git Source

Parameters structure for registering a merchant

struct MerchantParams {
string merchantName;
string merchantId;
string description;
bytes2 iso2;
string locationId;
string location;
string merchantType;
string verification;
}

DeviceParams

Git Source

Parameters structure for registering a device

struct DeviceParams {
string deviceId;
string deviceType;
string partnerCode;
string merchantId;
}

UploadBatchParams

Git Source

Parameters structure for uploading a transaction batch

struct UploadBatchParams {
string deviceId;
string dateComparable;
uint32 orderCount;
string totalAmount;
bytes transactionData;
}

PackedCounters

Git Source

Packed counters for efficiency

struct PackedCounters {
uint64 partnerCounter;
uint64 merchantCounter;
uint64 deviceCounter;
uint64 batchCounter;
uint64 countriesCounter;
}

PowerPassSalesConfig

Git Source

Deprecated: Use PowerPassRoundConfig for multi-round support

PowerPass sales configuration structure (gas-optimized packing)

struct PowerPassSalesConfig {
uint128 priorityStartTime; // Priority round start timestamp (UTC+8)
uint128 priorityEndTime; // Priority round end timestamp (UTC+8)
uint128 generalStartTime; // General round start timestamp (UTC+8)
uint128 generalEndTime; // General round end timestamp (UTC+8)
uint128 standardPrice; // Price per NFT in payment token smallest unit
uint128 discountCodeDiscount; // Global discount applied when redeeming a code
}

PowerPassRoundConfig

Git Source

Each round contains priority + general windows with independent whitelist and supply limit

PowerPass round configuration structure with supply limit (gas-optimized packing)

struct PowerPassRoundConfig {
uint128 priorityStartTime; // Priority window start timestamp
uint128 priorityEndTime; // Priority window end timestamp
uint128 generalStartTime; // General window start timestamp
uint128 generalEndTime; // General window end timestamp
uint128 standardPrice; // Price per NFT in payment token smallest unit
uint128 discountCodeDiscount; // Discount applied when redeeming a code
uint128 roundSupplyLimit; // Max NFTs mintable in this round (0 = unlimited, still capped by
// MAX_SUPPLY)
uint128 roundMintedCount; // NFTs minted in this round via Web3 mint
}

PowerPassWhitelistInfo

Git Source

PowerPass whitelist allocation structure (gas-optimized packing)

struct PowerPassWhitelistInfo {
uint64 priorityAllocation; // Priority round allocation
uint64 generalAllocation; // General round allocation (total cap)
uint64 priorityMinted; // Already minted in priority round
uint64 generalMinted; // Already minted in general round
uint64 novaDiscountAllocation; // Allocation eligible for Nova 80% pricing
uint64 novaDiscountMinted; // NFTs already purchased with Nova discount
}

PowerPassMintStatus

Git Source

PowerPass mint status for view functions

struct PowerPassMintStatus {
uint256 priorityRemaining; // Remaining priority allocation
uint256 generalRemaining; // Remaining general allocation (total cap)
uint256 novaDiscountRemaining; // Remaining Nova discount allocation
uint256 standardPrice; // Standard price per NFT
uint256 novaDiscountPrice; // Discounted price per NFT for Nova holders
uint256 discountCodeDiscount; // Discount amount when using a valid code
bool isPriorityActive; // Whether priority round is active
bool isGeneralActive; // Whether general round is active
bool hasNovaDiscount; // Whether account is Nova discount eligible
}

PowerPassCustodialWhitelistInfo

Git Source

Custodial whitelist allocation structure for ShareX wallet minting

struct PowerPassCustodialWhitelistInfo {
uint64 allocation; // Total custodial allocation for an address
uint64 minted; // Number of custodial mints already consumed
}

EntityAlreadyExists

Git Source

Entity already exists

error EntityAlreadyExists(string entityType, bytes32 entityId);

EntityNotFound

Git Source

Entity not found

error EntityNotFound(string entityType, bytes32 entityId);

InvalidAdminAddress

Git Source

Invalid admin address

error InvalidAdminAddress();

EmptyTransactionData

Git Source

Empty transaction data

error EmptyTransactionData();

TooManyTransactions

Git Source

Too many transactions

error TooManyTransactions();

OrderCountMismatch

Git Source

Order count mismatch

error OrderCountMismatch();

InvalidStringLength

Git Source

Invalid string length

error InvalidStringLength(string field, uint256 maxLength);

PowerPassMaxSupplyExceeded

Git Source

PowerPass maximum supply exceeded

error PowerPassMaxSupplyExceeded();

PowerPassTokenNotFound

Git Source

PowerPass token not found

error PowerPassTokenNotFound();

PowerPassNotOwnerOrApproved

Git Source

Not owner or approved for PowerPass token

error PowerPassNotOwnerOrApproved();

PowerPassNoActiveSalesRound

Git Source

PowerPass whitelist and sales round errors

error PowerPassNoActiveSalesRound();

PowerPassInvalidSalesConfig

Git Source

error PowerPassInvalidSalesConfig();

PowerPassInsufficientPayment

Git Source

error PowerPassInsufficientPayment(uint256 required, uint256 provided);

PowerPassExceedsAllocation

Git Source

error PowerPassExceedsAllocation(address account, uint256 requested, uint256 remaining);

PowerPassNoWhitelistAllocation

Git Source

error PowerPassNoWhitelistAllocation(address account);

PowerPassInvalidTimestamp

Git Source

error PowerPassInvalidTimestamp(uint256 timestamp);

PowerPassSnapshotNotTaken

Git Source

error PowerPassSnapshotNotTaken();

PowerPassZeroAddress

Git Source

error PowerPassZeroAddress();

PowerPassInvalidArrayLength

Git Source

error PowerPassInvalidArrayLength();

PowerPassInvalidAmount

Git Source

error PowerPassInvalidAmount();

PowerPassStakingContractNotSet

Git Source

error PowerPassStakingContractNotSet();

PowerPassWithdrawFailed

Git Source

error PowerPassWithdrawFailed();

PowerPassPaymentTokenNotSet

Git Source

error PowerPassPaymentTokenNotSet();

PowerPassNativePaymentNotSupported

Git Source

error PowerPassNativePaymentNotSupported();

PowerPassInvalidDiscountAmount

Git Source

error PowerPassInvalidDiscountAmount();

PowerPassDiscountCodeInvalid

Git Source

error PowerPassDiscountCodeInvalid();

PowerPassDiscountCodeAlreadyExists

Git Source

error PowerPassDiscountCodeAlreadyExists(bytes32 codeHash);

PowerPassCustodialNotWhitelisted

Git Source

error PowerPassCustodialNotWhitelisted(address account);

PowerPassCustodialExceedsAllocation

Git Source

error PowerPassCustodialExceedsAllocation(address account, uint256 requested, uint256 remaining);

PowerPassNoActiveRound

Git Source

error PowerPassNoActiveRound();

PowerPassRoundLimitExceeded

Git Source

error PowerPassRoundLimitExceeded(uint256 requested, uint256 available);

ShareXWalletInvalidUserId

Git Source

ShareX Wallet errors

error ShareXWalletInvalidUserId(uint256 userId);

ShareXWalletInvalidWalletId

Git Source

error ShareXWalletInvalidWalletId(uint256 walletId);

ShareXWalletInvalidArrayLength

Git Source

error ShareXWalletInvalidArrayLength();

ShareXWalletCallFailed

Git Source

error ShareXWalletCallFailed();

ShareXWalletWithdrawFailed

Git Source

error ShareXWalletWithdrawFailed();

ShareXWalletTransferFailed

Git Source

error ShareXWalletTransferFailed();

ShareXWalletMintFailed

Git Source

error ShareXWalletMintFailed();

ShareXWalletBurnFailed

Git Source

error ShareXWalletBurnFailed();

ShareXWalletNoRoleToCreateWallet

Git Source

error ShareXWalletNoRoleToCreateWallet(address account);

ShareXWalletWalletNotFound

Git Source

error ShareXWalletWalletNotFound();

ShareXWalletInvalidAdminAddress

Git Source

error ShareXWalletInvalidAdminAddress();

ShareXWalletPowerPassApprovalFailed

Git Source

error ShareXWalletPowerPassApprovalFailed(address tokenContract, uint256 tokenId);

ShareXWalletPowerPassNotOwned

Git Source

error ShareXWalletPowerPassNotOwned(address owner, uint256 tokenId);

ShareXWalletPowerPassBatchOperationFailed

Git Source

error ShareXWalletPowerPassBatchOperationFailed(uint256 index, string reason);

ShareXWalletStakeFailed

Git Source

error ShareXWalletStakeFailed();

ShareXWalletUnstakeFailed

Git Source

error ShareXWalletUnstakeFailed();

ShareXWalletClaimRewardsFailed

Git Source

error ShareXWalletClaimRewardsFailed();

ShareXKeysInvalidTokenId

Git Source

ShareX Keys Series errors

error ShareXKeysInvalidTokenId(uint256 tokenId);

ShareXKeysNoWhitelistAllocation

Git Source

error ShareXKeysNoWhitelistAllocation(address account, uint256 tokenId);

ShareXKeysInvalidArrayLength

Git Source

error ShareXKeysInvalidArrayLength();

ShareXKeysZeroAddress

Git Source

error ShareXKeysZeroAddress();

ShareXKeysInvalidAmount

Git Source

error ShareXKeysInvalidAmount();

ShareXKeysExceedsAllocation

Git Source

error ShareXKeysExceedsAllocation(
address account, uint256 tokenId, uint256 requested, uint256 remaining
);

ShareXKeysNoTokensToMint

Git Source

error ShareXKeysNoTokensToMint(address account);

ShareXStakingZeroAddress

Git Source

ShareX Keys Staking errors

error ShareXStakingZeroAddress();

ShareXStakingInvalidTokenId

Git Source

error ShareXStakingInvalidTokenId(uint256 tokenId);

ShareXStakingInvalidAmount

Git Source

error ShareXStakingInvalidAmount();

ShareXStakingInsufficientBalance

Git Source

error ShareXStakingInsufficientBalance(
address account, uint256 tokenId, uint256 requested, uint256 available
);

ShareXStakingInsufficientStake

Git Source

error ShareXStakingInsufficientStake(
address account, uint256 tokenId, uint256 requested, uint256 staked
);

ShareXStakingNoTokensToStake

Git Source

error ShareXStakingNoTokensToStake(address account);

ShareXStakingNoTokensToUnstake

Git Source

error ShareXStakingNoTokensToUnstake(address account);

ShareXStakingInvalidShareXKeysContract

Git Source

error ShareXStakingInvalidShareXKeysContract();

ShareXStakingInvalidArrayLength

Git Source

error ShareXStakingInvalidArrayLength();

ShareXStakingRewardCalculationFailed

Git Source

error ShareXStakingRewardCalculationFailed();

ShareXStakingNoTokensToBurn

Git Source

error ShareXStakingNoTokensToBurn(address account);

ShareXKeysStakingZeroAddress

Git Source

error ShareXKeysStakingZeroAddress();

ShareXKeysStakingInvalidTokenContract

Git Source

error ShareXKeysStakingInvalidTokenContract();

ShareXKeysStakingInvalidAmount

Git Source

error ShareXKeysStakingInvalidAmount();

ShareXKeysStakingNoNFTToStake

Git Source

error ShareXKeysStakingNoNFTToStake(address owner, uint256 tokenId);

ShareXKeysStakingNFTNotStaked

Git Source

error ShareXKeysStakingNFTNotStaked(uint256 tokenId);

ShareXKeysStakingUnauthorizedCaller

Git Source

error ShareXKeysStakingUnauthorizedCaller(address caller, uint256 tokenId);

ShareXKeysStakingInvalidBalance

Git Source

error ShareXKeysStakingInvalidBalance(uint256 tokenId, uint256 balance);

ShareXKeysStakingNoRewardsToHarvest

Git Source

error ShareXKeysStakingNoRewardsToHarvest(uint256 tokenId);

ShareXMomentumBadgeZeroAddress

Git Source

error ShareXMomentumBadgeZeroAddress();

ShareXMomentumBadgeInvalidArrayLength

Git Source

error ShareXMomentumBadgeInvalidArrayLength();

ShareXMomentumBadgeTokenNotExists

Git Source

error ShareXMomentumBadgeTokenNotExists(uint256 tokenId);

ShareXMomentumBadgeUnauthorizedBurn

Git Source

error ShareXMomentumBadgeUnauthorizedBurn(address caller, uint256 tokenId);

PowerPassStakingZeroAddress

Git Source

error PowerPassStakingZeroAddress();

PowerPassStakingInvalidArrayLength

Git Source

error PowerPassStakingInvalidArrayLength();

PowerPassStakingNotOwner

Git Source

error PowerPassStakingNotOwner(address caller, uint256 tokenId);

PowerPassStakingAlreadyStaked

Git Source

error PowerPassStakingAlreadyStaked(uint256 tokenId);

PowerPassStakingNotStaked

Git Source

error PowerPassStakingNotStaked(uint256 tokenId);

PowerPassStakingUnauthorized

Git Source

error PowerPassStakingUnauthorized(address caller, uint256 tokenId);

PowerPassStakingOrderAlreadyProcessed

Git Source

error PowerPassStakingOrderAlreadyProcessed(bytes32 orderId);

PowerPassStakingInvalidRewardPercentage

Git Source

error PowerPassStakingInvalidRewardPercentage(uint256 bps);

PowerPassStakingInsufficientBalance

Git Source

error PowerPassStakingInsufficientBalance(uint256 required, uint256 available);

PowerPassStakingPaymentTokenNotSet

Git Source

error PowerPassStakingPaymentTokenNotSet();

PowerPassStakingWithdrawFailed

Git Source

error PowerPassStakingWithdrawFailed();

PowerPassStakingTransferFailed

Git Source

error PowerPassStakingTransferFailed();

PowerPassStakingClaimAmountExceedsClaimable

Git Source

error PowerPassStakingClaimAmountExceedsClaimable(uint256 requested, uint256 available);

PowerPassStakingRequestNotFound

Git Source

error PowerPassStakingRequestNotFound(uint256 requestId);

PowerPassStakingRequestNotPending

Git Source

error PowerPassStakingRequestNotPending(uint256 requestId);

PowerPassStakingRequestNotApproved

Git Source

error PowerPassStakingRequestNotApproved(uint256 requestId);

PowerPassStakingNotRequestOwner

Git Source

error PowerPassStakingNotRequestOwner(uint256 requestId, address expected, address actual);

PowerPassStakingZeroClaimAmount

Git Source

error PowerPassStakingZeroClaimAmount();

PowerPassStakingNoApprovedRequests

Git Source

error PowerPassStakingNoApprovedRequests(address user);

PartnerRegistered

Git Source

Emitted when a partner is registered

event PartnerRegistered(
uint256 indexed id,
bytes32 indexed partnerCode,
bytes32 partnerName,
bytes2 iso2,
uint256 timestamp
);

MerchantRegistered

Git Source

Emitted when a merchant is registered

event MerchantRegistered(
uint256 indexed id,
bytes32 indexed merchantName,
bytes32 indexed merchantId,
bytes2 iso2,
uint256 timestamp
);

DeviceRegistered

Git Source

Emitted when a device is registered

event DeviceRegistered(
uint256 indexed id,
bytes32 indexed deviceId,
bytes32 deviceType,
bytes32 partnerCode,
bytes32 merchantId,
uint256 timestamp
);

TransactionBatchUploaded

Git Source

Emitted when a transaction batch is uploaded

event TransactionBatchUploaded(
uint256 indexed batchId,
bytes32 indexed deviceId,
uint32 orderCount,
string totalAmount,
string dateComparable,
uint256 timestamp
);

TransactionDataUploaded

Git Source

Emitted when transaction data is uploaded

event TransactionDataUploaded(uint256 indexed batchId, uint256 transactionCount, uint256 timestamp);

ContractInitialized

Git Source

Emitted when contract is initialized

event ContractInitialized(address indexed admin, Version version, uint256 timestamp);

CountryRegistered

Git Source

Emitted when a country is registered

event CountryRegistered(bytes2 indexed iso2, uint256 timestamp);

PowerPassMinted

Git Source

Emitted when a PowerPass NFT is minted

event PowerPassMinted(address indexed to, uint256 indexed tokenId, string tokenURI);

PowerPassBurned

Git Source

Emitted when a PowerPass NFT is burned

event PowerPassBurned(uint256 indexed tokenId);

PowerPassSalesConfigUpdated

Git Source

Deprecated: Use PowerPassNewRoundStarted for multi-round support

Emitted when PowerPass sales configuration is updated

event PowerPassSalesConfigUpdated(
uint128 priorityStartTime,
uint128 priorityEndTime,
uint128 generalStartTime,
uint128 generalEndTime,
uint128 standardPrice,
uint128 discountCodeDiscount,
uint256 timestamp
);

PowerPassNewRoundStarted

Git Source

Emitted when a new PowerPass sales round is started

event PowerPassNewRoundStarted(
uint64 indexed roundId,
uint128 priorityStartTime,
uint128 priorityEndTime,
uint128 generalStartTime,
uint128 generalEndTime,
uint128 standardPrice,
uint128 discountCodeDiscount,
uint128 roundSupplyLimit,
uint256 timestamp
);

PowerPassBatchMinted

Git Source

Emitted when PowerPass NFTs are minted in batch

event PowerPassBatchMinted(
address indexed to,
uint256 amount,
uint256 totalPrice,
bool indexed isPriorityRound,
uint256 timestamp
);

PowerPassBatchWhitelistSet

Git Source

Emitted when PowerPass whitelist is set for multiple users in a round

event PowerPassBatchWhitelistSet(
uint64 indexed roundId,
address[] accounts,
uint256[] priorityAmounts,
uint256[] generalAmounts,
uint256 timestamp
);

PowerPassNovaDiscountsSet

Git Source

Emitted when Nova discount allocations are configured for a round

event PowerPassNovaDiscountsSet(
uint64 indexed roundId, address[] accounts, uint256[] discountAllocations, uint256 timestamp
);

PowerPassBaseURIUpdated

Git Source

Emitted when PowerPass base URI is updated

event PowerPassBaseURIUpdated(string newBaseURI, uint256 timestamp);

PowerPassFundsWithdrawn

Git Source

Emitted when PowerPass funds are withdrawn

event PowerPassFundsWithdrawn(address indexed admin, uint256 amount, uint256 timestamp);

PowerPassDiscountCodeDiscountUpdated

Git Source

Emitted when global discount code amount is updated

event PowerPassDiscountCodeDiscountUpdated(uint256 newDiscount, uint256 timestamp);

PowerPassDiscountCodesAdded

Git Source

Emitted when discount code hashes are added

event PowerPassDiscountCodesAdded(bytes32[] codeHashes, uint256 timestamp);

PowerPassDiscountCodesRemoved

Git Source

Emitted when discount code hashes are removed

event PowerPassDiscountCodesRemoved(bytes32[] codeHashes, uint256 timestamp);

PowerPassCustodialWhitelistsSet

Git Source

Emitted when custodial whitelist allocations are configured

event PowerPassCustodialWhitelistsSet(address[] accounts, uint256[] allocations, uint256 timestamp);

PowerPassInitialized

Git Source

Emitted when PowerPass contract is initialized

event PowerPassInitialized(
address indexed admin, address indexed stakingContract, string baseURI, uint256 timestamp
);

PowerPassApprovalSet

Git Source

Emitted when PowerPass approval is set through ShareX wallet

event PowerPassApprovalSet(
address indexed tokenContract, address indexed owner, address indexed approved, uint256 tokenId
);

PowerPassApprovalForAllSet

Git Source

Emitted when PowerPass approval for all is set through ShareX wallet

event PowerPassApprovalForAllSet(
address indexed tokenContract, address indexed owner, address indexed operator, bool approved
);

PowerPassBatchApproved

Git Source

Emitted when PowerPass batch approval is completed through ShareX wallet manager

event PowerPassBatchApproved(
address indexed tokenContract, address[] owners, uint256[] tokenIds, address indexed operator
);

PowerPassBatchTransferred

Git Source

Emitted when PowerPass batch transfer is completed through ShareX wallet manager

event PowerPassBatchTransferred(
address indexed tokenContract, address[] from, address[] to, uint256[] tokenIds
);

PowerPassStakedViaWallet

Git Source

Emitted when PowerPass is staked through ShareX wallet

event PowerPassStakedViaWallet(
address indexed stakingContract,
address indexed walletAddr,
uint256 indexed tokenId,
uint256 timestamp
);

PowerPassBatchStakedViaWallet

Git Source

Emitted when PowerPass batch is staked through ShareX wallet

event PowerPassBatchStakedViaWallet(
address indexed stakingContract,
address indexed walletAddr,
uint256[] tokenIds,
uint256 timestamp
);

PowerPassUnstakedViaWallet

Git Source

Emitted when PowerPass is unstaked through ShareX wallet

event PowerPassUnstakedViaWallet(
address indexed stakingContract,
address indexed walletAddr,
uint256 indexed tokenId,
uint256 timestamp
);

PowerPassBatchUnstakedViaWallet

Git Source

Emitted when PowerPass batch is unstaked through ShareX wallet

event PowerPassBatchUnstakedViaWallet(
address indexed stakingContract,
address indexed walletAddr,
uint256[] tokenIds,
uint256 timestamp
);

PowerPassRewardsClaimedViaWallet

Git Source

Emitted when staking rewards are claimed through ShareX wallet

event PowerPassRewardsClaimedViaWallet(
address indexed stakingContract,
address indexed walletAddr,
uint256 indexed tokenId,
uint64 periodId,
uint256 timestamp
);

PowerPassAllRewardsClaimedViaWallet

Git Source

Emitted when all staking rewards are claimed for user through ShareX wallet

event PowerPassAllRewardsClaimedViaWallet(
address indexed stakingContract, address indexed walletAddr, uint256 timestamp
);

PowerPassClaimRequestedViaWallet

Git Source

Emitted when a claim request is submitted through ShareX wallet

event PowerPassClaimRequestedViaWallet(
address indexed stakingContract,
address indexed walletAddr,
uint256 indexed requestId,
uint256 amount,
uint256 timestamp
);

PowerPassRewardClaimedViaWallet

Git Source

Emitted when a single claim request is fulfilled through ShareX wallet

event PowerPassRewardClaimedViaWallet(
address indexed stakingContract,
address indexed walletAddr,
uint256 indexed requestId,
uint256 timestamp
);

ShareXKeysWhitelistsSet

Git Source

Emitted when whitelist amounts are set for one address in ShareX Keys Series

event ShareXKeysWhitelistsSet(
address indexed account, uint256 essentiaAmount, uint256 magnaAmount, uint256 novaAmount
);

ShareXKeysBatchWhitelistsSet

Git Source

Emitted when batch whitelist amounts are set for all NFT types in ShareX Keys Series

event ShareXKeysBatchWhitelistsSet(
address[] accounts, uint256[] essentiaAmounts, uint256[] magnaAmounts, uint256[] novaAmounts
);

ShareXKeysMinted

Git Source

Emitted when ShareX Keys Series NFT is minted

event ShareXKeysMinted(address indexed to, uint256 indexed tokenId, uint256 amount);

ShareXKeysBatchMinted

Git Source

Emitted when multiple ShareX Keys Series NFTs are minted in batch

event ShareXKeysBatchMinted(address indexed to, uint256[] tokenIds, uint256[] amounts);

ShareXKeysInitialized

Git Source

Emitted when ShareX Keys Series contract is initialized

event ShareXKeysInitialized(address indexed admin, uint256 timestamp);

ShareXStakingInitialized

Git Source

Emitted when ShareX Keys Staking contract is initialized

event ShareXStakingInitialized(
address indexed admin, address indexed shareXKeysContract, uint256 timestamp
);

ShareXStakingStaked

Git Source

Emitted when a user stakes tokens

event ShareXStakingStaked(
address indexed user, uint256 indexed tokenId, uint256 amount, uint256 timestamp
);

ShareXStakingUnstaked

Git Source

Emitted when a user unstakes tokens

event ShareXStakingUnstaked(
address indexed user, uint256 indexed tokenId, uint256 amount, uint256 timestamp
);

ShareXStakingBatchStaked

Git Source

Emitted when a user stakes all available tokens in batch

event ShareXStakingBatchStaked(
address indexed user, uint256[] tokenIds, uint256[] amounts, uint256 timestamp
);

ShareXStakingBatchUnstaked

Git Source

Emitted when a user unstakes all tokens in batch

event ShareXStakingBatchUnstaked(
address indexed user, uint256[] tokenIds, uint256[] amounts, uint256 timestamp
);

ShareXStakingRewardsClaimed

Git Source

Emitted when a user claims rewards

event ShareXStakingRewardsClaimed(address indexed user, uint256 rewardAmount, uint256 timestamp);

ShareXStakingPoolUpdated

Git Source

Emitted when pool rewards configuration is updated

event ShareXStakingPoolUpdated(uint256 indexed tokenId, uint256 rewardPerBlock, uint256 timestamp);

ShareXStakingEmergencyWithdrawal

Git Source

Emitted when emergency withdrawal is performed

event ShareXStakingEmergencyWithdrawal(
address indexed user, uint256 indexed tokenId, uint256 amount, uint256 timestamp
);

ShareXStakingTokensBurned

Git Source

Emitted when all tokens for a user are burned by admin

event ShareXStakingTokensBurned(
address indexed admin,
address indexed user,
uint256[] tokenIds,
uint256[] amounts,
uint256 timestamp
);

ShareXMomentumBadgeInitialized

Git Source

event ShareXMomentumBadgeInitialized(address indexed admin, uint256 timestamp);

ShareXMomentumBadgeMinted

Git Source

event ShareXMomentumBadgeMinted(address indexed to, uint256 indexed tokenId);

ShareXMomentumBadgeBatchMinted

Git Source

event ShareXMomentumBadgeBatchMinted(address[] recipients);

ShareXMomentumBadgeBurned

Git Source

event ShareXMomentumBadgeBurned(uint256 indexed tokenId);

ShareXMomentumBadgeBatchBurned

Git Source

event ShareXMomentumBadgeBatchBurned(uint256[] tokenIds);

PowerPassStakingInitialized

Git Source

event PowerPassStakingInitialized(
address indexed admin, address indexed powerPassContract, address indexed paymentToken
);

PowerPassStakingStaked

Git Source

event PowerPassStakingStaked(address indexed user, uint256 indexed tokenId, uint256 timestamp);

PowerPassStakingBatchStaked

Git Source

event PowerPassStakingBatchStaked(address indexed user, uint256[] tokenIds, uint256 timestamp);

PowerPassStakingUnstaked

Git Source

event PowerPassStakingUnstaked(address indexed user, uint256 indexed tokenId, uint256 timestamp);

PowerPassStakingBatchUnstaked

Git Source

event PowerPassStakingBatchUnstaked(address indexed user, uint256[] tokenIds, uint256 timestamp);

PowerPassStakingOrdersUploaded

Git Source

event PowerPassStakingOrdersUploaded(
uint256[] tokenIds, uint256 totalOrders, uint256 totalRewardAmount, uint256 timestamp
);

PowerPassStakingRewardPercentageUpdated

Git Source

event PowerPassStakingRewardPercentageUpdated(uint256 oldBps, uint256 newBps, uint256 timestamp);

PowerPassStakingPaymentTokenUpdated

Git Source

event PowerPassStakingPaymentTokenUpdated(
address indexed oldToken, address indexed newToken, uint256 timestamp
);

PowerPassStakingRewardsWithdrawn

Git Source

event PowerPassStakingRewardsWithdrawn(address indexed admin, uint256 amount, uint256 timestamp);

PowerPassStakingEmergencyNFTWithdrawn

Git Source

event PowerPassStakingEmergencyNFTWithdrawn(
address indexed admin, uint256 indexed tokenId, address indexed to, uint256 timestamp
);

PowerPassStakingOrderRewardRecorded

Git Source

This event is emitted per order to enable detailed reward tracking

orderAmount and rewardAmount can be negative for corrections

Emitted for each order reward recorded during uploadOrders

event PowerPassStakingOrderRewardRecorded(
uint256 indexed tokenId,
bytes32 indexed orderId,
bytes32 powernowDeviceId,
uint64 orderStartTime,
uint64 orderEndTime,
int128 orderAmount, // Signed to support corrections
int128 rewardAmount, // Signed to support corrections
uint64 batchId,
uint256 timestamp
);

PowerPassStakingClaimRequested

Git Source

event PowerPassStakingClaimRequested(
uint256 indexed requestId, address indexed user, uint128 amount, uint256 timestamp
);

PowerPassStakingClaimApproved

Git Source

event PowerPassStakingClaimApproved(
uint256 indexed requestId,
address indexed user,
uint128 amount,
address indexed approver,
uint256 timestamp
);

PowerPassStakingClaimRejected

Git Source

event PowerPassStakingClaimRejected(
uint256 indexed requestId,
address indexed user,
uint128 amount,
address indexed rejector,
uint256 timestamp
);

PowerPassStakingRewardsClaimed

Git Source

event PowerPassStakingRewardsClaimed(
uint256 indexed requestId, address indexed user, uint128 amount, uint256 timestamp
);

PowerPassStakingAllApprovedRewardsClaimed

Git Source

event PowerPassStakingAllApprovedRewardsClaimed(
address indexed user, uint256[] requestIds, uint128 totalAmount, uint256 timestamp
);

PowerPassStakingBatchClaimsApproved

Git Source

event PowerPassStakingBatchClaimsApproved(
uint256[] requestIds, address indexed approver, uint128 totalAmount, uint256 timestamp
);

PowerPassStakingBatchClaimsRejected

Git Source

event PowerPassStakingBatchClaimsRejected(
uint256[] requestIds, address indexed rejector, uint128 totalAmount, uint256 timestamp
);

PowerPassDiscountCodeUsed

Git Source

Emitted when a discount code is used during PowerPass minting

event PowerPassDiscountCodeUsed(
bytes32 indexed codeHash, address indexed user, uint256 quantity, uint256 totalUsageCount
);

PowerPassStakingDirectClaimed

Git Source

Emitted when rewards are directly claimed without USDT transfer (for custodial wallets)

event PowerPassStakingDirectClaimed(address indexed user, uint128 amount, uint256 timestamp);

PowerPassDirectClaimSettledViaWallet

Git Source

Emitted when direct claim is settled via ShareX wallet

event PowerPassDirectClaimSettledViaWallet(
address indexed stakingContract, address indexed walletAddr, uint256 amount, uint256 timestamp
);

Deshare

Git Source

Inherits: Initializable, AccessControl, ReentrancyGuard, IDeshare

Title: Deshare Contract

Handles partner, merchant, device registration and transaction processing

Core business logic contract for Deshare ecosystem data management

State Variables

_version

Core system state including version

Version private _version

_counters

Packed counters instance

PackedCounters private _counters

_partners

Mapping from partner ID to partner information

mapping(uint256 partnerId => PartnerInfo partner) private _partners

_partnerCodeToId

Mapping from partner code hash to partner ID

mapping(bytes32 partnerCode => uint256 partnerId) private _partnerCodeToId

_merchants

Mapping from merchant ID to merchant information

mapping(uint256 merchantId => MerchantInfo merchant) private _merchants

_merchantIdToId

Mapping from merchant ID hash to internal ID

mapping(bytes32 merchantId => uint256 id) private _merchantIdToId

_devices

Mapping from device ID to device information

mapping(uint256 deviceId => DeviceInfo device) private _devices

_deviceIdToId

Mapping from device ID hash to internal ID

mapping(bytes32 deviceId => uint256 id) private _deviceIdToId

_transactionBatches

Mapping from batch ID to transaction batch information

mapping(uint256 batchId => TransactionBatch batch) private _transactionBatches

_transactionData

Mapping from batch ID to transaction data

mapping(uint256 batchId => bytes transactionData) private _transactionData

_countries

Mapping from ISO2 country code to country information

mapping(bytes2 iso2 => CountryInfo country) private _countries

_partnerStatsByBusinessType

Mapping from business type hash to partner count

mapping(bytes32 businessTypeHash => uint256 count) private _partnerStatsByBusinessType

_merchantStatsByRegion

Mapping from country code and location ID hash to merchant count

mapping(bytes2 iso2 => mapping(bytes32 locationIdHash => uint256 count)) private
    _merchantStatsByRegion

Functions

constructor

Constructor that disables initializers to prevent implementation initialization

constructor(address admin) payable;

Parameters

NameTypeDescription
adminaddressAddress for validation (required but not used in implementation)

initialize

Initialize the Deshare proxy

function initialize(address admin) external payable initializer;

Parameters

NameTypeDescription
adminaddressAddress that will be granted admin and operator roles

registerPartner

Register a new partner

function registerPartner(PartnerParams calldata params)
    external
    override
    onlyRole(OPERATOR_ROLE);

Parameters

NameTypeDescription
paramsPartnerParamsPartner registration parameters

registerMerchant

Register a new merchant

function registerMerchant(MerchantParams calldata params)
    external
    override
    onlyRole(OPERATOR_ROLE);

Parameters

NameTypeDescription
paramsMerchantParamsMerchant registration parameters

registerDevice

Register a new device

function registerDevice(DeviceParams calldata params)
    external
    override
    onlyRole(OPERATOR_ROLE);

Parameters

NameTypeDescription
paramsDeviceParamsDevice registration parameters

uploadTransactionBatch

Upload a transaction batch

function uploadTransactionBatch(UploadBatchParams calldata params)
    external
    override
    onlyRole(OPERATOR_ROLE)
    nonReentrant;

Parameters

NameTypeDescription
paramsUploadBatchParamsUpload batch parameters

registerCountry

Register a country

function registerCountry(bytes2 iso2) external override onlyRole(OPERATOR_ROLE);

Parameters

NameTypeDescription
iso2bytes2The ISO2 country code

getVersion

Get the contract version

function getVersion() external view override returns (Version memory);

Returns

NameTypeDescription
<none>Versionversion The current version

getStats

Get statistics information

function getStats() external view override returns (StatsInfo memory stats);

Returns

NameTypeDescription
statsStatsInfoThe current statistics

getDetailedStats

Get detailed statistics information with descriptive labels

function getDetailedStats()
    external
    view
    override
    returns (DetailedStatsInfo memory detailedStats);

Returns

NameTypeDescription
detailedStatsDetailedStatsInfoThe detailed statistics with labels and metadata

getPartner

Get partner information by ID

function getPartner(uint256 partnerId) external view override returns (PartnerInfo memory);

Parameters

NameTypeDescription
partnerIduint256The partner ID

Returns

NameTypeDescription
<none>PartnerInfopartner The partner information

getPartnerByCode

Get partner information by partner code

function getPartnerByCode(string calldata partnerCode)
    external
    view
    override
    returns (PartnerInfo memory);

Parameters

NameTypeDescription
partnerCodestringThe partner code

Returns

NameTypeDescription
<none>PartnerInfopartner The partner information

partnerExists

Check if a partner exists by code

function partnerExists(string calldata partnerCode)
    external
    view
    override
    returns (bool exists);

Parameters

NameTypeDescription
partnerCodestringThe partner code

Returns

NameTypeDescription
existsboolWhether the partner exists

getMerchant

Get merchant information by ID

function getMerchant(uint256 merchantId) external view override returns (MerchantInfo memory);

Parameters

NameTypeDescription
merchantIduint256The merchant ID

Returns

NameTypeDescription
<none>MerchantInfomerchant The merchant information

getMerchantById

Get merchant information by merchant ID

function getMerchantById(string calldata merchantId)
    external
    view
    override
    returns (MerchantInfo memory);

Parameters

NameTypeDescription
merchantIdstringThe merchant ID (string)

Returns

NameTypeDescription
<none>MerchantInfomerchant The merchant information

merchantExists

Check if a merchant exists by ID

function merchantExists(string calldata merchantId)
    external
    view
    override
    returns (bool exists);

Parameters

NameTypeDescription
merchantIdstringThe merchant ID

Returns

NameTypeDescription
existsboolWhether the merchant exists

getDevice

Get device information by ID

function getDevice(uint256 deviceId) external view override returns (DeviceInfo memory);

Parameters

NameTypeDescription
deviceIduint256The device ID

Returns

NameTypeDescription
<none>DeviceInfodevice The device information

getDeviceById

Get device information by device ID

function getDeviceById(string calldata deviceId)
    external
    view
    override
    returns (DeviceInfo memory);

Parameters

NameTypeDescription
deviceIdstringThe device ID (string)

Returns

NameTypeDescription
<none>DeviceInfodevice The device information

deviceExists

Check if a device exists by ID

function deviceExists(string calldata deviceId) external view override returns (bool exists);

Parameters

NameTypeDescription
deviceIdstringThe device ID

Returns

NameTypeDescription
existsboolWhether the device exists

getTransactionBatch

Get transaction batch by ID

function getTransactionBatch(uint256 batchId)
    external
    view
    override
    returns (TransactionBatch memory);

Parameters

NameTypeDescription
batchIduint256The batch ID

Returns

NameTypeDescription
<none>TransactionBatchbatch The transaction batch

getTransactionData

Retrieves transaction data for a batch

function getTransactionData(uint256 batchId)
    external
    view
    override
    returns (string memory jsonData);

Parameters

NameTypeDescription
batchIduint256The batch ID to retrieve data for

Returns

NameTypeDescription
jsonDatastringThe transaction data as JSON string

getCountry

Get country information

function getCountry(bytes2 iso2) external view override returns (CountryInfo memory);

Parameters

NameTypeDescription
iso2bytes2The ISO2 country code

Returns

NameTypeDescription
<none>CountryInfocountry The country information

countryExists

Check if a country is registered

function countryExists(bytes2 iso2) external view override returns (bool exists);

Parameters

NameTypeDescription
iso2bytes2The ISO2 country code

Returns

NameTypeDescription
existsboolWhether the country is registered

getPartnerCountByBusinessType

Get the number of partners for a given business type

function getPartnerCountByBusinessType(string calldata businessType)
    external
    view
    override
    returns (uint256 count);

Parameters

NameTypeDescription
businessTypestringThe business type to query

Returns

NameTypeDescription
countuint256The count of partners

getMerchantCountByRegion

Get the number of merchants for a given region

function getMerchantCountByRegion(bytes2 iso2, string calldata locationId)
    external
    view
    override
    returns (uint256 count);

Parameters

NameTypeDescription
iso2bytes2The ISO2 country code
locationIdstringThe location ID (e.g., city identifier)

Returns

NameTypeDescription
countuint256The count of merchants

_getCountriesCount

Returns the count of registered countries

function _getCountriesCount() internal view returns (uint256 count);

Returns

NameTypeDescription
countuint256The number of registered countries

_createTransactionBatch

Creates and stores a new transaction batch

function _createTransactionBatch(UploadBatchParams calldata params)
    private
    returns (uint64 batchId);

Parameters

NameTypeDescription
paramsUploadBatchParamsThe upload batch parameters

Returns

NameTypeDescription
batchIduint64The ID of the created batch

_storeTransactionData

Stores transaction data for a batch

function _storeTransactionData(uint64 batchId, bytes calldata transactionData) private;

Parameters

NameTypeDescription
batchIduint64The batch ID to store data for
transactionDatabytesThe transaction data to store

_emitBatchEvents

Emits events for transaction batch upload

function _emitBatchEvents(
    uint64 batchId,
    bytes32 deviceIdHash,
    UploadBatchParams calldata params
) private;

Parameters

NameTypeDescription
batchIduint64The batch ID
deviceIdHashbytes32The hash of the device ID
paramsUploadBatchParamsThe upload batch parameters

_validateUploadBatchParams

Validates the upload batch parameters

function _validateUploadBatchParams(UploadBatchParams calldata params)
    private
    view
    returns (bytes32 deviceIdHash);

Parameters

NameTypeDescription
paramsUploadBatchParamsThe upload batch parameters to validate

Returns

NameTypeDescription
deviceIdHashbytes32The hash of the device ID for later use

PowerPass

Git Source

Inherits: Initializable, ERC721Upgradeable, ERC721URIStorageUpgradeable, AccessControlUpgradeable, ReentrancyGuardUpgradeable, IPowerPass

Title: PowerPass - ShareX Ecosystem Premium Access NFT

Author: ShareX Team

Upgradeable ERC721 contract with time-based whitelist sales rounds PowerPass implements sophisticated whitelist-based sales with two rounds:

  • Priority Round: Exclusive access for MAGNA/NOVA stakers
  • General Round: Access for all ShareX Keys stakers Features:
  • Gas-optimized struct packing and unchecked arithmetic
  • Snapshot-based whitelist eligibility tied to ShareXKeysStaking
  • Admin-configurable sales rounds and pricing
  • Upgradeable proxy pattern for future enhancements
  • Comprehensive validation and error handling

State Variables

MAX_SUPPLY

Maximum supply of PowerPass NFTs

uint256 public constant MAX_SUPPLY = 5000

BPS_DENOMINATOR

Basis points denominator for discount calculations

uint16 private constant BPS_DENOMINATOR = 10_000

NOVA_DISCOUNT_BPS

Nova discount expressed in basis points (80%)

uint16 private constant NOVA_DISCOUNT_BPS = 8_000

MAX_NOVA_DISCOUNT_PER_ADDRESS

Maximum number of discounted NFTs per address for Nova holders

uint64 private constant MAX_NOVA_DISCOUNT_PER_ADDRESS = 10

_paymentToken

ERC20 payment token (e.g., USDT on BSC)

IERC20 private _paymentToken

MINTER_ROLE

Optional direct mint role for operational tooling

bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE")

_currentRoundId

Current active round ID (starts from 1, 0 = no round started)

uint64 private _currentRoundId

_roundConfigs

Round configurations: roundId => RoundConfig

mapping(uint64 roundId => PowerPassRoundConfig config) private _roundConfigs

_roundWhitelists

Round whitelists: roundId => user => WhitelistInfo

mapping(uint64 roundId => mapping(address user => PowerPassWhitelistInfo whitelist)) private
    _roundWhitelists

_custodialWhitelists

Custodial whitelist allocations for ShareX wallet flow (independent of rounds)

mapping(address account => PowerPassCustodialWhitelistInfo whitelist) private
    _custodialWhitelists

_baseTokenURI

Base URI for token metadata

string private _baseTokenURI

_discountCodes

Active discount code hashes

mapping(bytes32 codeHash => bool isActive) private _discountCodes

_totalSupply

Current token supply

uint256 private _totalSupply

_currentTokenId

Current token ID counter

uint256 private _currentTokenId

_web3MintedCount

Web3 channel minted count (via public mint function)

uint256 private _web3MintedCount

_custodialMintedCount

Custodial/Web2 channel minted count (via MINTER_ROLE)

uint256 private _custodialMintedCount

_discountCodeUsageCount

Discount code usage count: codeHash => number of NFTs minted using this code

mapping(bytes32 codeHash => uint256 usageCount) private _discountCodeUsageCount

__gap

Storage gap for upgrade safety

uint256[30] private __gap

Functions

validAddress

Modifier to validate non-zero addresses

modifier validAddress(address addr) ;

validAmount

Modifier to validate non-zero amounts

modifier validAmount(uint256 amount) ;

initialize

Initialize the PowerPass contract

Replaces constructor for upgradeable pattern

function initialize(address _admin, string calldata baseURI_)
    external
    initializer
    validAddress(_admin);

Parameters

NameTypeDescription
_adminaddressAddress to grant admin role to
baseURI_stringBase URI for token metadata

initializeWithToken

Initialize with admin, baseURI and payment token

function initializeWithToken(address _admin, string calldata baseURI_, address paymentToken_)
    external
    initializer
    validAddress(_admin)
    validAddress(paymentToken_);

Parameters

NameTypeDescription
_adminaddressAddress to grant admin role to
baseURI_stringBase URI for token metadata
paymentToken_addressERC20 token used for payments (e.g., USDT)

startNewRound

Start a new sales round with configuration and supply limit

Admin function to create a new round; increments roundId automatically

function startNewRound(SalesConfig calldata config, uint256 supplyLimit)
    external
    override
    onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
configSalesConfigSales configuration including timestamps and pricing
supplyLimituint256Maximum NFTs for this round (0 = no limit, still capped by MAX_SUPPLY) Requirements: - Caller must have DEFAULT_ADMIN_ROLE - Priority round must end before or when general round starts - All timestamps must be future timestamps (> block.timestamp) - Standard price must be greater than 0 Emits: PowerPassNewRoundStarted event

setPaymentToken

Set ERC20 payment token address (e.g., USDT on BSC)

Admin function; price is interpreted in this token's decimals

function setPaymentToken(address token) external override onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
tokenaddressERC20 token address used for payments

setDiscountCodeDiscount

Set discount code discount amount for current round

Updates discountCodeDiscount in current round config

function setDiscountCodeDiscount(uint256 discountAmount)
    external
    override
    onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
discountAmountuint256New discount amount per NFT

addDiscountCodes

Register discount code hashes that can be redeemed on-chain

function addDiscountCodes(bytes32[] calldata codeHashes)
    external
    override
    onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
codeHashesbytes32[]Array of keccak256 hashes of discount codes

removeDiscountCodes

Remove discount code hashes

function removeDiscountCodes(bytes32[] calldata codeHashes)
    external
    override
    onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
codeHashesbytes32[]Array of keccak256 hashes of discount codes to remove

isDiscountCodeValid

Check if discount code hash is currently active

function isDiscountCodeValid(bytes32 codeHash) external view override returns (bool);

Parameters

NameTypeDescription
codeHashbytes32keccak256 hash of the off-chain discount code

getDiscountCodeUsageCount

Get the usage count for a specific discount code

Only counts usage when discount code is actually applied (excludes Nova discount cases)

function getDiscountCodeUsageCount(bytes32 codeHash) external view override returns (uint256);

Parameters

NameTypeDescription
codeHashbytes32keccak256 hash of the discount code

Returns

NameTypeDescription
<none>uint256usageCount Number of NFTs minted using this discount code

mint

Mint PowerPass NFTs during active sales rounds

Gas-optimized minting with comprehensive validation

function mint(uint256 amount, string calldata discountCode)
    external
    payable
    override
    nonReentrant
    validAmount(amount);

Parameters

NameTypeDescription
amountuint256Number of NFTs to mint
discountCodestringOptional discount code string; ignored when empty or Nova discount applies Validation includes: - Active sales round verification (priority or general) - Whitelist allocation and remaining balance checks - Payment in ERC20 payment token (e.g., USDT) equals applicable discounted price * amount - Maximum supply limit enforcement Requirements: - Active sales round (priority or general) must be ongoing - Amount must not exceed remaining allocation for current round - Payment must be provided via ERC20 approve + transferFrom - User must have whitelist allocation for current round Emits: PowerPassBatchMinted event

_calculateTotalPrice

Calculate total price with Nova and discount code discounts

function _calculateTotalPrice(
    PowerPassRoundConfig storage roundConfig,
    uint256 amount,
    uint256 novaEligible,
    string calldata discountCode
) private returns (uint256 totalPrice);

Parameters

NameTypeDescription
roundConfigPowerPassRoundConfigRound configuration containing prices
amountuint256Total amount to mint
novaEligibleuint256Amount eligible for Nova discount
discountCodestringDiscount code string

Returns

NameTypeDescription
totalPriceuint256Final price after discounts

batchSetWhitelists

Batch set whitelist allocations for multiple users

Admin function for efficient whitelist management. Preserves already minted counts and clamps new allocations to be >= minted so far for each round.

function batchSetWhitelists(
    address[] calldata accounts,
    uint256[] calldata priorityAmounts,
    uint256[] calldata generalAmounts
) external override onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
accountsaddress[]Array of addresses to set allocations for
priorityAmountsuint256[]Array of priority allocations corresponding to accounts
generalAmountsuint256[]Array of total (priority + general) allocations corresponding to accounts Requirements: - Caller must have DEFAULT_ADMIN_ROLE - All arrays must have equal length - No account can be zero address - Never reduces effective allocation below already minted amounts - Gas-optimized with unchecked arithmetic for large batches Emits: PowerPassBatchWhitelistSet event

batchSetNovaDiscounts

Batch set Nova discount allocations for multiple users

Admin function to configure 80% pricing eligibility per address

function batchSetNovaDiscounts(
    address[] calldata accounts,
    uint256[] calldata discountAllocations
) external override onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
accountsaddress[]Array of addresses to configure
discountAllocationsuint256[]Array of discount allocations corresponding to accounts

batchSetCustodialWhitelists

Batch set custodial mint allocations for ShareX wallet users

Separate whitelist for web2 custodial flow; amounts represent direct mint allowance

function batchSetCustodialWhitelists(
    address[] calldata accounts,
    uint256[] calldata allocations
) external override onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
accountsaddress[]Custodial wallet addresses (ShareX wallet addresses or end-user custodial addrs)
allocationsuint256[]Total NFTs each address may receive via custodial mint

setBaseURI

Set the base URI for token metadata

Admin function to configure NFT metadata URIs

function setBaseURI(string calldata baseURI) external override onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
baseURIstringThe new base URI for all tokens Requirements: - Caller must have DEFAULT_ADMIN_ROLE - BaseURI should point to valid metadata endpoint Emits: PowerPassBaseURIUpdated event

withdrawFunds

Withdraw payment tokens to admin

Admin function to withdraw accumulated ERC20 (USDT) from sales Requirements:

  • Caller must have DEFAULT_ADMIN_ROLE
  • Contract must have token balance > 0 Emits: PowerPassFundsWithdrawn event
function withdrawFunds() external override onlyRole(DEFAULT_ADMIN_ROLE);

paymentToken

Get ERC20 payment token address

function paymentToken() external view override returns (address);

mint

Direct mint by operators with MINTER_ROLE

function mint(address to, string calldata tokenURI_)
    external
    onlyRole(MINTER_ROLE)
    returns (uint256 tokenId);

mint

Direct mint by operators with MINTER_ROLE using automatic token URI formatting

function mint(address to) external onlyRole(MINTER_ROLE) returns (uint256 tokenId);

burn

Burn a token (legacy compatibility)

function burn(uint256 tokenId) external;

Parameters

NameTypeDescription
tokenIduint256Token ID to burn

setTokenURI

Set token URI for a specific token (admin only)

function setTokenURI(uint256 tokenId, string calldata newTokenURI)
    external
    onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
tokenIduint256Token ID to set URI for
newTokenURIstringNew URI for the token

setCurrentTokenId

Set the next token ID counter (admin only)

Use this to skip token ID 0 and start from 1, or resume from a specific ID

function setCurrentTokenId(uint256 newTokenId) external onlyRole(DEFAULT_ADMIN_ROLE);

Parameters

NameTypeDescription
newTokenIduint256The next token ID to be minted

currentTokenId

Get the current token ID counter

function currentTokenId() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256The next token ID that will be minted

getMintStatus

Get current mint status for a user

View function providing complete minting information and round status

function getMintStatus(address account)
    external
    view
    override
    returns (MintStatus memory status);

Parameters

NameTypeDescription
accountaddressThe address to query mint status for

Returns

NameTypeDescription
statusMintStatusComplete mint status including allocations, current price, and round status The MintStatus contains: - priorityRemaining: NFTs remaining in priority allocation - generalRemaining: NFTs remaining in general allocation - standardPrice: Current standard price per NFT based on active round - isPriorityActive: Whether priority round is currently active - isGeneralActive: Whether general round is currently active

getWhitelistInfo

Get whitelist allocations for an account

View function for checking total allocations across both rounds

function getWhitelistInfo(address account)
    external
    view
    override
    returns (WhitelistInfo memory info);

Parameters

NameTypeDescription
accountaddressThe address to query allocations for

Returns

NameTypeDescription
infoWhitelistInfoComplete whitelist information including allocations and minted amounts The WhitelistInfo contains: - priorityAllocation: Total NFTs allocated for priority round - generalAllocation: Total NFTs allocated for general round - priorityMinted: Already minted in priority round - generalMinted: Already minted in general round

getCustodialWhitelistInfo

Get custodial whitelist allocation info for a ShareX wallet address

function getCustodialWhitelistInfo(address account)
    external
    view
    override
    returns (CustodialWhitelistInfo memory info);

getSalesConfig

Get current sales configuration (from current round)

View function for checking sales round parameters and pricing

function getSalesConfig() external view override returns (SalesConfig memory config);

Returns

NameTypeDescription
configSalesConfigComplete sales configuration including timestamps and pricing The SalesConfig contains: - priorityStartTime: Priority round start timestamp (UTC+8) - priorityEndTime: Priority round end timestamp (UTC+8) - generalStartTime: General round start timestamp (UTC+8) - generalEndTime: General round end timestamp (UTC+8) - standardPrice: Price per NFT in wei

getCurrentRoundId

Get current round ID

function getCurrentRoundId() external view override returns (uint64);

Returns

NameTypeDescription
<none>uint64roundId Current active round ID (0 = no round started)

getCurrentRoundInfo

Get current round information including supply limit and minted count

function getCurrentRoundInfo() external view override returns (RoundInfo memory info);

Returns

NameTypeDescription
infoRoundInfoRoundInfo struct with roundId, supplyLimit, mintedCount, remaining

getRoundConfig

Get configuration for a specific round

function getRoundConfig(uint64 roundId)
    external
    view
    override
    returns (SalesConfig memory config, uint256 supplyLimit, uint256 mintedCount);

Parameters

NameTypeDescription
roundIduint64Round ID to query

Returns

NameTypeDescription
configSalesConfigSales configuration for the round
supplyLimituint256Maximum NFTs for the round
mintedCountuint256NFTs already minted in the round

getWhitelistInfoForRound

Get whitelist info for a user in a specific round

function getWhitelistInfoForRound(uint64 roundId, address account)
    external
    view
    override
    returns (WhitelistInfo memory info);

Parameters

NameTypeDescription
roundIduint64Round ID to query
accountaddressUser address to query

Returns

NameTypeDescription
infoWhitelistInfoWhitelistInfo for the user in the specified round

totalSupply

Get total supply of minted PowerPass NFTs

View function for supply tracking and analytics

function totalSupply() external view override returns (uint256);

Returns

NameTypeDescription
<none>uint256totalSupply Current total supply of minted NFTs

getChannelMintedCounts

Get minted counts by channel (Web3 vs Custodial/Web2)

function getChannelMintedCounts()
    external
    view
    returns (uint256 web3Count, uint256 custodialCount);

Returns

NameTypeDescription
web3Countuint256Number of NFTs minted via Web3 public mint
custodialCountuint256Number of NFTs minted via custodial/Web2 channel

maxSupply

Get maximum supply limit for PowerPass NFTs

View function for supply cap information

function maxSupply() external pure override returns (uint256);

Returns

NameTypeDescription
<none>uint256maxSupply Maximum number of NFTs that can ever be minted

supportsInterface

function supportsInterface(bytes4 interfaceId)
    public
    view
    override(ERC721Upgradeable, ERC721URIStorageUpgradeable, AccessControlUpgradeable, IERC165)
    returns (bool);

tokenURI

function tokenURI(uint256 tokenId)
    public
    view
    override(ERC721Upgradeable, ERC721URIStorageUpgradeable)
    returns (string memory);

_update

Transfers tokenId from its current owner to to, or alternatively mints (or burns) if the current owner (or to) is the zero address. Returns the owner of the tokenId before the update. The auth argument is optional. If the value passed is non 0, then this function will check that auth is either the owner of the token, or approved to operate on the token (by the owner). Emits a {Transfer} event. NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}.

function _update(address to, uint256 tokenId, address auth)
    internal
    override(ERC721Upgradeable)
    returns (address);

_increaseBalance

Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that a uint256 would ever overflow from increments when these increments are bounded to uint128 values. WARNING: Increasing an account's balance using this function tends to be paired with an override of the {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership remain consistent with one another.

function _increaseBalance(address account, uint128 value) internal override(ERC721Upgradeable);

_baseURI

Base URI for tokens

function _baseURI() internal view override returns (string memory);

_validateAndUpdateAllocation

Validate and update allocation for minting

function _validateAndUpdateAllocation(
    PowerPassWhitelistInfo storage userWhitelist,
    uint256 amount,
    bool isPriorityActive
) private returns (uint256 novaEligible);

Parameters

NameTypeDescription
userWhitelistPowerPassWhitelistInfo
amountuint256Amount to mint
isPriorityActiveboolWhether priority round is active

_mintTokens

Mint tokens with gas-optimized loop and proper token URI formatting

function _mintTokens(uint256 amount) private;

Parameters

NameTypeDescription
amountuint256Amount of tokens to mint

_formatTokenURI

Format token URI properly as {tokenId}.json

function _formatTokenURI(uint256 tokenId) private pure returns (string memory);

Parameters

NameTypeDescription
tokenIduint256Token ID to format

Returns

NameTypeDescription
<none>stringFormatted token URI relative path

_toString

Convert uint256 to string (gas-optimized)

function _toString(uint256 value) private pure returns (string memory);

Parameters

NameTypeDescription
valueuint256Number to convert

Returns

NameTypeDescription
<none>stringString representation of the number

_checkRoundActive

Check if priority or general round is active for given config

function _checkRoundActive(PowerPassRoundConfig storage config)
    private
    view
    returns (bool isPriorityActive, bool isGeneralActive);

Parameters

NameTypeDescription
configPowerPassRoundConfigRound configuration to check

Returns

NameTypeDescription
isPriorityActiveboolWhether priority round is active
isGeneralActiveboolWhether general round is active

_priorityRemaining

function _priorityRemaining(PowerPassWhitelistInfo storage info)
    private
    view
    returns (uint256);

_generalRemaining

function _generalRemaining(PowerPassWhitelistInfo storage info) private view returns (uint256);

_novaDiscountRemainingRaw

function _novaDiscountRemainingRaw(PowerPassWhitelistInfo storage info)
    private
    view
    returns (uint256);

_novaDiscountRemaining

function _novaDiscountRemaining(PowerPassWhitelistInfo storage info)
    private
    view
    returns (uint256);

_calculateNovaDiscountPrice

function _calculateNovaDiscountPrice(uint256 standardPrice) private pure returns (uint256);

_calculatePriorityAllocation

Calculate priority round allocation based on MAGNA/NOVA stakes

function _calculatePriorityAllocation(uint256 magnaStaked, uint256 novaStaked)
    private
    pure
    returns (uint64 allocation);

Parameters

NameTypeDescription
magnaStakeduint256Amount of MAGNA tokens staked
novaStakeduint256Amount of NOVA tokens staked

Returns

NameTypeDescription
allocationuint64Priority round allocation (max 10 NFTs)

_calculateGeneralAllocation

Calculate general round allocation based on all stakes

function _calculateGeneralAllocation(
    uint256 essentiaStaked,
    uint256 magnaStaked,
    uint256 novaStaked
) private pure returns (uint64 allocation);

Parameters

NameTypeDescription
essentiaStakeduint256Amount of ESSENTIA tokens staked
magnaStakeduint256Amount of MAGNA tokens staked
novaStakeduint256Amount of NOVA tokens staked

Returns

NameTypeDescription
allocationuint64General round allocation (max 10 NFTs)

PowerPassStaking

Git Source

Inherits: Initializable, AccessControlUpgradeable, PausableUpgradeable, ReentrancyGuardUpgradeable, IERC721Receiver, IPowerPassStaking

Title: PowerPassStaking - NFT Staking with Claim Request/Approval Workflow

Author: ShareX Team

Upgradeable staking contract for PowerPass NFTs with admin-approved claim flow Key Features:

  • Users stake NFTs to accumulate rewards from powerbank device orders
  • Users request to claim rewards, which requires admin approval
  • Minimal on-chain storage: only Pending/Approved requests stored
  • Rejected/Claimed requests are deleted, tracked via events for off-chain indexing

State Variables

BPS_DENOMINATOR

uint256 public constant BPS_DENOMINATOR = 10_000

DEFAULT_REWARD_BPS

uint256 public constant DEFAULT_REWARD_BPS = 2500

OPERATOR_ROLE

bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE")

_powerPassContract

IERC721 private _powerPassContract

_paymentToken

IERC20 private _paymentToken

_rewardBps

uint96 private _rewardBps

_totalStaked

uint256 private _totalStaked

_totalPendingRewards

uint256 private _totalPendingRewards

_stakingInfo

tokenId => StakingInfo

mapping(uint256 tokenId => StakingInfoInternal info) private _stakingInfo

_userStakedTokens

user => staked tokenIds

mapping(address user => uint256[] tokenIds) private _userStakedTokens

_tokenIndex

tokenId => index in user's array

mapping(uint256 tokenId => uint256 index) private _tokenIndex

_rewardBatchCounter

Counter for reward upload batches (used in events for off-chain indexing)

uint64 private _rewardBatchCounter

_requestCounter

Request counter (never resets, ensures unique requestId)

uint256 private _requestCounter

_claimRequests

requestId => ClaimRequest (only stores Pending/Approved)

mapping(uint256 requestId => ClaimRequestInternal request) private _claimRequests

_userActiveRequests

user => active requestIds (Pending + Approved)

mapping(address user => uint256[] requestIds) private _userActiveRequests

_requestIndexInUser

requestId => index in user's active requests array

mapping(uint256 requestId => uint256 index) private _requestIndexInUser

_userClaimInfo

user => UserClaimInfo

mapping(address user => UserClaimInfoInternal info) private _userClaimInfo

_pendingRequestIds

All pending request IDs (for admin query)

uint256[] private _pendingRequestIds

_pendingRequestIndex

requestId => index + 1 in pending array (0 means not in array)

mapping(uint256 requestId => uint256 indexPlusOne) private _pendingRequestIndex

__gap

uint256[30] private __gap

Functions

validAddress

modifier validAddress(address addr) ;

initialize

function initialize(address powerPass_, address paymentToken_, address admin_)
    external
    initializer
    validAddress(powerPass_)
    validAddress(paymentToken_)
    validAddress(admin_);

stake

function stake(uint256 tokenId) external override nonReentrant whenNotPaused;

stakeBatch

function stakeBatch(uint256[] calldata tokenIds) external override nonReentrant whenNotPaused;

unstake

function unstake(uint256 tokenId) external override nonReentrant whenNotPaused;

unstakeBatch

function unstakeBatch(uint256[] calldata tokenIds)
    external
    override
    nonReentrant
    whenNotPaused;

requestClaim

function requestClaim(uint256 amount)
    external
    override
    nonReentrant
    whenNotPaused
    returns (uint256 requestId);

claimRewards

function claimRewards(uint256 requestId) external override nonReentrant whenNotPaused;

claimAllApprovedRewards

function claimAllApprovedRewards() external override nonReentrant whenNotPaused;

approveClaim

function approveClaim(uint256 requestId)
    external
    override
    onlyRole(DEFAULT_ADMIN_ROLE)
    nonReentrant;

rejectClaim

function rejectClaim(uint256 requestId)
    external
    override
    onlyRole(DEFAULT_ADMIN_ROLE)
    nonReentrant;

batchApproveClaims

function batchApproveClaims(uint256[] calldata requestIds)
    external
    override
    onlyRole(DEFAULT_ADMIN_ROLE)
    nonReentrant;

batchRejectClaims

function batchRejectClaims(uint256[] calldata requestIds)
    external
    override
    onlyRole(DEFAULT_ADMIN_ROLE)
    nonReentrant;

directClaim

function directClaim(uint256 amount) external override nonReentrant whenNotPaused;

uploadOrders

function uploadOrders(uint256[] calldata tokenIds, OrderInfo[][] calldata orders)
    external
    override
    onlyRole(OPERATOR_ROLE)
    nonReentrant;

setRewardPercentage

function setRewardPercentage(uint256 rewardBps) external override onlyRole(DEFAULT_ADMIN_ROLE);

setPaymentToken

function setPaymentToken(address token)
    external
    override
    onlyRole(DEFAULT_ADMIN_ROLE)
    validAddress(token);

withdrawExcessRewards

function withdrawExcessRewards(uint256 amount)
    external
    override
    onlyRole(DEFAULT_ADMIN_ROLE)
    nonReentrant;

emergencyWithdrawNFT

function emergencyWithdrawNFT(uint256 tokenId, address to)
    external
    override
    onlyRole(DEFAULT_ADMIN_ROLE)
    validAddress(to)
    nonReentrant;

pause

function pause() external onlyRole(DEFAULT_ADMIN_ROLE);

unpause

function unpause() external onlyRole(DEFAULT_ADMIN_ROLE);

getStakingInfo

function getStakingInfo(uint256 tokenId)
    external
    view
    override
    returns (StakingInfo memory info);

isStaked

function isStaked(uint256 tokenId) external view override returns (bool);

getStaker

function getStaker(uint256 tokenId) external view override returns (address staker);

getStakedTokenIds

function getStakedTokenIds(address user) external view override returns (uint256[] memory);

powerPassContract

function powerPassContract() external view override returns (address);

paymentToken

function paymentToken() external view override returns (address);

rewardPercentage

function rewardPercentage() external view override returns (uint256);

totalStaked

function totalStaked() external view override returns (uint256);

getUserTotalRewards

function getUserTotalRewards(address user) external view override returns (uint256);

getClaimableAmount

function getClaimableAmount(address user) external view override returns (uint256);

getUserRewardsSummary

function getUserRewardsSummary(address user)
    external
    view
    override
    returns (UserRewardsSummary memory summary);

getUserClaimInfo

function getUserClaimInfo(address user)
    external
    view
    override
    returns (UserClaimInfo memory info);

getUserActiveRequests

function getUserActiveRequests(address user)
    external
    view
    override
    returns (ClaimRequest[] memory requests);

getClaimRequest

function getClaimRequest(uint256 requestId)
    external
    view
    override
    returns (ClaimRequest memory request);

getPendingClaimRequests

function getPendingClaimRequests()
    external
    view
    override
    returns (ClaimRequest[] memory requests);

getPendingClaimRequestCount

function getPendingClaimRequestCount() external view override returns (uint256);

onERC721Received

function onERC721Received(address, address, uint256, bytes calldata)
    external
    pure
    override
    returns (bytes4);

_stake

function _stake(address user, uint256 tokenId) internal;

_unstake

function _unstake(address user, uint256 tokenId) internal;

_removeTokenFromUser

function _removeTokenFromUser(address user, uint256 tokenId) internal;

_approveClaim

function _approveClaim(uint256 requestId) internal;

_approveClaimInternal

function _approveClaimInternal(uint256 requestId) internal returns (uint128 amount);

_rejectClaim

function _rejectClaim(uint256 requestId) internal;

_rejectClaimInternal

function _rejectClaimInternal(uint256 requestId) internal returns (uint128 amount);

_removeRequest

function _removeRequest(uint256 requestId, address user) internal;

_removeFromPendingList

function _removeFromPendingList(uint256 requestId) internal;

_processOrdersBatch

function _processOrdersBatch(
    uint256[] calldata tokenIds,
    OrderInfo[][] calldata orders,
    uint64 batchId
) internal returns (int256 netRewardChange, uint256 totalOrders);

_processTokenOrders

function _processTokenOrders(
    uint256 tokenId,
    OrderInfo[] calldata tokenOrders,
    uint256 rewardBps,
    uint64 batchId
) internal returns (int256 tokenRewardChange, uint256 orderCount);

_getUserTotalRewards

function _getUserTotalRewards(address user) internal view returns (uint256 totalRewards);

_getClaimableAmount

function _getClaimableAmount(address user) internal view returns (uint256);

Structs

StakingInfoInternal

Packed staking info (3 storage slots)

struct StakingInfoInternal {
    address owner; // 20 bytes
    uint64 stakedAt; // 8 bytes
    bool isStaked; // 1 byte
    // 3 bytes padding
    uint128 totalRewards; // 16 bytes - slot 2 (cumulative, never resets)
    uint128 rewardsAtStake; // 16 bytes - slot 3 (snapshot when user staked)
}

ClaimRequestInternal

Packed claim request (2 storage slots)

struct ClaimRequestInternal {
    address user; // 20 bytes
    uint64 requestTime; // 8 bytes
    ClaimRequestStatus status; // 1 byte
    uint128 amount; // 16 bytes - new slot
}

UserClaimInfoInternal

Packed user claim info (2 storage slots)

struct UserClaimInfoInternal {
    uint128 totalEarned; // 16 bytes - total rewards earned (includes settled from unstaked
    // NFTs)
    uint128 claimed; // 16 bytes - total claimed amount
    uint64 pendingApproval; // 8 bytes - amount waiting for approval
    uint64 approved; // 8 bytes - amount approved but not yet claimed
}

ShareXKeysSeries

Git Source

Inherits: ERC1155Supply, AccessControl, IShareXKeysSeries

State Variables

ESSENTIA

uint256 public constant ESSENTIA = 0

MAGNA

uint256 public constant MAGNA = 1

NOVA

uint256 public constant NOVA = 2

_whitelists

mapping(address account => mapping(uint256 tokenId => uint256 amount)) private _whitelists

_minted

mapping(address account => mapping(uint256 tokenId => uint256 amount)) private _minted

_tokenURIs

mapping(uint256 tokenId => string tokenURI) private _tokenURIs

Functions

constructor

constructor(string memory baseURI) ERC1155(baseURI);

uri

function uri(uint256 tokenId) public view virtual override returns (string memory);

setTokenURI

function setTokenURI(uint256 tokenId, string calldata tokenURI)
    external
    onlyRole(DEFAULT_ADMIN_ROLE);

setWhitelists

function setWhitelists(
    address account,
    uint256 essentiaAmount,
    uint256 magnaAmount,
    uint256 novaAmount
) external override onlyRole(DEFAULT_ADMIN_ROLE);

batchSetWhitelists

function batchSetWhitelists(
    address[] calldata accounts,
    uint256[] calldata essentiaAmounts,
    uint256[] calldata magnaAmounts,
    uint256[] calldata novaAmounts
) external override onlyRole(DEFAULT_ADMIN_ROLE);

mint

function mint(uint256 tokenId, uint256 amount) external override;

mintAll

function mintAll() external override;

getMintStatus

function getMintStatus(address account)
    external
    view
    override
    returns (MintStatus memory essentia, MintStatus memory magna, MintStatus memory nova);

getWhitelisted

function getWhitelisted(address account)
    external
    view
    override
    returns (uint256 essentiaAmount, uint256 magnaAmount, uint256 novaAmount);

supportsInterface

function supportsInterface(bytes4 interfaceId)
    public
    view
    override(ERC1155, AccessControl, IERC165)
    returns (bool);

_validateMintParameters

function _validateMintParameters(address to, uint256 tokenId, uint256 amount) internal pure;

_getMintStatusForToken

function _getMintStatusForToken(address account, uint256 tokenId)
    private
    view
    returns (MintStatus memory status);

ShareXKeysStaking

Git Source

Inherits: Initializable, AccessControlUpgradeable, PausableUpgradeable, ReentrancyGuardUpgradeable, IERC1155Receiver, IShareXKeysStaking

State Variables

ESSENTIA

Token type constants

uint256 public constant ESSENTIA = 0

MAGNA

uint256 public constant MAGNA = 1

NOVA

uint256 public constant NOVA = 2

PRECISION_FACTOR

Precision factor for reward calculations

uint256 public constant PRECISION_FACTOR = 1e18

shareXKeysContract

ShareX Keys Series contract for token operations

IShareXKeysSeries public shareXKeysContract

_stakes

User staking information: user => tokenId => StakeInfo

mapping(address user => mapping(uint256 tokenId => StakeInfo)) private _stakes

_pools

Pool information for each token type: tokenId => InternalPoolInfo

mapping(uint256 tokenId => InternalPoolInfo poolInfo) private _pools

__gap

Storage gap for upgrade safety

uint256[45] private __gap

Functions

validTokenId

Modifier to validate token IDs (0, 1, 2)

modifier validTokenId(uint256 tokenId) ;

validAmount

Modifier to validate non-zero amounts

modifier validAmount(uint256 amount) ;

initialize

Initialize the staking contract

Replaces constructor for upgradeable pattern

function initialize(address _shareXKeysContract, address _admin) external initializer;

Parameters

NameTypeDescription
_shareXKeysContractaddressAddress of the ShareX Keys Series ERC1155 contract
_adminaddressAddress to grant admin role to

stake

Stake tokens for rewards

function stake(uint256 tokenId, uint256 amount)
    external
    override
    nonReentrant
    whenNotPaused
    validTokenId(tokenId)
    validAmount(amount);

Parameters

NameTypeDescription
tokenIduint256Token type to stake (0=ESSENTIA, 1=MAGNA, 2=NOVA)
amountuint256Number of tokens to stake

unstake

Unstake tokens and claim rewards

function unstake(uint256 tokenId, uint256 amount)
    external
    override
    nonReentrant
    whenNotPaused
    validTokenId(tokenId)
    validAmount(amount);

Parameters

NameTypeDescription
tokenIduint256Token type to unstake (0=ESSENTIA, 1=MAGNA, 2=NOVA)
amountuint256Number of tokens to unstake

stakeAll

Stake all available tokens across all types

Gas-optimized batch operation

function stakeAll() external override nonReentrant whenNotPaused;

unstakeAll

Unstake all staked tokens across all types

Gas-optimized batch operation with reward claiming

function unstakeAll() external override nonReentrant whenNotPaused;

claimRewards

Claim accumulated rewards from all staked positions

function claimRewards() external override nonReentrant whenNotPaused;

emergencyWithdraw

Emergency withdrawal without rewards

function emergencyWithdraw(uint256 tokenId)
    external
    override
    nonReentrant
    validTokenId(tokenId);

Parameters

NameTypeDescription
tokenIduint256Token type to withdraw

burnAllTokens

Burn all tokens (staked and owned) for a specific address

Admin function to burn all tokens belonging to a user

function burnAllTokens(address account)
    external
    override
    onlyRole(DEFAULT_ADMIN_ROLE)
    nonReentrant;

Parameters

NameTypeDescription
accountaddressThe address whose tokens should be burned

updatePoolRewards

Update pool reward parameters (admin only)

function updatePoolRewards(uint256 tokenId, uint256 rewardPerBlock)
    external
    override
    onlyRole(DEFAULT_ADMIN_ROLE)
    validTokenId(tokenId);

Parameters

NameTypeDescription
tokenIduint256Token type to update
rewardPerBlockuint256New reward rate per block

pause

Pause the contract (admin only)

function pause() external onlyRole(DEFAULT_ADMIN_ROLE);

unpause

Unpause the contract (admin only)

function unpause() external onlyRole(DEFAULT_ADMIN_ROLE);

getStakingInfo

Get staking information for a user and token type

function getStakingInfo(address account, uint256 tokenId)
    external
    view
    override
    validTokenId(tokenId)
    returns (StakingInfo memory info);

Parameters

NameTypeDescription
accountaddressUser address
tokenIduint256Token type

Returns

NameTypeDescription
infoStakingInfoComplete staking information

getPoolInfo

Get pool information for a token type

function getPoolInfo(uint256 tokenId)
    external
    view
    override
    validTokenId(tokenId)
    returns (PoolInfo memory info);

Parameters

NameTypeDescription
tokenIduint256Token type

Returns

NameTypeDescription
infoPoolInfoPool configuration and statistics

getTotalPendingRewards

Get total pending rewards for a user

function getTotalPendingRewards(address account)
    external
    view
    override
    returns (uint256 totalRewards);

Parameters

NameTypeDescription
accountaddressUser address

Returns

NameTypeDescription
totalRewardsuint256Sum of pending rewards across all token types

shareXKeys

Get ShareX Keys Series contract address

function shareXKeys() external view override returns (address);

onERC1155Received

ERC1155 token receiver implementation

function onERC1155Received(address, address, uint256, uint256, bytes calldata)
    external
    pure
    override
    returns (bytes4);

onERC1155BatchReceived

ERC1155 batch token receiver implementation

function onERC1155BatchReceived(
    address,
    address,
    uint256[] calldata,
    uint256[] calldata,
    bytes calldata
) external pure override returns (bytes4);

supportsInterface

ERC165 interface support

function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(AccessControlUpgradeable, IERC165)
    returns (bool);

_updatePool

Update pool accumulated rewards

function _updatePool(uint256 tokenId) internal;

Parameters

NameTypeDescription
tokenIduint256Token type to update

_updateUserRewards

Update user reward debt

function _updateUserRewards(address account, uint256 tokenId) internal;

Parameters

NameTypeDescription
accountaddressUser address
tokenIduint256Token type

_validateStakeParameters

Internal function to validate staking parameters

function _validateStakeParameters(address to, uint256 tokenId, uint256 amount) internal view;

_calculatePendingReward

Calculate pending rewards for a user (internal state-changing)

function _calculatePendingReward(address account, uint256 tokenId)
    internal
    view
    returns (uint256);

Parameters

NameTypeDescription
accountaddressUser address
tokenIduint256Token type

Returns

NameTypeDescription
<none>uint256Pending reward amount

_calculatePendingRewardView

Calculate pending rewards for view function

function _calculatePendingRewardView(address account, uint256 tokenId)
    internal
    view
    returns (uint256);

Parameters

NameTypeDescription
accountaddressUser address
tokenIduint256Token type

Returns

NameTypeDescription
<none>uint256Pending reward amount

Structs

StakeInfo

Internal struct for user staking data

Optimized storage layout for gas efficiency

struct StakeInfo {
    uint128 stakedAmount; // Current staked amount (fits in 128 bits)
    uint128 rewardDebt; // Reward debt for calculations (fits in 128 bits)
    uint64 lastStakedTime; // Last staking timestamp (fits in 64 bits)
}

InternalPoolInfo

Internal struct for pool configuration

Optimized storage layout for gas efficiency

struct InternalPoolInfo {
    uint128 rewardPerBlock; // Rewards per block (fits in 128 bits)
    uint128 accRewardPerShare; // Accumulated reward per share (fits in 128 bits)
    uint64 lastRewardBlock; // Last reward block (fits in 64 bits)
    uint128 totalStaked; // Total staked in pool (fits in 128 bits)
}

ShareXMomentumBadge

Git Source

Inherits: ERC721Enumerable, AccessControl, IShareXMomentumBadge

Title: ShareX Momentum Badge

ERC721 badge contract to celebrate the 5th Anniversary of BNB Chain

This Badge is awarded to participants who joined ShareX activities during official #BNBDay celebrations

State Variables

MINTER_ROLE

Role for minting badges

bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE")

BURNER_ROLE

Role for burning badges

bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE")

_TOKEN_URI

Fixed metadata URI for all badges

string private constant _TOKEN_URI = "https://rwa.sharex.network/metadata/momentum-badge.json"

_currentTokenId

Current token ID counter

uint256 private _currentTokenId

Functions

constructor

Initialize the ShareX Momentum Badge contract

constructor(address admin) ERC721("ShareX Momentum Badge", "SMB");

Parameters

NameTypeDescription
adminaddressAddress to be granted admin role

mint

Mint a badge to a recipient

function mint(address to) external override onlyRole(MINTER_ROLE);

Parameters

NameTypeDescription
toaddressRecipient address

batchMint

Mint badges to multiple recipients

function batchMint(address[] calldata recipients) external override onlyRole(MINTER_ROLE);

Parameters

NameTypeDescription
recipientsaddress[]Array of recipient addresses

burn

Burn a badge

function burn(uint256 tokenId) external override;

Parameters

NameTypeDescription
tokenIduint256Token ID to burn

batchBurn

Burn multiple badges

function batchBurn(uint256[] calldata tokenIds) external override;

Parameters

NameTypeDescription
tokenIdsuint256[]Array of token IDs to burn

tokenURI

Get the metadata URI for a token

function tokenURI(uint256 tokenId)
    public
    view
    virtual
    override(ERC721, IShareXMomentumBadge)
    returns (string memory);

Parameters

NameTypeDescription
tokenIduint256Token ID

Returns

NameTypeDescription
<none>stringThe metadata URI

totalSupply

Get the total supply of badges

function totalSupply()
    public
    view
    override(ERC721Enumerable, IShareXMomentumBadge)
    returns (uint256);

Returns

NameTypeDescription
<none>uint256The total number of badges minted

supportsInterface

Check if the contract supports an interface

function supportsInterface(bytes4 interfaceId)
    public
    view
    override(ERC721Enumerable, AccessControl, IERC165)
    returns (bool);

Parameters

NameTypeDescription
interfaceIdbytes4Interface identifier

Returns

NameTypeDescription
<none>boolTrue if the interface is supported

_exists

Internal function to check if a token exists

function _exists(uint256 tokenId) internal view returns (bool);

Parameters

NameTypeDescription
tokenIduint256Token ID to check

Returns

NameTypeDescription
<none>boolTrue if the token exists

ShareXUSDT

Git Source

Inherits: ERC20, AccessControl

Title: ShareX USDT

This is a test token for development purposes only

ERC20 token for ShareX ecosystem testing on BSC testnet

State Variables

MINTER_ROLE

bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE")

DECIMALS

uint8 private constant DECIMALS = 6

MAX_SUPPLY

uint256 public constant MAX_SUPPLY = 1_000_000_000 * 10 ** DECIMALS

Functions

constructor

Constructor that gives DEFAULT_ADMIN_ROLE and MINTER_ROLE to the deployer

constructor() ERC20("ShareX USDT", "XUSDT");

decimals

Returns the number of decimals used to get its user representation

function decimals() public pure override returns (uint8);

mint

Mints tokens to a specified address

function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE);

Parameters

NameTypeDescription
toaddressThe address to mint tokens to
amountuint256The amount of tokens to mint

burn

Burns tokens from the caller's account

function burn(uint256 amount) external;

Parameters

NameTypeDescription
amountuint256The amount of tokens to burn

burnFrom

Burns tokens from a specified account (requires allowance)

function burnFrom(address from, uint256 amount) external;

Parameters

NameTypeDescription
fromaddressThe account to burn tokens from
amountuint256The amount of tokens to burn

batchMint

Batch mint tokens to multiple addresses

function batchMint(address[] calldata recipients, uint256[] calldata amounts)
    external
    onlyRole(MINTER_ROLE);

Parameters

NameTypeDescription
recipientsaddress[]Array of addresses to mint to
amountsuint256[]Array of amounts to mint

faucet

Limited to 1000 USDT per call to prevent abuse

Faucet function for testnet - allows anyone to mint small amounts for testing

function faucet() external;

Events

TokensMinted

event TokensMinted(address indexed to, uint256 amount);

TokensBurned

event TokensBurned(address indexed from, uint256 amount);

Errors

MaxSupplyExceeded

error MaxSupplyExceeded();

InvalidAmount

error InvalidAmount();

ShareXWallet

Git Source

Inherits: IShareXWallet, Ownable

Functions

constructor

constructor() payable Ownable(msg.sender);

receive

receive() external payable override;

fallback

fallback() external payable override;

batchTransfer

function batchTransfer(
    address[] calldata tokens,
    address[] calldata recipients,
    uint256[] calldata amounts
) external override onlyOwner;

mintPowerPass

function mintPowerPass(address powerPassContract, address to, string calldata tokenURI)
    external
    override
    onlyOwner
    returns (uint256 tokenId);

transferPowerPass

function transferPowerPass(address powerPassContract, address from, address to, uint256 tokenId)
    external
    override
    onlyOwner;

burnPowerPass

function burnPowerPass(address powerPassContract, uint256 tokenId) external override onlyOwner;

approvePowerPass

function approvePowerPass(address powerPassContract, address to, uint256 tokenId)
    external
    override
    onlyOwner;

setApprovalForAllPowerPass

function setApprovalForAllPowerPass(address powerPassContract, address operator, bool approved)
    external
    override
    onlyOwner;

getPowerPassBalance

function getPowerPassBalance(address powerPassContract)
    external
    view
    override
    returns (uint256 balance);

getPowerPassApproved

function getPowerPassApproved(address powerPassContract, uint256 tokenId)
    external
    view
    override
    returns (address approved);

aggregate

function aggregate(Call[] calldata calls)
    public
    payable
    override
    onlyOwner
    returns (uint256 blockNumber, bytes[] memory returnData);

withdraw

function withdraw(address payable to, uint256 amount) public override onlyOwner;

withdrawToken

function withdrawToken(address token, address to, uint256 amount) public override onlyOwner;

stakePowerPass

function stakePowerPass(address stakingContract, uint256 tokenId) external override onlyOwner;

stakePowerPassBatch

function stakePowerPassBatch(address stakingContract, uint256[] calldata tokenIds)
    external
    override
    onlyOwner;

unstakePowerPass

function unstakePowerPass(address stakingContract, uint256 tokenId)
    external
    override
    onlyOwner;

unstakePowerPassBatch

function unstakePowerPassBatch(address stakingContract, uint256[] calldata tokenIds)
    external
    override
    onlyOwner;

requestPowerPassClaim

function requestPowerPassClaim(address stakingContract, uint256 amount)
    external
    override
    onlyOwner
    returns (uint256 requestId);

claimPowerPassReward

function claimPowerPassReward(address stakingContract, uint256 requestId)
    external
    override
    onlyOwner;

claimAllApprovedPowerPassRewards

function claimAllApprovedPowerPassRewards(address stakingContract) external override onlyOwner;

ShareXWalletManager

Git Source

Inherits: IShareXWalletManager, Initializable, AccessControl

State Variables

_wallets

mapping(uint256 userId => mapping(uint256 walletId => address walletAddr)) private _wallets

_walletIndex

uint256 private _walletIndex

Functions

validUserId

modifier validUserId(uint256 userId) ;

validWalletId

modifier validWalletId(uint256 walletId) ;

onlyAdmin

modifier onlyAdmin() ;

constructor

constructor(address admin) payable;

initialize

function initialize(address admin) external override initializer;

fund

function fund() external payable override;

batchTransfer

function batchTransfer(
    uint256 userId,
    uint256 walletId,
    address[] calldata tokens,
    address[] calldata recipients,
    uint256[] calldata amounts
) external override validUserId(userId) validWalletId(walletId) onlyAdmin;

mintPowerPass

function mintPowerPass(
    uint256 userId,
    uint256 walletId,
    address powerPassContract,
    address to,
    string calldata tokenURI
)
    external
    override
    validUserId(userId)
    validWalletId(walletId)
    onlyAdmin
    returns (uint256 tokenId);

transferPowerPass

function transferPowerPass(
    uint256 userId,
    uint256 walletId,
    address powerPassContract,
    address from,
    address to,
    uint256 tokenId
) external override validUserId(userId) validWalletId(walletId) onlyAdmin;

burnPowerPass

function burnPowerPass(
    uint256 userId,
    uint256 walletId,
    address powerPassContract,
    uint256 tokenId
) external override validUserId(userId) validWalletId(walletId) onlyAdmin;

approvePowerPass

function approvePowerPass(
    uint256 userId,
    uint256 walletId,
    address powerPassContract,
    address to,
    uint256 tokenId
) external override validUserId(userId) validWalletId(walletId) onlyAdmin;

setApprovalForAllPowerPass

function setApprovalForAllPowerPass(
    uint256 userId,
    uint256 walletId,
    address powerPassContract,
    address operator,
    bool approved
) external override validUserId(userId) validWalletId(walletId) onlyAdmin;

batchApprovePowerPass

function batchApprovePowerPass(
    uint256 userId,
    uint256 walletId,
    address powerPassContract,
    uint256[] calldata tokenIds,
    address[] calldata operators
) external override validUserId(userId) validWalletId(walletId) onlyAdmin;

approveAndTransferPowerPass

function approveAndTransferPowerPass(
    uint256 fromUserId,
    uint256 fromWalletId,
    address powerPassContract,
    address to,
    uint256 tokenId
) external override validUserId(fromUserId) validWalletId(fromWalletId) onlyAdmin;

batchTransferPowerPass

function batchTransferPowerPass(
    uint256 userId,
    uint256 walletId,
    address powerPassContract,
    address[] calldata from,
    address[] calldata to,
    uint256[] calldata tokenIds
) external override validUserId(userId) validWalletId(walletId) onlyAdmin;

getPowerPassBalance

function getPowerPassBalance(uint256 userId, uint256 walletId, address powerPassContract)
    external
    view
    override
    validUserId(userId)
    validWalletId(walletId)
    returns (uint256 balance);

getPowerPassApproved

function getPowerPassApproved(
    uint256 userId,
    uint256 walletId,
    address powerPassContract,
    uint256 tokenId
)
    external
    view
    override
    validUserId(userId)
    validWalletId(walletId)
    returns (address approved);

isApprovedForAllPowerPass

function isApprovedForAllPowerPass(
    uint256 userId,
    uint256 walletId,
    address powerPassContract,
    address operator
) external view override validUserId(userId) validWalletId(walletId) returns (bool approved);

createWallet

function createWallet(uint256 userId)
    public
    override
    validUserId(userId)
    onlyAdmin
    returns (uint256 walletId, address walletAddr);

deposit

function deposit(uint256 userId, uint256 walletId, address token, uint256 amount)
    public
    payable
    override
    validUserId(userId)
    validWalletId(walletId)
    onlyAdmin;

withdraw

function withdraw(
    uint256 userId,
    uint256 walletId,
    address payable to,
    address token,
    uint256 amount
) public override validUserId(userId) validWalletId(walletId) onlyAdmin;

transfer

function transfer(
    uint256 fromUserId,
    uint256 fromWalletId,
    uint256 toUserId,
    uint256 toWalletId,
    address token,
    uint256 amount
)
    public
    override
    validUserId(fromUserId)
    validUserId(toUserId)
    validWalletId(fromWalletId)
    validWalletId(toWalletId)
    onlyAdmin;

getNativeTokenBalance

function getNativeTokenBalance(uint256 userId, uint256 walletId)
    public
    view
    override
    validUserId(userId)
    validWalletId(walletId)
    returns (uint256 nativeBalance);

getTokenBalance

function getTokenBalance(uint256 userId, uint256 walletId, address token)
    public
    view
    override
    validUserId(userId)
    validWalletId(walletId)
    returns (uint256 tokenBalance);

getWalletAddr

function getWalletAddr(uint256 userId, uint256 walletId)
    public
    view
    override
    validUserId(userId)
    validWalletId(walletId)
    returns (address);

getWalletIndex

function getWalletIndex() public view override returns (uint256);

_getWalletAddr

function _getWalletAddr(uint256 userId, uint256 walletId) private view returns (address);

stakePowerPass

function stakePowerPass(
    uint256 userId,
    uint256 walletId,
    address stakingContract,
    uint256 tokenId
) external override validUserId(userId) validWalletId(walletId) onlyAdmin;

stakePowerPassBatch

function stakePowerPassBatch(
    uint256 userId,
    uint256 walletId,
    address stakingContract,
    uint256[] calldata tokenIds
) external override validUserId(userId) validWalletId(walletId) onlyAdmin;

unstakePowerPass

function unstakePowerPass(
    uint256 userId,
    uint256 walletId,
    address stakingContract,
    uint256 tokenId
) external override validUserId(userId) validWalletId(walletId) onlyAdmin;

unstakePowerPassBatch

function unstakePowerPassBatch(
    uint256 userId,
    uint256 walletId,
    address stakingContract,
    uint256[] calldata tokenIds
) external override validUserId(userId) validWalletId(walletId) onlyAdmin;

requestPowerPassClaim

function requestPowerPassClaim(
    uint256 userId,
    uint256 walletId,
    address stakingContract,
    uint256 amount
)
    external
    override
    validUserId(userId)
    validWalletId(walletId)
    onlyAdmin
    returns (uint256 requestId);

claimPowerPassReward

function claimPowerPassReward(
    uint256 userId,
    uint256 walletId,
    address stakingContract,
    uint256 requestId
) external override validUserId(userId) validWalletId(walletId) onlyAdmin;

claimAllApprovedPowerPassRewards

function claimAllApprovedPowerPassRewards(
    uint256 userId,
    uint256 walletId,
    address stakingContract
) external override validUserId(userId) validWalletId(walletId) onlyAdmin;

directClaimPowerPassReward

function directClaimPowerPassReward(
    uint256 userId,
    uint256 walletId,
    address stakingContract,
    uint256 amount
) external override validUserId(userId) validWalletId(walletId) onlyAdmin;

Events

WalletCreated

event WalletCreated(
    uint256 indexed userId, uint256 indexed walletId, address indexed walletAddr
);

TokensDeposited

event TokensDeposited(address indexed to, uint256 indexed amount, address token);

TokensWithdrawn

event TokensWithdrawn(
    address indexed from, address indexed to, uint256 indexed amount, address token
);

TokensTransferred

event TokensTransferred(
    address indexed from, address indexed to, uint256 indexed amount, address token
);

PowerPassMinted

event PowerPassMinted(address indexed to, uint256 indexed tokenId, address powerPassContract);

PowerPassTransferred

event PowerPassTransferred(
    address indexed from, address indexed to, uint256 indexed tokenId, address powerPassContract
);

PowerPassBurned

event PowerPassBurned(uint256 indexed tokenId, address powerPassContract);