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 |