Deshare Protocol
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:
| # | Code | Keccak256 Hash |
|---|---|---|
| 1 | QAHFT | 0xc586fb63d1c6eede694002bac945e1fc93dffd2bb58ee916addf7b14ebc53005 |
| 2 | RXCKA | 0xda83a4728c99e658aa25b9019174565c757f00ab1ddb5fa25c587a8367f5682d |
| 3 | FNAFQ | 0x9d840d42aac08a8ef2551fb83db5491d83d2b1babfa2b2540402f3844c1d4fa1 |
| 4 | OFPVA | 0x4c0ddc905489d5ff324a48638cb7034d165f82aef7c86538d0913db2c2fe30d2 |
| 5 | USIEY | 0x0b0a596055a60540ef37a00515d938965e3ca609278e2387b35590f668dc4434 |
| 6 | ICCWP | 0xbad4092fdc31d6e358f15bd4da34d67b0266eab4cf9749008dadcac56c160bbe |
| 7 | USNZJ | 0x80130976afa8b115b22dae9f3122248e84806b3c8b65c6637a90e0ea0157fc4f |
| 8 | OVQWP | 0x83c49292403faf660a2d1ca7ac696f72c94958324ad6a389e09ba910d5fa2586 |
| 9 | SBFHC | 0xa7640a297eaa636ab8864b56800d221207008f6bceb3d7915650e15a85c86720 |
| 10 | GCHQJ | 0xe6f44e784405546578b03c652654c1f7c27ff7781f8f2c08edfec70b78f03e03 |
| 11 | JFGYQ | 0xfeb647b6cef20e8a742702a0667f50fc0ca65971d679fb28b1ebb63bc669b14a |
| 12 | PESEJ | 0x37ad281a3597a41957fc2d4a2878392f2cb75ae07e2b1945bbe02d885c4ac1a3 |
| 13 | ZQORV | 0xfc3d350f702796b652699a7e5edae75fb0cbca6868d91c1de24cc7ba2496dd7f |
| 14 | UFAIG | 0xa7555d840a22bfecbd6dc1868182cbe52940501667319e7328388f5a20c318a8 |
| 15 | FYWIR | 0x915ee928322569b80fdcd85e200de2a88d08bb2ab4637380fe58199641844199 |
| 16 | KXLGG | 0x05e5849e61f4a1374283123dae6bdd9fd594c1e9f3a0714bcadde1d4e7f390c2 |
| 17 | OGPXK | 0x71d2db0ec70669a052c3a80dacc2bfd02cb285d90e320d93a5a4ec8294e4796b |
| 18 | FZNCB | 0xd9eaa46f1629ada38b47e110ccd027fd5b32deb4c3bddf34479fb5b8d4dfc605 |
| 19 | CQUKB | 0xf1130c4946f2b15f872eda6003028a464c3cd78bf621b0cc671c6e1136524cb2 |
| 20 | JZNZW | 0xdadad1a5d5550d72260f7c7ae168b82e73b254e6d4af7a3bbbd1d2ba38be53f4 |
| 21 | SHARE | 0x6ecee827156c952a04f57a0610c4ec267270d7865b010b3163aa1d3657d9a421 |
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
| Scenario | Price per NFT | Total for 2 NFTs | Savings |
|---|---|---|---|
| Standard | 50 USDT | 100 USDT | 0 USDT |
| Nova Discount | 40 USDT | 80 USDT | 20 USDT |
| Discount Code | 45 USDT | 90 USDT | 10 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 managementOPERATOR_ROLE: Day-to-day protocol operations and entity registration
PowerPass Roles
DEFAULT_ADMIN_ROLE: PowerPass administration and token URI managementMINTER_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
Modular Deployment Commands (Recommended)
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)
| Contract | Address | BSCScan Link |
|---|---|---|
| Deshare (Implementation) | 0x09D3E9d08348b22AB5E03158Dc1927da4646EB79 | View on BSCScan |
| DeshareProxy (Main Contract) | 0x23E89f8aC6e7751095fD5DbC71B89Bd1C60f23C7 | View on BSCScan |
| PowerPass (Implementation) | 0x40635E6f3D1F4f3311E0Bc892A4Ee38fD7fd4ce3 | View on BSCScan |
| PowerPassProxy (Main Contract) | 0x3d3624D578bf7bF81a76633a355320B3123c70f7 | View on BSCScan |
| PowerPassProxyAdmin | 0x734b8EbAe5992d4795D6b919aAfFA17Edd1ED099 | View on BSCScan |
| PowerPassStaking (Implementation) | 0xcDA6366b624D4Fe52f25469912E3c788F0D19024 | View on BSCScan |
| PowerPassStakingProxy (Main Contract) | 0x5560e8CD017D2BD8474601D682731a807a66654B | View on BSCScan |
| PowerPassStakingProxyAdmin | 0x2c56854aaf4d483b85f0580dad5ae4eec8fc4148 | View on BSCScan |
| ShareXUSDT (Test Token) | 0x6350a32a4406469608B5D93A77572e140b5F3D73 | View on BSCScan |
| ShareXWalletManager (Implementation) | 0x0e0517EF0c011757Ea71FeeB2766481F440bB3Dd | View on BSCScan |
| ShareXWalletManagerProxy (Main Contract) | 0x5dC5Fdb90E57A5390c6524414f3d6da0b3Ef0f48 | View on BSCScan |
| ShareXWalletManagerProxyAdmin | 0xe86657f17b8d155b06cba4481bd3391be9d2886f | View on BSCScan |
| ShareXKeysSeries (ERC1155 NFT) | 0x5F8044C7Acf488C359EB1c8afDfc4e57c8E1733a | View on BSCScan |
| ShareXKeysStaking (Implementation) | 0x5e2a4C4D0fe6b1aa871bB7EBfeA54ea6f0439850 | View on BSCScan |
| ShareXKeysStakingProxy (Main Contract) | 0xfCb95edFBEB8e47492558c6E36db7B8F6766D220 | View on BSCScan |
| ProxyAdmin | 0x606ad7a222bdcc5a43a1927794c29122d708e289 | View 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)
| Contract | Address | BSCScan Link |
|---|---|---|
| PowerPass (Implementation) | 0x4a0A3da46f0adF8491F9134f2FaeA880115C4949 | View on BSCScan |
| PowerPassProxy (Main Contract) | 0xdF9A38E920902022eF54B5F05bD28C8ca4eFD961 | View on BSCScan |
| PowerPassProxyAdmin | 0xed4c0d0c1815c5ed4e03487655e8550bcac244ca | View on BSCScan |
| ShareXWalletManager (Implementation) | 0x517D18cE441D8B249eB40b6dc363Df13B8D01451 | View on BSCScan |
| ShareXWalletManagerProxy (Main Contract) | 0x371c05B0CC9B6Fc3794A911DdD2DfbB266db5b38 | View on BSCScan |
| ShareXWalletManagerProxyAdmin | 0x4cdb3d86e876c714f691021418e62bd3e7b18210 | View on BSCScan |
| ShareXKeysSeries (ERC1155 NFT) | 0x28e3889A3bc57D4421a5041E85Df8b516Ab683F8 | View on BSCScan |
| ShareXKeysStaking (Implementation) | 0x75a487bE463431F96765f2007e45b9C9bA3BED38 | View on BSCScan |
| ShareXKeysStakingProxy (Main Contract) | 0xC7e54532ea427b7Bcf682dc0BEF24CD1338b3026 | View on BSCScan |
| ShareXMomentumBadge (ERC721 NFT) | 0x7184dCdFEBEE6D3910782FBEEE5Ea1470692eb21 | View on BSCScan |
| ProxyAdmin (Keys) | 0x84D27c82B5191E8CdDE5772d42657A39e55333C3 | View 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)
| Contract | Address | opBNBScan Link |
|---|---|---|
| Deshare (Implementation) | 0xD81B9c15dE92D9A5e373d3E0817B648987079c37 | View on opBNBScan |
| DeshareProxy (Main Contract) | 0x28e3889A3bc57D4421a5041E85Df8b516Ab683F8 | View on opBNBScan |
| ProxyAdmin | 0xdfd3c8bf6dad595293ecdce4c0e1b485f072119a | View 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:
- Visit Verification Page: opBNBScan Contract Verification
- Enter Contract Details:
- Contract Address:
0xD81B9c15dE92D9A5e373d3E0817B648987079c37 - Compiler Type: Solidity (Single file) or Standard JSON Input
- Contract Address:
- Compiler Settings:
- Compiler Version: 0.8.24
- Optimization: Yes (999999 runs)
- EVM Version: Paris
- Constructor Arguments:
0x0000000000000000000000003047db262c4e142b2c7927bb7df5cC86A0f6EE78 - 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 .envto load environment variables before deployment - Private Key Format: Use raw private key without
0xprefix in.envfile - 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
- Fork the repository and create a feature branch
- Write comprehensive tests for new functionality
- Ensure all tests pass (
make foundry-test) - Follow Solidity coding standards and security best practices
- Update documentation and examples as needed
- 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
- IPowerPass
- IPowerPassStaking
- IShareXKeysSeries
- IShareXKeysStaking
- IShareXMomentumBadge
- IShareXWallet
- IShareXWalletManager
IDeshare
Title: IDeshare
Interface for the Deshare contract
Functions
registerPartner
Register a new partner
function registerPartner(PartnerParams calldata params) external;
Parameters
| Name | Type | Description |
|---|---|---|
params | PartnerParams | Partner registration parameters |
registerMerchant
Register a new merchant
function registerMerchant(MerchantParams calldata params) external;
Parameters
| Name | Type | Description |
|---|---|---|
params | MerchantParams | Merchant registration parameters |
registerDevice
Register a new device
function registerDevice(DeviceParams calldata params) external;
Parameters
| Name | Type | Description |
|---|---|---|
params | DeviceParams | Device registration parameters |
uploadTransactionBatch
Upload a transaction batch
function uploadTransactionBatch(UploadBatchParams calldata params) external;
Parameters
| Name | Type | Description |
|---|---|---|
params | UploadBatchParams | Upload batch parameters |
registerCountry
Register a country
function registerCountry(bytes2 iso2) external;
Parameters
| Name | Type | Description |
|---|---|---|
iso2 | bytes2 | The ISO2 country code |
getVersion
Get the contract version
function getVersion() external view returns (Version memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | Version | version The current version |
getStats
Get statistics information
function getStats() external view returns (StatsInfo memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | StatsInfo | stats The current statistics |
getDetailedStats
Get detailed statistics information with descriptive labels
function getDetailedStats() external view returns (DetailedStatsInfo memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | DetailedStatsInfo | detailedStats The detailed statistics with labels and metadata |
getPartner
Get partner information by ID
function getPartner(uint256 partnerId) external view returns (PartnerInfo memory);
Parameters
| Name | Type | Description |
|---|---|---|
partnerId | uint256 | The partner ID |
Returns
| Name | Type | Description |
|---|---|---|
<none> | PartnerInfo | partner The partner information |
getPartnerByCode
Get partner information by partner code
function getPartnerByCode(string calldata partnerCode)
external
view
returns (PartnerInfo memory);
Parameters
| Name | Type | Description |
|---|---|---|
partnerCode | string | The partner code |
Returns
| Name | Type | Description |
|---|---|---|
<none> | PartnerInfo | partner The partner information |
partnerExists
Check if a partner exists by code
function partnerExists(string calldata partnerCode) external view returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
partnerCode | string | The partner code |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | exists Whether the partner exists |
getMerchant
Get merchant information by ID
function getMerchant(uint256 merchantId) external view returns (MerchantInfo memory);
Parameters
| Name | Type | Description |
|---|---|---|
merchantId | uint256 | The merchant ID |
Returns
| Name | Type | Description |
|---|---|---|
<none> | MerchantInfo | merchant The merchant information |
getMerchantById
Get merchant information by merchant ID
function getMerchantById(string calldata merchantId) external view returns (MerchantInfo memory);
Parameters
| Name | Type | Description |
|---|---|---|
merchantId | string | The merchant ID (string) |
Returns
| Name | Type | Description |
|---|---|---|
<none> | MerchantInfo | merchant The merchant information |
merchantExists
Check if a merchant exists by ID
function merchantExists(string calldata merchantId) external view returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
merchantId | string | The merchant ID |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | exists Whether the merchant exists |
getDevice
Get device information by ID
function getDevice(uint256 deviceId) external view returns (DeviceInfo memory);
Parameters
| Name | Type | Description |
|---|---|---|
deviceId | uint256 | The device ID |
Returns
| Name | Type | Description |
|---|---|---|
<none> | DeviceInfo | device The device information |
getDeviceById
Get device information by device ID
function getDeviceById(string calldata deviceId) external view returns (DeviceInfo memory);
Parameters
| Name | Type | Description |
|---|---|---|
deviceId | string | The device ID (string) |
Returns
| Name | Type | Description |
|---|---|---|
<none> | DeviceInfo | device The device information |
deviceExists
Check if a device exists by ID
function deviceExists(string calldata deviceId) external view returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
deviceId | string | The device ID |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | exists Whether the device exists |
getTransactionBatch
Get transaction batch by ID
function getTransactionBatch(uint256 batchId) external view returns (TransactionBatch memory);
Parameters
| Name | Type | Description |
|---|---|---|
batchId | uint256 | The batch ID |
Returns
| Name | Type | Description |
|---|---|---|
<none> | TransactionBatch | batch The transaction batch |
getCountry
Get country information
function getCountry(bytes2 iso2) external view returns (CountryInfo memory);
Parameters
| Name | Type | Description |
|---|---|---|
iso2 | bytes2 | The ISO2 country code |
Returns
| Name | Type | Description |
|---|---|---|
<none> | CountryInfo | country The country information |
countryExists
Check if a country is registered
function countryExists(bytes2 iso2) external view returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
iso2 | bytes2 | The ISO2 country code |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | exists 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
| Name | Type | Description |
|---|---|---|
businessType | string | The business type to query |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The 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
| Name | Type | Description |
|---|---|---|
iso2 | bytes2 | The ISO2 country code |
locationId | string | The location ID (e.g., city identifier) |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The count of merchants |
getTransactionData
Retrieves transaction data for a batch
function getTransactionData(uint256 batchId) external view returns (string memory jsonData);
Parameters
| Name | Type | Description |
|---|---|---|
batchId | uint256 | The batch ID to retrieve data for |
Returns
| Name | Type | Description |
|---|---|---|
jsonData | string | The transaction data as JSON string |
IPowerPass
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
| Name | Type | Description |
|---|---|---|
config | SalesConfig | Sales configuration including timestamps and pricing |
supplyLimit | uint256 | Maximum 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
| Name | Type | Description |
|---|---|---|
amount | uint256 | Number of NFTs to mint |
discountCode | string | Optional 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
| Name | Type | Description |
|---|---|---|
accounts | address[] | Array of addresses to set allocations for |
priorityAmounts | uint256[] | Array of priority allocations corresponding to accounts |
generalAmounts | uint256[] | 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
| Name | Type | Description |
|---|---|---|
accounts | address[] | Array of addresses to configure |
discountAllocations | uint256[] | 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
| Name | Type | Description |
|---|---|---|
accounts | address[] | Custodial wallet addresses (ShareX wallet addresses or end-user custodial addrs) |
allocations | uint256[] | 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
| Name | Type | Description |
|---|---|---|
baseURI | string | The 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
| Name | Type | Description |
|---|---|---|
token | address | ERC20 token address used for payments |
setDiscountCodeDiscount
Set global discount amount applied when using a valid code
function setDiscountCodeDiscount(uint256 discountAmount) external;
Parameters
| Name | Type | Description |
|---|---|---|
discountAmount | uint256 | Amount 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
| Name | Type | Description |
|---|---|---|
codeHashes | bytes32[] | Array of keccak256 hashes of discount codes |
removeDiscountCodes
Remove discount code hashes
function removeDiscountCodes(bytes32[] calldata codeHashes) external;
Parameters
| Name | Type | Description |
|---|---|---|
codeHashes | bytes32[] | 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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The 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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The ID of the token to update |
newTokenURI | string | The 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
| Name | Type | Description |
|---|---|---|
account | address | The address to query mint status for |
Returns
| Name | Type | Description |
|---|---|---|
status | MintStatus | Complete 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
| Name | Type | Description |
|---|---|---|
account | address | The address to query allocations for |
Returns
| Name | Type | Description |
|---|---|---|
info | WhitelistInfo | Complete 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
| Name | Type | Description |
|---|---|---|
config | SalesConfig | Complete 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
| Name | Type | Description |
|---|---|---|
roundId | uint64 | Current 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
| Name | Type | Description |
|---|---|---|
info | RoundInfo | RoundInfo 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
| Name | Type | Description |
|---|---|---|
roundId | uint64 | Round ID to query |
Returns
| Name | Type | Description |
|---|---|---|
config | SalesConfig | Sales configuration for the round |
supplyLimit | uint256 | Maximum NFTs for the round |
mintedCount | uint256 | NFTs 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
| Name | Type | Description |
|---|---|---|
roundId | uint64 | Round ID to query |
account | address | User address to query |
Returns
| Name | Type | Description |
|---|---|---|
info | WhitelistInfo | WhitelistInfo 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
| Name | Type | Description |
|---|---|---|
totalSupply | uint256 | Current 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
| Name | Type | Description |
|---|---|---|
maxSupply | uint256 | Maximum 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
| Name | Type | Description |
|---|---|---|
codeHash | bytes32 | keccak256 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
| Name | Type | Description |
|---|---|---|
codeHash | bytes32 | keccak256 hash of the discount code |
Returns
| Name | Type | Description |
|---|---|---|
usageCount | uint256 | Number 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
| Name | Type | Description |
|---|---|---|
newTokenId | uint256 | The 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
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The 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
| Name | Type | Description |
|---|---|---|
priorityStartTime | uint128 | Priority round start timestamp (UTC+8) |
priorityEndTime | uint128 | Priority round end timestamp (UTC+8) |
generalStartTime | uint128 | General round start timestamp (UTC+8) |
generalEndTime | uint128 | General round end timestamp (UTC+8) |
standardPrice | uint128 | Price per NFT in payment token smallest units |
discountCodeDiscount | uint128 | Discount 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
| Name | Type | Description |
|---|---|---|
priorityAllocation | uint64 | Total NFTs allocated for priority round |
generalAllocation | uint64 | Total NFTs allocated for general round |
priorityMinted | uint64 | Already minted in priority round |
generalMinted | uint64 | Already minted in general round |
novaDiscountAllocation | uint64 | Allocation eligible for Nova 80% pricing |
novaDiscountMinted | uint64 | NFTs 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
| Name | Type | Description |
|---|---|---|
priorityRemaining | uint256 | Remaining priority round allocation |
generalRemaining | uint256 | Remaining general round allocation (total cap) |
novaDiscountRemaining | uint256 | Remaining Nova discount allocation |
standardPrice | uint256 | Standard price based on active round |
novaDiscountPrice | uint256 | Discounted price for Nova addresses when discount allocation remains |
discountCodeDiscount | uint256 | Discount amount applied per NFT when redeeming a code |
isPriorityActive | bool | Whether priority round is currently active |
isGeneralActive | bool | Whether general round is currently active |
hasNovaDiscount | bool | Whether user has remaining Nova discount allocation |
RoundInfo
Round information for queries
struct RoundInfo {
uint64 roundId;
uint256 supplyLimit;
uint256 mintedCount;
uint256 remaining;
}
Properties
| Name | Type | Description |
|---|---|---|
roundId | uint64 | Current round ID |
supplyLimit | uint256 | Max NFTs for this round (0 = unlimited) |
mintedCount | uint256 | NFTs minted in this round |
remaining | uint256 | NFTs remaining in this round |
IPowerPassStaking
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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | NFT token ID to stake |
stakeBatch
Stake multiple PowerPass NFTs
function stakeBatch(uint256[] calldata tokenIds) external;
Parameters
| Name | Type | Description |
|---|---|---|
tokenIds | uint256[] | Array of NFT token IDs to stake |
unstake
Unstake a single PowerPass NFT
function unstake(uint256 tokenId) external;
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | NFT token ID to unstake |
unstakeBatch
Unstake multiple PowerPass NFTs
function unstakeBatch(uint256[] calldata tokenIds) external;
Parameters
| Name | Type | Description |
|---|---|---|
tokenIds | uint256[] | Array of NFT token IDs to unstake |
requestClaim
Request to claim rewards
function requestClaim(uint256 amount) external returns (uint256 requestId);
Parameters
| Name | Type | Description |
|---|---|---|
amount | uint256 | Amount to claim (must be <= claimable amount) |
Returns
| Name | Type | Description |
|---|---|---|
requestId | uint256 | The ID of the created claim request |
claimRewards
Claim rewards for an approved request
function claimRewards(uint256 requestId) external;
Parameters
| Name | Type | Description |
|---|---|---|
requestId | uint256 | The request ID to claim |
claimAllApprovedRewards
Claim all approved rewards
function claimAllApprovedRewards() external;
approveClaim
Approve a claim request
function approveClaim(uint256 requestId) external;
Parameters
| Name | Type | Description |
|---|---|---|
requestId | uint256 | The request ID to approve |
rejectClaim
Reject a claim request
function rejectClaim(uint256 requestId) external;
Parameters
| Name | Type | Description |
|---|---|---|
requestId | uint256 | The request ID to reject |
batchApproveClaims
Batch approve claim requests
function batchApproveClaims(uint256[] calldata requestIds) external;
Parameters
| Name | Type | Description |
|---|---|---|
requestIds | uint256[] | Array of request IDs to approve |
batchRejectClaims
Batch reject claim requests
function batchRejectClaims(uint256[] calldata requestIds) external;
Parameters
| Name | Type | Description |
|---|---|---|
requestIds | uint256[] | 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
| Name | Type | Description |
|---|---|---|
amount | uint256 | Amount to claim |
uploadOrders
Upload order information by NFT token ID
function uploadOrders(uint256[] calldata tokenIds, OrderInfo[][] calldata orders) external;
Parameters
| Name | Type | Description |
|---|---|---|
tokenIds | uint256[] | Array of NFT token IDs |
orders | OrderInfo[][] | Array of order arrays per token |
setRewardPercentage
Set reward percentage in basis points
function setRewardPercentage(uint256 rewardBps) external;
Parameters
| Name | Type | Description |
|---|---|---|
rewardBps | uint256 | New reward percentage (e.g. 2500 = 25%) |
setPaymentToken
Set payment token for rewards
function setPaymentToken(address token) external;
Parameters
| Name | Type | Description |
|---|---|---|
token | address | New payment token address |
withdrawExcessRewards
Withdraw excess reward tokens
function withdrawExcessRewards(uint256 amount) external;
Parameters
| Name | Type | Description |
|---|---|---|
amount | uint256 | Amount to withdraw |
emergencyWithdrawNFT
Emergency withdraw NFT to specified address
function emergencyWithdrawNFT(uint256 tokenId, address to) external;
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | NFT token ID to withdraw |
to | address | Recipient address |
getStakingInfo
Get staking information for an NFT
function getStakingInfo(uint256 tokenId) external view returns (StakingInfo memory);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | NFT token ID |
getUserTotalRewards
Get user's total rewards across all their NFTs
function getUserTotalRewards(address user) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
user | address | User address |
getClaimableAmount
Get user's claimable amount (available to request)
function getClaimableAmount(address user) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
user | address | User address |
getUserRewardsSummary
Get comprehensive rewards summary for a user
function getUserRewardsSummary(address user) external view returns (UserRewardsSummary memory);
Parameters
| Name | Type | Description |
|---|---|---|
user | address | User address |
getUserClaimInfo
Get user's claim tracking info
function getUserClaimInfo(address user) external view returns (UserClaimInfo memory);
Parameters
| Name | Type | Description |
|---|---|---|
user | address | User address |
getUserActiveRequests
Get user's active claim requests (Pending + Approved)
function getUserActiveRequests(address user) external view returns (ClaimRequest[] memory);
Parameters
| Name | Type | Description |
|---|---|---|
user | address | User address |
getClaimRequest
Get a specific claim request
function getClaimRequest(uint256 requestId) external view returns (ClaimRequest memory);
Parameters
| Name | Type | Description |
|---|---|---|
requestId | uint256 | Request 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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | NFT token ID |
getStaker
Get current staker or claimant of an NFT
function getStaker(uint256 tokenId) external view returns (address);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | NFT 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
| Name | Type | Description |
|---|---|---|
user | address | User 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
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
| Name | Type | Description |
|---|---|---|
account | address | The address to set allocations for |
essentiaAmount | uint256 | Number of ESSENTIA tokens to allocate |
magnaAmount | uint256 | Number of MAGNA tokens to allocate |
novaAmount | uint256 | Number 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
| Name | Type | Description |
|---|---|---|
accounts | address[] | Array of addresses to set allocations for |
essentiaAmounts | uint256[] | Array of ESSENTIA allocations corresponding to accounts |
magnaAmounts | uint256[] | Array of MAGNA allocations corresponding to accounts |
novaAmounts | uint256[] | 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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The token type to mint (0=ESSENTIA, 1=MAGNA, 2=NOVA) |
amount | uint256 | Number 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
| Name | Type | Description |
|---|---|---|
account | address | The address to query status for |
Returns
| Name | Type | Description |
|---|---|---|
essentia | MintStatus | Mint status for ESSENTIA tokens (ID: 0) |
magna | MintStatus | Mint status for MAGNA tokens (ID: 1) |
nova | MintStatus | Mint 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
| Name | Type | Description |
|---|---|---|
account | address | The address to query allocations for |
Returns
| Name | Type | Description |
|---|---|---|
essentiaAmount | uint256 | Total ESSENTIA tokens allocated |
magnaAmount | uint256 | Total MAGNA tokens allocated |
novaAmount | uint256 | Total 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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The token type to set URI for (0=ESSENTIA, 1=MAGNA, 2=NOVA) |
tokenURI | string | The 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
| Name | Type | Description |
|---|---|---|
whitelisted | uint256 | Total tokens allocated to the account |
minted | uint256 | Total tokens already minted by the account |
remaining | uint256 | Tokens remaining to be minted (whitelisted - minted) |
IShareXKeysStaking
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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The token type to stake (0=ESSENTIA, 1=MAGNA, 2=NOVA) |
amount | uint256 | Number 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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The token type to unstake (0=ESSENTIA, 1=MAGNA, 2=NOVA) |
amount | uint256 | Number 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
| Name | Type | Description |
|---|---|---|
account | address | The address to query staking information for |
tokenId | uint256 | The token type to query (0=ESSENTIA, 1=MAGNA, 2=NOVA) |
Returns
| Name | Type | Description |
|---|---|---|
info | StakingInfo | Complete 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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The token type to query (0=ESSENTIA, 1=MAGNA, 2=NOVA) |
Returns
| Name | Type | Description |
|---|---|---|
info | PoolInfo | Complete 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
| Name | Type | Description |
|---|---|---|
account | address | The address to calculate total pending rewards for |
Returns
| Name | Type | Description |
|---|---|---|
totalRewards | uint256 | Sum 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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The token type to configure (0=ESSENTIA, 1=MAGNA, 2=NOVA) |
rewardPerBlock | uint256 | New 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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The 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
| Name | Type | Description |
|---|---|---|
account | address | The 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
| Name | Type | Description |
|---|---|---|
shareXKeys | address | Address 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
| Name | Type | Description |
|---|---|---|
stakedAmount | uint256 | Current amount of tokens staked by the user |
rewardDebt | uint256 | Accumulated reward debt used for reward calculation precision |
lastStakedTime | uint256 | Timestamp of the user's last staking action |
pendingRewards | uint256 | Currently 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
| Name | Type | Description |
|---|---|---|
rewardPerBlock | uint128 | Rewards distributed per block for this token type |
accRewardPerShare | uint128 | Accumulated rewards per share (scaled by precision factor) |
lastRewardBlock | uint64 | Block number when rewards were last calculated |
totalStaked | uint128 | Total amount of tokens currently staked in this pool |
IShareXMomentumBadge
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
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
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
- Version
- CountryInfo
- PartnerInfo
- MerchantInfo
- DeviceInfo
- TransactionBatch
- StatsInfo
- DetailedStatsInfo
- PartnerParams
- MerchantParams
- DeviceParams
- UploadBatchParams
- PackedCounters
- PowerPassSalesConfig
- PowerPassRoundConfig
- PowerPassWhitelistInfo
- PowerPassMintStatus
- PowerPassCustodialWhitelistInfo
- EntityAlreadyExists
- EntityNotFound
- InvalidAdminAddress
- EmptyTransactionData
- TooManyTransactions
- OrderCountMismatch
- InvalidStringLength
- PowerPassMaxSupplyExceeded
- PowerPassTokenNotFound
- PowerPassNotOwnerOrApproved
- PowerPassNoActiveSalesRound
- PowerPassInvalidSalesConfig
- PowerPassInsufficientPayment
- PowerPassExceedsAllocation
- PowerPassNoWhitelistAllocation
- PowerPassInvalidTimestamp
- PowerPassSnapshotNotTaken
- PowerPassZeroAddress
- PowerPassInvalidArrayLength
- PowerPassInvalidAmount
- PowerPassStakingContractNotSet
- PowerPassWithdrawFailed
- PowerPassPaymentTokenNotSet
- PowerPassNativePaymentNotSupported
- PowerPassInvalidDiscountAmount
- PowerPassDiscountCodeInvalid
- PowerPassDiscountCodeAlreadyExists
- PowerPassCustodialNotWhitelisted
- PowerPassCustodialExceedsAllocation
- PowerPassNoActiveRound
- PowerPassRoundLimitExceeded
- ShareXWalletInvalidUserId
- ShareXWalletInvalidWalletId
- ShareXWalletInvalidArrayLength
- ShareXWalletCallFailed
- ShareXWalletWithdrawFailed
- ShareXWalletTransferFailed
- ShareXWalletMintFailed
- ShareXWalletBurnFailed
- ShareXWalletNoRoleToCreateWallet
- ShareXWalletWalletNotFound
- ShareXWalletInvalidAdminAddress
- ShareXWalletPowerPassApprovalFailed
- ShareXWalletPowerPassNotOwned
- ShareXWalletPowerPassBatchOperationFailed
- ShareXWalletStakeFailed
- ShareXWalletUnstakeFailed
- ShareXWalletClaimRewardsFailed
- ShareXKeysInvalidTokenId
- ShareXKeysNoWhitelistAllocation
- ShareXKeysInvalidArrayLength
- ShareXKeysZeroAddress
- ShareXKeysInvalidAmount
- ShareXKeysExceedsAllocation
- ShareXKeysNoTokensToMint
- ShareXStakingZeroAddress
- ShareXStakingInvalidTokenId
- ShareXStakingInvalidAmount
- ShareXStakingInsufficientBalance
- ShareXStakingInsufficientStake
- ShareXStakingNoTokensToStake
- ShareXStakingNoTokensToUnstake
- ShareXStakingInvalidShareXKeysContract
- ShareXStakingInvalidArrayLength
- ShareXStakingRewardCalculationFailed
- ShareXStakingNoTokensToBurn
- ShareXKeysStakingZeroAddress
- ShareXKeysStakingInvalidTokenContract
- ShareXKeysStakingInvalidAmount
- ShareXKeysStakingNoNFTToStake
- ShareXKeysStakingNFTNotStaked
- ShareXKeysStakingUnauthorizedCaller
- ShareXKeysStakingInvalidBalance
- ShareXKeysStakingNoRewardsToHarvest
- ShareXMomentumBadgeZeroAddress
- ShareXMomentumBadgeInvalidArrayLength
- ShareXMomentumBadgeTokenNotExists
- ShareXMomentumBadgeUnauthorizedBurn
- PowerPassStakingZeroAddress
- PowerPassStakingInvalidArrayLength
- PowerPassStakingNotOwner
- PowerPassStakingAlreadyStaked
- PowerPassStakingNotStaked
- PowerPassStakingUnauthorized
- PowerPassStakingOrderAlreadyProcessed
- PowerPassStakingInvalidRewardPercentage
- PowerPassStakingInsufficientBalance
- PowerPassStakingPaymentTokenNotSet
- PowerPassStakingWithdrawFailed
- PowerPassStakingTransferFailed
- PowerPassStakingClaimAmountExceedsClaimable
- PowerPassStakingRequestNotFound
- PowerPassStakingRequestNotPending
- PowerPassStakingRequestNotApproved
- PowerPassStakingNotRequestOwner
- PowerPassStakingZeroClaimAmount
- PowerPassStakingNoApprovedRequests
- PartnerRegistered
- MerchantRegistered
- DeviceRegistered
- TransactionBatchUploaded
- TransactionDataUploaded
- ContractInitialized
- CountryRegistered
- PowerPassMinted
- PowerPassBurned
- PowerPassSalesConfigUpdated
- PowerPassNewRoundStarted
- PowerPassBatchMinted
- PowerPassBatchWhitelistSet
- PowerPassNovaDiscountsSet
- PowerPassBaseURIUpdated
- PowerPassFundsWithdrawn
- PowerPassDiscountCodeDiscountUpdated
- PowerPassDiscountCodesAdded
- PowerPassDiscountCodesRemoved
- PowerPassCustodialWhitelistsSet
- PowerPassInitialized
- PowerPassApprovalSet
- PowerPassApprovalForAllSet
- PowerPassBatchApproved
- PowerPassBatchTransferred
- PowerPassStakedViaWallet
- PowerPassBatchStakedViaWallet
- PowerPassUnstakedViaWallet
- PowerPassBatchUnstakedViaWallet
- PowerPassRewardsClaimedViaWallet
- PowerPassAllRewardsClaimedViaWallet
- PowerPassClaimRequestedViaWallet
- PowerPassRewardClaimedViaWallet
- ShareXKeysWhitelistsSet
- ShareXKeysBatchWhitelistsSet
- ShareXKeysMinted
- ShareXKeysBatchMinted
- ShareXKeysInitialized
- ShareXStakingInitialized
- ShareXStakingStaked
- ShareXStakingUnstaked
- ShareXStakingBatchStaked
- ShareXStakingBatchUnstaked
- ShareXStakingRewardsClaimed
- ShareXStakingPoolUpdated
- ShareXStakingEmergencyWithdrawal
- ShareXStakingTokensBurned
- ShareXMomentumBadgeInitialized
- ShareXMomentumBadgeMinted
- ShareXMomentumBadgeBatchMinted
- ShareXMomentumBadgeBurned
- ShareXMomentumBadgeBatchBurned
- PowerPassStakingInitialized
- PowerPassStakingStaked
- PowerPassStakingBatchStaked
- PowerPassStakingUnstaked
- PowerPassStakingBatchUnstaked
- PowerPassStakingOrdersUploaded
- PowerPassStakingRewardPercentageUpdated
- PowerPassStakingPaymentTokenUpdated
- PowerPassStakingRewardsWithdrawn
- PowerPassStakingEmergencyNFTWithdrawn
- PowerPassStakingOrderRewardRecorded
- PowerPassStakingClaimRequested
- PowerPassStakingClaimApproved
- PowerPassStakingClaimRejected
- PowerPassStakingRewardsClaimed
- PowerPassStakingAllApprovedRewardsClaimed
- PowerPassStakingBatchClaimsApproved
- PowerPassStakingBatchClaimsRejected
- PowerPassDiscountCodeUsed
- PowerPassStakingDirectClaimed
- PowerPassDirectClaimSettledViaWallet
Constants
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
Version information structure
struct Version {
uint8 major;
uint8 minor;
uint8 patch;
}
CountryInfo
Country information structure
struct CountryInfo {
bytes2 iso2; // ISO2 country code
uint32 timestamp; // Registration timestamp
}
PartnerInfo
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
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
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
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
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
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
Parameters structure for registering a partner
struct PartnerParams {
string partnerCode;
string partnerName;
bytes2 iso2;
string verification;
string description;
string businessType;
}
MerchantParams
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
Parameters structure for registering a device
struct DeviceParams {
string deviceId;
string deviceType;
string partnerCode;
string merchantId;
}
UploadBatchParams
Parameters structure for uploading a transaction batch
struct UploadBatchParams {
string deviceId;
string dateComparable;
uint32 orderCount;
string totalAmount;
bytes transactionData;
}
PackedCounters
Packed counters for efficiency
struct PackedCounters {
uint64 partnerCounter;
uint64 merchantCounter;
uint64 deviceCounter;
uint64 batchCounter;
uint64 countriesCounter;
}
PowerPassSalesConfig
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
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
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
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
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
Entity already exists
error EntityAlreadyExists(string entityType, bytes32 entityId);
EntityNotFound
Entity not found
error EntityNotFound(string entityType, bytes32 entityId);
InvalidAdminAddress
Invalid admin address
error InvalidAdminAddress();
EmptyTransactionData
Empty transaction data
error EmptyTransactionData();
TooManyTransactions
Too many transactions
error TooManyTransactions();
OrderCountMismatch
Order count mismatch
error OrderCountMismatch();
InvalidStringLength
Invalid string length
error InvalidStringLength(string field, uint256 maxLength);
PowerPassMaxSupplyExceeded
PowerPass maximum supply exceeded
error PowerPassMaxSupplyExceeded();
PowerPassTokenNotFound
PowerPass token not found
error PowerPassTokenNotFound();
PowerPassNotOwnerOrApproved
Not owner or approved for PowerPass token
error PowerPassNotOwnerOrApproved();
PowerPassNoActiveSalesRound
PowerPass whitelist and sales round errors
error PowerPassNoActiveSalesRound();
PowerPassInvalidSalesConfig
error PowerPassInvalidSalesConfig();
PowerPassInsufficientPayment
error PowerPassInsufficientPayment(uint256 required, uint256 provided);
PowerPassExceedsAllocation
error PowerPassExceedsAllocation(address account, uint256 requested, uint256 remaining);
PowerPassNoWhitelistAllocation
error PowerPassNoWhitelistAllocation(address account);
PowerPassInvalidTimestamp
error PowerPassInvalidTimestamp(uint256 timestamp);
PowerPassSnapshotNotTaken
error PowerPassSnapshotNotTaken();
PowerPassZeroAddress
error PowerPassZeroAddress();
PowerPassInvalidArrayLength
error PowerPassInvalidArrayLength();
PowerPassInvalidAmount
error PowerPassInvalidAmount();
PowerPassStakingContractNotSet
error PowerPassStakingContractNotSet();
PowerPassWithdrawFailed
error PowerPassWithdrawFailed();
PowerPassPaymentTokenNotSet
error PowerPassPaymentTokenNotSet();
PowerPassNativePaymentNotSupported
error PowerPassNativePaymentNotSupported();
PowerPassInvalidDiscountAmount
error PowerPassInvalidDiscountAmount();
PowerPassDiscountCodeInvalid
error PowerPassDiscountCodeInvalid();
PowerPassDiscountCodeAlreadyExists
error PowerPassDiscountCodeAlreadyExists(bytes32 codeHash);
PowerPassCustodialNotWhitelisted
error PowerPassCustodialNotWhitelisted(address account);
PowerPassCustodialExceedsAllocation
error PowerPassCustodialExceedsAllocation(address account, uint256 requested, uint256 remaining);
PowerPassNoActiveRound
error PowerPassNoActiveRound();
PowerPassRoundLimitExceeded
error PowerPassRoundLimitExceeded(uint256 requested, uint256 available);
ShareXWalletInvalidUserId
ShareX Wallet errors
error ShareXWalletInvalidUserId(uint256 userId);
ShareXWalletInvalidWalletId
error ShareXWalletInvalidWalletId(uint256 walletId);
ShareXWalletInvalidArrayLength
error ShareXWalletInvalidArrayLength();
ShareXWalletCallFailed
error ShareXWalletCallFailed();
ShareXWalletWithdrawFailed
error ShareXWalletWithdrawFailed();
ShareXWalletTransferFailed
error ShareXWalletTransferFailed();
ShareXWalletMintFailed
error ShareXWalletMintFailed();
ShareXWalletBurnFailed
error ShareXWalletBurnFailed();
ShareXWalletNoRoleToCreateWallet
error ShareXWalletNoRoleToCreateWallet(address account);
ShareXWalletWalletNotFound
error ShareXWalletWalletNotFound();
ShareXWalletInvalidAdminAddress
error ShareXWalletInvalidAdminAddress();
ShareXWalletPowerPassApprovalFailed
error ShareXWalletPowerPassApprovalFailed(address tokenContract, uint256 tokenId);
ShareXWalletPowerPassNotOwned
error ShareXWalletPowerPassNotOwned(address owner, uint256 tokenId);
ShareXWalletPowerPassBatchOperationFailed
error ShareXWalletPowerPassBatchOperationFailed(uint256 index, string reason);
ShareXWalletStakeFailed
error ShareXWalletStakeFailed();
ShareXWalletUnstakeFailed
error ShareXWalletUnstakeFailed();
ShareXWalletClaimRewardsFailed
error ShareXWalletClaimRewardsFailed();
ShareXKeysInvalidTokenId
ShareX Keys Series errors
error ShareXKeysInvalidTokenId(uint256 tokenId);
ShareXKeysNoWhitelistAllocation
error ShareXKeysNoWhitelistAllocation(address account, uint256 tokenId);
ShareXKeysInvalidArrayLength
error ShareXKeysInvalidArrayLength();
ShareXKeysZeroAddress
error ShareXKeysZeroAddress();
ShareXKeysInvalidAmount
error ShareXKeysInvalidAmount();
ShareXKeysExceedsAllocation
error ShareXKeysExceedsAllocation(
address account, uint256 tokenId, uint256 requested, uint256 remaining
);
ShareXKeysNoTokensToMint
error ShareXKeysNoTokensToMint(address account);
ShareXStakingZeroAddress
ShareX Keys Staking errors
error ShareXStakingZeroAddress();
ShareXStakingInvalidTokenId
error ShareXStakingInvalidTokenId(uint256 tokenId);
ShareXStakingInvalidAmount
error ShareXStakingInvalidAmount();
ShareXStakingInsufficientBalance
error ShareXStakingInsufficientBalance(
address account, uint256 tokenId, uint256 requested, uint256 available
);
ShareXStakingInsufficientStake
error ShareXStakingInsufficientStake(
address account, uint256 tokenId, uint256 requested, uint256 staked
);
ShareXStakingNoTokensToStake
error ShareXStakingNoTokensToStake(address account);
ShareXStakingNoTokensToUnstake
error ShareXStakingNoTokensToUnstake(address account);
ShareXStakingInvalidShareXKeysContract
error ShareXStakingInvalidShareXKeysContract();
ShareXStakingInvalidArrayLength
error ShareXStakingInvalidArrayLength();
ShareXStakingRewardCalculationFailed
error ShareXStakingRewardCalculationFailed();
ShareXStakingNoTokensToBurn
error ShareXStakingNoTokensToBurn(address account);
ShareXKeysStakingZeroAddress
error ShareXKeysStakingZeroAddress();
ShareXKeysStakingInvalidTokenContract
error ShareXKeysStakingInvalidTokenContract();
ShareXKeysStakingInvalidAmount
error ShareXKeysStakingInvalidAmount();
ShareXKeysStakingNoNFTToStake
error ShareXKeysStakingNoNFTToStake(address owner, uint256 tokenId);
ShareXKeysStakingNFTNotStaked
error ShareXKeysStakingNFTNotStaked(uint256 tokenId);
ShareXKeysStakingUnauthorizedCaller
error ShareXKeysStakingUnauthorizedCaller(address caller, uint256 tokenId);
ShareXKeysStakingInvalidBalance
error ShareXKeysStakingInvalidBalance(uint256 tokenId, uint256 balance);
ShareXKeysStakingNoRewardsToHarvest
error ShareXKeysStakingNoRewardsToHarvest(uint256 tokenId);
ShareXMomentumBadgeZeroAddress
error ShareXMomentumBadgeZeroAddress();
ShareXMomentumBadgeInvalidArrayLength
error ShareXMomentumBadgeInvalidArrayLength();
ShareXMomentumBadgeTokenNotExists
error ShareXMomentumBadgeTokenNotExists(uint256 tokenId);
ShareXMomentumBadgeUnauthorizedBurn
error ShareXMomentumBadgeUnauthorizedBurn(address caller, uint256 tokenId);
PowerPassStakingZeroAddress
error PowerPassStakingZeroAddress();
PowerPassStakingInvalidArrayLength
error PowerPassStakingInvalidArrayLength();
PowerPassStakingNotOwner
error PowerPassStakingNotOwner(address caller, uint256 tokenId);
PowerPassStakingAlreadyStaked
error PowerPassStakingAlreadyStaked(uint256 tokenId);
PowerPassStakingNotStaked
error PowerPassStakingNotStaked(uint256 tokenId);
PowerPassStakingUnauthorized
error PowerPassStakingUnauthorized(address caller, uint256 tokenId);
PowerPassStakingOrderAlreadyProcessed
error PowerPassStakingOrderAlreadyProcessed(bytes32 orderId);
PowerPassStakingInvalidRewardPercentage
error PowerPassStakingInvalidRewardPercentage(uint256 bps);
PowerPassStakingInsufficientBalance
error PowerPassStakingInsufficientBalance(uint256 required, uint256 available);
PowerPassStakingPaymentTokenNotSet
error PowerPassStakingPaymentTokenNotSet();
PowerPassStakingWithdrawFailed
error PowerPassStakingWithdrawFailed();
PowerPassStakingTransferFailed
error PowerPassStakingTransferFailed();
PowerPassStakingClaimAmountExceedsClaimable
error PowerPassStakingClaimAmountExceedsClaimable(uint256 requested, uint256 available);
PowerPassStakingRequestNotFound
error PowerPassStakingRequestNotFound(uint256 requestId);
PowerPassStakingRequestNotPending
error PowerPassStakingRequestNotPending(uint256 requestId);
PowerPassStakingRequestNotApproved
error PowerPassStakingRequestNotApproved(uint256 requestId);
PowerPassStakingNotRequestOwner
error PowerPassStakingNotRequestOwner(uint256 requestId, address expected, address actual);
PowerPassStakingZeroClaimAmount
error PowerPassStakingZeroClaimAmount();
PowerPassStakingNoApprovedRequests
error PowerPassStakingNoApprovedRequests(address user);
PartnerRegistered
Emitted when a partner is registered
event PartnerRegistered(
uint256 indexed id,
bytes32 indexed partnerCode,
bytes32 partnerName,
bytes2 iso2,
uint256 timestamp
);
MerchantRegistered
Emitted when a merchant is registered
event MerchantRegistered(
uint256 indexed id,
bytes32 indexed merchantName,
bytes32 indexed merchantId,
bytes2 iso2,
uint256 timestamp
);
DeviceRegistered
Emitted when a device is registered
event DeviceRegistered(
uint256 indexed id,
bytes32 indexed deviceId,
bytes32 deviceType,
bytes32 partnerCode,
bytes32 merchantId,
uint256 timestamp
);
TransactionBatchUploaded
Emitted when a transaction batch is uploaded
event TransactionBatchUploaded(
uint256 indexed batchId,
bytes32 indexed deviceId,
uint32 orderCount,
string totalAmount,
string dateComparable,
uint256 timestamp
);
TransactionDataUploaded
Emitted when transaction data is uploaded
event TransactionDataUploaded(uint256 indexed batchId, uint256 transactionCount, uint256 timestamp);
ContractInitialized
Emitted when contract is initialized
event ContractInitialized(address indexed admin, Version version, uint256 timestamp);
CountryRegistered
Emitted when a country is registered
event CountryRegistered(bytes2 indexed iso2, uint256 timestamp);
PowerPassMinted
Emitted when a PowerPass NFT is minted
event PowerPassMinted(address indexed to, uint256 indexed tokenId, string tokenURI);
PowerPassBurned
Emitted when a PowerPass NFT is burned
event PowerPassBurned(uint256 indexed tokenId);
PowerPassSalesConfigUpdated
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
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
Emitted when PowerPass NFTs are minted in batch
event PowerPassBatchMinted(
address indexed to,
uint256 amount,
uint256 totalPrice,
bool indexed isPriorityRound,
uint256 timestamp
);
PowerPassBatchWhitelistSet
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
Emitted when Nova discount allocations are configured for a round
event PowerPassNovaDiscountsSet(
uint64 indexed roundId, address[] accounts, uint256[] discountAllocations, uint256 timestamp
);
PowerPassBaseURIUpdated
Emitted when PowerPass base URI is updated
event PowerPassBaseURIUpdated(string newBaseURI, uint256 timestamp);
PowerPassFundsWithdrawn
Emitted when PowerPass funds are withdrawn
event PowerPassFundsWithdrawn(address indexed admin, uint256 amount, uint256 timestamp);
PowerPassDiscountCodeDiscountUpdated
Emitted when global discount code amount is updated
event PowerPassDiscountCodeDiscountUpdated(uint256 newDiscount, uint256 timestamp);
PowerPassDiscountCodesAdded
Emitted when discount code hashes are added
event PowerPassDiscountCodesAdded(bytes32[] codeHashes, uint256 timestamp);
PowerPassDiscountCodesRemoved
Emitted when discount code hashes are removed
event PowerPassDiscountCodesRemoved(bytes32[] codeHashes, uint256 timestamp);
PowerPassCustodialWhitelistsSet
Emitted when custodial whitelist allocations are configured
event PowerPassCustodialWhitelistsSet(address[] accounts, uint256[] allocations, uint256 timestamp);
PowerPassInitialized
Emitted when PowerPass contract is initialized
event PowerPassInitialized(
address indexed admin, address indexed stakingContract, string baseURI, uint256 timestamp
);
PowerPassApprovalSet
Emitted when PowerPass approval is set through ShareX wallet
event PowerPassApprovalSet(
address indexed tokenContract, address indexed owner, address indexed approved, uint256 tokenId
);
PowerPassApprovalForAllSet
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
Emitted when PowerPass batch approval is completed through ShareX wallet manager
event PowerPassBatchApproved(
address indexed tokenContract, address[] owners, uint256[] tokenIds, address indexed operator
);
PowerPassBatchTransferred
Emitted when PowerPass batch transfer is completed through ShareX wallet manager
event PowerPassBatchTransferred(
address indexed tokenContract, address[] from, address[] to, uint256[] tokenIds
);
PowerPassStakedViaWallet
Emitted when PowerPass is staked through ShareX wallet
event PowerPassStakedViaWallet(
address indexed stakingContract,
address indexed walletAddr,
uint256 indexed tokenId,
uint256 timestamp
);
PowerPassBatchStakedViaWallet
Emitted when PowerPass batch is staked through ShareX wallet
event PowerPassBatchStakedViaWallet(
address indexed stakingContract,
address indexed walletAddr,
uint256[] tokenIds,
uint256 timestamp
);
PowerPassUnstakedViaWallet
Emitted when PowerPass is unstaked through ShareX wallet
event PowerPassUnstakedViaWallet(
address indexed stakingContract,
address indexed walletAddr,
uint256 indexed tokenId,
uint256 timestamp
);
PowerPassBatchUnstakedViaWallet
Emitted when PowerPass batch is unstaked through ShareX wallet
event PowerPassBatchUnstakedViaWallet(
address indexed stakingContract,
address indexed walletAddr,
uint256[] tokenIds,
uint256 timestamp
);
PowerPassRewardsClaimedViaWallet
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
Emitted when all staking rewards are claimed for user through ShareX wallet
event PowerPassAllRewardsClaimedViaWallet(
address indexed stakingContract, address indexed walletAddr, uint256 timestamp
);
PowerPassClaimRequestedViaWallet
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
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
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
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
Emitted when ShareX Keys Series NFT is minted
event ShareXKeysMinted(address indexed to, uint256 indexed tokenId, uint256 amount);
ShareXKeysBatchMinted
Emitted when multiple ShareX Keys Series NFTs are minted in batch
event ShareXKeysBatchMinted(address indexed to, uint256[] tokenIds, uint256[] amounts);
ShareXKeysInitialized
Emitted when ShareX Keys Series contract is initialized
event ShareXKeysInitialized(address indexed admin, uint256 timestamp);
ShareXStakingInitialized
Emitted when ShareX Keys Staking contract is initialized
event ShareXStakingInitialized(
address indexed admin, address indexed shareXKeysContract, uint256 timestamp
);
ShareXStakingStaked
Emitted when a user stakes tokens
event ShareXStakingStaked(
address indexed user, uint256 indexed tokenId, uint256 amount, uint256 timestamp
);
ShareXStakingUnstaked
Emitted when a user unstakes tokens
event ShareXStakingUnstaked(
address indexed user, uint256 indexed tokenId, uint256 amount, uint256 timestamp
);
ShareXStakingBatchStaked
Emitted when a user stakes all available tokens in batch
event ShareXStakingBatchStaked(
address indexed user, uint256[] tokenIds, uint256[] amounts, uint256 timestamp
);
ShareXStakingBatchUnstaked
Emitted when a user unstakes all tokens in batch
event ShareXStakingBatchUnstaked(
address indexed user, uint256[] tokenIds, uint256[] amounts, uint256 timestamp
);
ShareXStakingRewardsClaimed
Emitted when a user claims rewards
event ShareXStakingRewardsClaimed(address indexed user, uint256 rewardAmount, uint256 timestamp);
ShareXStakingPoolUpdated
Emitted when pool rewards configuration is updated
event ShareXStakingPoolUpdated(uint256 indexed tokenId, uint256 rewardPerBlock, uint256 timestamp);
ShareXStakingEmergencyWithdrawal
Emitted when emergency withdrawal is performed
event ShareXStakingEmergencyWithdrawal(
address indexed user, uint256 indexed tokenId, uint256 amount, uint256 timestamp
);
ShareXStakingTokensBurned
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
event ShareXMomentumBadgeInitialized(address indexed admin, uint256 timestamp);
ShareXMomentumBadgeMinted
event ShareXMomentumBadgeMinted(address indexed to, uint256 indexed tokenId);
ShareXMomentumBadgeBatchMinted
event ShareXMomentumBadgeBatchMinted(address[] recipients);
ShareXMomentumBadgeBurned
event ShareXMomentumBadgeBurned(uint256 indexed tokenId);
ShareXMomentumBadgeBatchBurned
event ShareXMomentumBadgeBatchBurned(uint256[] tokenIds);
PowerPassStakingInitialized
event PowerPassStakingInitialized(
address indexed admin, address indexed powerPassContract, address indexed paymentToken
);
PowerPassStakingStaked
event PowerPassStakingStaked(address indexed user, uint256 indexed tokenId, uint256 timestamp);
PowerPassStakingBatchStaked
event PowerPassStakingBatchStaked(address indexed user, uint256[] tokenIds, uint256 timestamp);
PowerPassStakingUnstaked
event PowerPassStakingUnstaked(address indexed user, uint256 indexed tokenId, uint256 timestamp);
PowerPassStakingBatchUnstaked
event PowerPassStakingBatchUnstaked(address indexed user, uint256[] tokenIds, uint256 timestamp);
PowerPassStakingOrdersUploaded
event PowerPassStakingOrdersUploaded(
uint256[] tokenIds, uint256 totalOrders, uint256 totalRewardAmount, uint256 timestamp
);
PowerPassStakingRewardPercentageUpdated
event PowerPassStakingRewardPercentageUpdated(uint256 oldBps, uint256 newBps, uint256 timestamp);
PowerPassStakingPaymentTokenUpdated
event PowerPassStakingPaymentTokenUpdated(
address indexed oldToken, address indexed newToken, uint256 timestamp
);
PowerPassStakingRewardsWithdrawn
event PowerPassStakingRewardsWithdrawn(address indexed admin, uint256 amount, uint256 timestamp);
PowerPassStakingEmergencyNFTWithdrawn
event PowerPassStakingEmergencyNFTWithdrawn(
address indexed admin, uint256 indexed tokenId, address indexed to, uint256 timestamp
);
PowerPassStakingOrderRewardRecorded
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
event PowerPassStakingClaimRequested(
uint256 indexed requestId, address indexed user, uint128 amount, uint256 timestamp
);
PowerPassStakingClaimApproved
event PowerPassStakingClaimApproved(
uint256 indexed requestId,
address indexed user,
uint128 amount,
address indexed approver,
uint256 timestamp
);
PowerPassStakingClaimRejected
event PowerPassStakingClaimRejected(
uint256 indexed requestId,
address indexed user,
uint128 amount,
address indexed rejector,
uint256 timestamp
);
PowerPassStakingRewardsClaimed
event PowerPassStakingRewardsClaimed(
uint256 indexed requestId, address indexed user, uint128 amount, uint256 timestamp
);
PowerPassStakingAllApprovedRewardsClaimed
event PowerPassStakingAllApprovedRewardsClaimed(
address indexed user, uint256[] requestIds, uint128 totalAmount, uint256 timestamp
);
PowerPassStakingBatchClaimsApproved
event PowerPassStakingBatchClaimsApproved(
uint256[] requestIds, address indexed approver, uint128 totalAmount, uint256 timestamp
);
PowerPassStakingBatchClaimsRejected
event PowerPassStakingBatchClaimsRejected(
uint256[] requestIds, address indexed rejector, uint128 totalAmount, uint256 timestamp
);
PowerPassDiscountCodeUsed
Emitted when a discount code is used during PowerPass minting
event PowerPassDiscountCodeUsed(
bytes32 indexed codeHash, address indexed user, uint256 quantity, uint256 totalUsageCount
);
PowerPassStakingDirectClaimed
Emitted when rewards are directly claimed without USDT transfer (for custodial wallets)
event PowerPassStakingDirectClaimed(address indexed user, uint128 amount, uint256 timestamp);
PowerPassDirectClaimSettledViaWallet
Emitted when direct claim is settled via ShareX wallet
event PowerPassDirectClaimSettledViaWallet(
address indexed stakingContract, address indexed walletAddr, uint256 amount, uint256 timestamp
);
Deshare
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
| Name | Type | Description |
|---|---|---|
admin | address | Address for validation (required but not used in implementation) |
initialize
Initialize the Deshare proxy
function initialize(address admin) external payable initializer;
Parameters
| Name | Type | Description |
|---|---|---|
admin | address | Address that will be granted admin and operator roles |
registerPartner
Register a new partner
function registerPartner(PartnerParams calldata params)
external
override
onlyRole(OPERATOR_ROLE);
Parameters
| Name | Type | Description |
|---|---|---|
params | PartnerParams | Partner registration parameters |
registerMerchant
Register a new merchant
function registerMerchant(MerchantParams calldata params)
external
override
onlyRole(OPERATOR_ROLE);
Parameters
| Name | Type | Description |
|---|---|---|
params | MerchantParams | Merchant registration parameters |
registerDevice
Register a new device
function registerDevice(DeviceParams calldata params)
external
override
onlyRole(OPERATOR_ROLE);
Parameters
| Name | Type | Description |
|---|---|---|
params | DeviceParams | Device registration parameters |
uploadTransactionBatch
Upload a transaction batch
function uploadTransactionBatch(UploadBatchParams calldata params)
external
override
onlyRole(OPERATOR_ROLE)
nonReentrant;
Parameters
| Name | Type | Description |
|---|---|---|
params | UploadBatchParams | Upload batch parameters |
registerCountry
Register a country
function registerCountry(bytes2 iso2) external override onlyRole(OPERATOR_ROLE);
Parameters
| Name | Type | Description |
|---|---|---|
iso2 | bytes2 | The ISO2 country code |
getVersion
Get the contract version
function getVersion() external view override returns (Version memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | Version | version The current version |
getStats
Get statistics information
function getStats() external view override returns (StatsInfo memory stats);
Returns
| Name | Type | Description |
|---|---|---|
stats | StatsInfo | The current statistics |
getDetailedStats
Get detailed statistics information with descriptive labels
function getDetailedStats()
external
view
override
returns (DetailedStatsInfo memory detailedStats);
Returns
| Name | Type | Description |
|---|---|---|
detailedStats | DetailedStatsInfo | The detailed statistics with labels and metadata |
getPartner
Get partner information by ID
function getPartner(uint256 partnerId) external view override returns (PartnerInfo memory);
Parameters
| Name | Type | Description |
|---|---|---|
partnerId | uint256 | The partner ID |
Returns
| Name | Type | Description |
|---|---|---|
<none> | PartnerInfo | partner The partner information |
getPartnerByCode
Get partner information by partner code
function getPartnerByCode(string calldata partnerCode)
external
view
override
returns (PartnerInfo memory);
Parameters
| Name | Type | Description |
|---|---|---|
partnerCode | string | The partner code |
Returns
| Name | Type | Description |
|---|---|---|
<none> | PartnerInfo | partner The partner information |
partnerExists
Check if a partner exists by code
function partnerExists(string calldata partnerCode)
external
view
override
returns (bool exists);
Parameters
| Name | Type | Description |
|---|---|---|
partnerCode | string | The partner code |
Returns
| Name | Type | Description |
|---|---|---|
exists | bool | Whether the partner exists |
getMerchant
Get merchant information by ID
function getMerchant(uint256 merchantId) external view override returns (MerchantInfo memory);
Parameters
| Name | Type | Description |
|---|---|---|
merchantId | uint256 | The merchant ID |
Returns
| Name | Type | Description |
|---|---|---|
<none> | MerchantInfo | merchant The merchant information |
getMerchantById
Get merchant information by merchant ID
function getMerchantById(string calldata merchantId)
external
view
override
returns (MerchantInfo memory);
Parameters
| Name | Type | Description |
|---|---|---|
merchantId | string | The merchant ID (string) |
Returns
| Name | Type | Description |
|---|---|---|
<none> | MerchantInfo | merchant The merchant information |
merchantExists
Check if a merchant exists by ID
function merchantExists(string calldata merchantId)
external
view
override
returns (bool exists);
Parameters
| Name | Type | Description |
|---|---|---|
merchantId | string | The merchant ID |
Returns
| Name | Type | Description |
|---|---|---|
exists | bool | Whether the merchant exists |
getDevice
Get device information by ID
function getDevice(uint256 deviceId) external view override returns (DeviceInfo memory);
Parameters
| Name | Type | Description |
|---|---|---|
deviceId | uint256 | The device ID |
Returns
| Name | Type | Description |
|---|---|---|
<none> | DeviceInfo | device The device information |
getDeviceById
Get device information by device ID
function getDeviceById(string calldata deviceId)
external
view
override
returns (DeviceInfo memory);
Parameters
| Name | Type | Description |
|---|---|---|
deviceId | string | The device ID (string) |
Returns
| Name | Type | Description |
|---|---|---|
<none> | DeviceInfo | device The device information |
deviceExists
Check if a device exists by ID
function deviceExists(string calldata deviceId) external view override returns (bool exists);
Parameters
| Name | Type | Description |
|---|---|---|
deviceId | string | The device ID |
Returns
| Name | Type | Description |
|---|---|---|
exists | bool | Whether the device exists |
getTransactionBatch
Get transaction batch by ID
function getTransactionBatch(uint256 batchId)
external
view
override
returns (TransactionBatch memory);
Parameters
| Name | Type | Description |
|---|---|---|
batchId | uint256 | The batch ID |
Returns
| Name | Type | Description |
|---|---|---|
<none> | TransactionBatch | batch The transaction batch |
getTransactionData
Retrieves transaction data for a batch
function getTransactionData(uint256 batchId)
external
view
override
returns (string memory jsonData);
Parameters
| Name | Type | Description |
|---|---|---|
batchId | uint256 | The batch ID to retrieve data for |
Returns
| Name | Type | Description |
|---|---|---|
jsonData | string | The transaction data as JSON string |
getCountry
Get country information
function getCountry(bytes2 iso2) external view override returns (CountryInfo memory);
Parameters
| Name | Type | Description |
|---|---|---|
iso2 | bytes2 | The ISO2 country code |
Returns
| Name | Type | Description |
|---|---|---|
<none> | CountryInfo | country The country information |
countryExists
Check if a country is registered
function countryExists(bytes2 iso2) external view override returns (bool exists);
Parameters
| Name | Type | Description |
|---|---|---|
iso2 | bytes2 | The ISO2 country code |
Returns
| Name | Type | Description |
|---|---|---|
exists | bool | Whether 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
| Name | Type | Description |
|---|---|---|
businessType | string | The business type to query |
Returns
| Name | Type | Description |
|---|---|---|
count | uint256 | The 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
| Name | Type | Description |
|---|---|---|
iso2 | bytes2 | The ISO2 country code |
locationId | string | The location ID (e.g., city identifier) |
Returns
| Name | Type | Description |
|---|---|---|
count | uint256 | The count of merchants |
_getCountriesCount
Returns the count of registered countries
function _getCountriesCount() internal view returns (uint256 count);
Returns
| Name | Type | Description |
|---|---|---|
count | uint256 | The number of registered countries |
_createTransactionBatch
Creates and stores a new transaction batch
function _createTransactionBatch(UploadBatchParams calldata params)
private
returns (uint64 batchId);
Parameters
| Name | Type | Description |
|---|---|---|
params | UploadBatchParams | The upload batch parameters |
Returns
| Name | Type | Description |
|---|---|---|
batchId | uint64 | The ID of the created batch |
_storeTransactionData
Stores transaction data for a batch
function _storeTransactionData(uint64 batchId, bytes calldata transactionData) private;
Parameters
| Name | Type | Description |
|---|---|---|
batchId | uint64 | The batch ID to store data for |
transactionData | bytes | The transaction data to store |
_emitBatchEvents
Emits events for transaction batch upload
function _emitBatchEvents(
uint64 batchId,
bytes32 deviceIdHash,
UploadBatchParams calldata params
) private;
Parameters
| Name | Type | Description |
|---|---|---|
batchId | uint64 | The batch ID |
deviceIdHash | bytes32 | The hash of the device ID |
params | UploadBatchParams | The upload batch parameters |
_validateUploadBatchParams
Validates the upload batch parameters
function _validateUploadBatchParams(UploadBatchParams calldata params)
private
view
returns (bytes32 deviceIdHash);
Parameters
| Name | Type | Description |
|---|---|---|
params | UploadBatchParams | The upload batch parameters to validate |
Returns
| Name | Type | Description |
|---|---|---|
deviceIdHash | bytes32 | The hash of the device ID for later use |
PowerPass
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
| Name | Type | Description |
|---|---|---|
_admin | address | Address to grant admin role to |
baseURI_ | string | Base 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
| Name | Type | Description |
|---|---|---|
_admin | address | Address to grant admin role to |
baseURI_ | string | Base URI for token metadata |
paymentToken_ | address | ERC20 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
| Name | Type | Description |
|---|---|---|
config | SalesConfig | Sales configuration including timestamps and pricing |
supplyLimit | uint256 | Maximum 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
| Name | Type | Description |
|---|---|---|
token | address | ERC20 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
| Name | Type | Description |
|---|---|---|
discountAmount | uint256 | New 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
| Name | Type | Description |
|---|---|---|
codeHashes | bytes32[] | Array of keccak256 hashes of discount codes |
removeDiscountCodes
Remove discount code hashes
function removeDiscountCodes(bytes32[] calldata codeHashes)
external
override
onlyRole(DEFAULT_ADMIN_ROLE);
Parameters
| Name | Type | Description |
|---|---|---|
codeHashes | bytes32[] | 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
| Name | Type | Description |
|---|---|---|
codeHash | bytes32 | keccak256 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
| Name | Type | Description |
|---|---|---|
codeHash | bytes32 | keccak256 hash of the discount code |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | usageCount 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
| Name | Type | Description |
|---|---|---|
amount | uint256 | Number of NFTs to mint |
discountCode | string | Optional 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
| Name | Type | Description |
|---|---|---|
roundConfig | PowerPassRoundConfig | Round configuration containing prices |
amount | uint256 | Total amount to mint |
novaEligible | uint256 | Amount eligible for Nova discount |
discountCode | string | Discount code string |
Returns
| Name | Type | Description |
|---|---|---|
totalPrice | uint256 | Final 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
| Name | Type | Description |
|---|---|---|
accounts | address[] | Array of addresses to set allocations for |
priorityAmounts | uint256[] | Array of priority allocations corresponding to accounts |
generalAmounts | uint256[] | 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
| Name | Type | Description |
|---|---|---|
accounts | address[] | Array of addresses to configure |
discountAllocations | uint256[] | 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
| Name | Type | Description |
|---|---|---|
accounts | address[] | Custodial wallet addresses (ShareX wallet addresses or end-user custodial addrs) |
allocations | uint256[] | 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
| Name | Type | Description |
|---|---|---|
baseURI | string | The 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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | Token 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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | Token ID to set URI for |
newTokenURI | string | New 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
| Name | Type | Description |
|---|---|---|
newTokenId | uint256 | The next token ID to be minted |
currentTokenId
Get the current token ID counter
function currentTokenId() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The 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
| Name | Type | Description |
|---|---|---|
account | address | The address to query mint status for |
Returns
| Name | Type | Description |
|---|---|---|
status | MintStatus | Complete 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
| Name | Type | Description |
|---|---|---|
account | address | The address to query allocations for |
Returns
| Name | Type | Description |
|---|---|---|
info | WhitelistInfo | Complete 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
| Name | Type | Description |
|---|---|---|
config | SalesConfig | Complete 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
| Name | Type | Description |
|---|---|---|
<none> | uint64 | roundId 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
| Name | Type | Description |
|---|---|---|
info | RoundInfo | RoundInfo 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
| Name | Type | Description |
|---|---|---|
roundId | uint64 | Round ID to query |
Returns
| Name | Type | Description |
|---|---|---|
config | SalesConfig | Sales configuration for the round |
supplyLimit | uint256 | Maximum NFTs for the round |
mintedCount | uint256 | NFTs 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
| Name | Type | Description |
|---|---|---|
roundId | uint64 | Round ID to query |
account | address | User address to query |
Returns
| Name | Type | Description |
|---|---|---|
info | WhitelistInfo | WhitelistInfo 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
| Name | Type | Description |
|---|---|---|
<none> | uint256 | totalSupply 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
| Name | Type | Description |
|---|---|---|
web3Count | uint256 | Number of NFTs minted via Web3 public mint |
custodialCount | uint256 | Number 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
| Name | Type | Description |
|---|---|---|
<none> | uint256 | maxSupply 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
| Name | Type | Description |
|---|---|---|
userWhitelist | PowerPassWhitelistInfo | |
amount | uint256 | Amount to mint |
isPriorityActive | bool | Whether priority round is active |
_mintTokens
Mint tokens with gas-optimized loop and proper token URI formatting
function _mintTokens(uint256 amount) private;
Parameters
| Name | Type | Description |
|---|---|---|
amount | uint256 | Amount of tokens to mint |
_formatTokenURI
Format token URI properly as {tokenId}.json
function _formatTokenURI(uint256 tokenId) private pure returns (string memory);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | Token ID to format |
Returns
| Name | Type | Description |
|---|---|---|
<none> | string | Formatted token URI relative path |
_toString
Convert uint256 to string (gas-optimized)
function _toString(uint256 value) private pure returns (string memory);
Parameters
| Name | Type | Description |
|---|---|---|
value | uint256 | Number to convert |
Returns
| Name | Type | Description |
|---|---|---|
<none> | string | String 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
| Name | Type | Description |
|---|---|---|
config | PowerPassRoundConfig | Round configuration to check |
Returns
| Name | Type | Description |
|---|---|---|
isPriorityActive | bool | Whether priority round is active |
isGeneralActive | bool | Whether 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
| Name | Type | Description |
|---|---|---|
magnaStaked | uint256 | Amount of MAGNA tokens staked |
novaStaked | uint256 | Amount of NOVA tokens staked |
Returns
| Name | Type | Description |
|---|---|---|
allocation | uint64 | Priority 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
| Name | Type | Description |
|---|---|---|
essentiaStaked | uint256 | Amount of ESSENTIA tokens staked |
magnaStaked | uint256 | Amount of MAGNA tokens staked |
novaStaked | uint256 | Amount of NOVA tokens staked |
Returns
| Name | Type | Description |
|---|---|---|
allocation | uint64 | General round allocation (max 10 NFTs) |
PowerPassStaking
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
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
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
| Name | Type | Description |
|---|---|---|
_shareXKeysContract | address | Address of the ShareX Keys Series ERC1155 contract |
_admin | address | Address 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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | Token type to stake (0=ESSENTIA, 1=MAGNA, 2=NOVA) |
amount | uint256 | Number 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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | Token type to unstake (0=ESSENTIA, 1=MAGNA, 2=NOVA) |
amount | uint256 | Number 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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | Token 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
| Name | Type | Description |
|---|---|---|
account | address | The 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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | Token type to update |
rewardPerBlock | uint256 | New 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
| Name | Type | Description |
|---|---|---|
account | address | User address |
tokenId | uint256 | Token type |
Returns
| Name | Type | Description |
|---|---|---|
info | StakingInfo | Complete staking information |
getPoolInfo
Get pool information for a token type
function getPoolInfo(uint256 tokenId)
external
view
override
validTokenId(tokenId)
returns (PoolInfo memory info);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | Token type |
Returns
| Name | Type | Description |
|---|---|---|
info | PoolInfo | Pool configuration and statistics |
getTotalPendingRewards
Get total pending rewards for a user
function getTotalPendingRewards(address account)
external
view
override
returns (uint256 totalRewards);
Parameters
| Name | Type | Description |
|---|---|---|
account | address | User address |
Returns
| Name | Type | Description |
|---|---|---|
totalRewards | uint256 | Sum 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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | Token type to update |
_updateUserRewards
Update user reward debt
function _updateUserRewards(address account, uint256 tokenId) internal;
Parameters
| Name | Type | Description |
|---|---|---|
account | address | User address |
tokenId | uint256 | Token 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
| Name | Type | Description |
|---|---|---|
account | address | User address |
tokenId | uint256 | Token type |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Pending reward amount |
_calculatePendingRewardView
Calculate pending rewards for view function
function _calculatePendingRewardView(address account, uint256 tokenId)
internal
view
returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
account | address | User address |
tokenId | uint256 | Token type |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Pending 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
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
| Name | Type | Description |
|---|---|---|
admin | address | Address to be granted admin role |
mint
Mint a badge to a recipient
function mint(address to) external override onlyRole(MINTER_ROLE);
Parameters
| Name | Type | Description |
|---|---|---|
to | address | Recipient address |
batchMint
Mint badges to multiple recipients
function batchMint(address[] calldata recipients) external override onlyRole(MINTER_ROLE);
Parameters
| Name | Type | Description |
|---|---|---|
recipients | address[] | Array of recipient addresses |
burn
Burn a badge
function burn(uint256 tokenId) external override;
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | Token ID to burn |
batchBurn
Burn multiple badges
function batchBurn(uint256[] calldata tokenIds) external override;
Parameters
| Name | Type | Description |
|---|---|---|
tokenIds | uint256[] | 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
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | Token ID |
Returns
| Name | Type | Description |
|---|---|---|
<none> | string | The metadata URI |
totalSupply
Get the total supply of badges
function totalSupply()
public
view
override(ERC721Enumerable, IShareXMomentumBadge)
returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The 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
| Name | Type | Description |
|---|---|---|
interfaceId | bytes4 | Interface identifier |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | True if the interface is supported |
_exists
Internal function to check if a token exists
function _exists(uint256 tokenId) internal view returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | Token ID to check |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | True if the token exists |
ShareXUSDT
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
| Name | Type | Description |
|---|---|---|
to | address | The address to mint tokens to |
amount | uint256 | The amount of tokens to mint |
burn
Burns tokens from the caller's account
function burn(uint256 amount) external;
Parameters
| Name | Type | Description |
|---|---|---|
amount | uint256 | The amount of tokens to burn |
burnFrom
Burns tokens from a specified account (requires allowance)
function burnFrom(address from, uint256 amount) external;
Parameters
| Name | Type | Description |
|---|---|---|
from | address | The account to burn tokens from |
amount | uint256 | The 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
| Name | Type | Description |
|---|---|---|
recipients | address[] | Array of addresses to mint to |
amounts | uint256[] | 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
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
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);