- PowerloomNodes Contract Documentation
PowerloomNodes is a Soul Bound Token (SBT) contract that manages Powerloom Snapshotter Nodes. It implements ERC1155 with non-transferability, making tokens bound to their owners. The contract supports both regular and legacy node types, with different vesting and claiming mechanisms.
- Non-transferable ERC1155 tokens (SBT)
- Upgradeable using UUPS pattern
- Pausable for emergency situations
- Supports both regular and legacy nodes
- Token vesting mechanism for legacy nodes
- KYC-dependent functionality
- Admin management system
- Snapshotter address management
- Purpose: Initializes the contract with basic parameters
- Parameters:
initialOwner
: Address that will have owner privilegesinitialNodePrice
: Starting price for minting regular nodesinitialName
: Name of the token contract
- Behavior:
- Initializes all OpenZeppelin components (ERC1155, Ownable, Pausable, etc.)
- Sets initial node price
- Sets contract name
- Purpose: Configures all parameters for legacy node functionality
- Parameters:
_legacyNodeCount
: Maximum number of legacy nodes_legacyNodeInitialClaimPercentage
: Initial claim percentage (in ppm, 1e6 = 100%)_legacyNodeCliff
: Vesting cliff period in days_legacyNodeValue
: Total value per legacy node_legacyNodeVestingDays
: Total vesting duration_legacyNodeVestingStart
: Vesting start timestamp_legacyTokensSentOnL1
: Tokens already distributed on L1_legacyNodeNonKycedCooldown
: Cooldown for non-KYCed nodes
- Behavior:
- Sets all legacy node parameters
- Validates input values (e.g., percentage ≤ 100%)
- Emits
ConfigurationUpdated
event
- Purpose: Allows users to mint regular nodes
- Parameters:
amount
: Number of nodes to mint
- Requirements:
- Contract must not be paused
- Minting must be open (current time ≥ mintStartTime)
- Sufficient ETH sent (amount * nodePrice)
- Behavior:
- Creates new nodes
- Assigns ownership
- Refunds excess ETH
- Updates state variables
- Emits
NodeMinted
events
- Purpose: Admin function to mint legacy nodes
- Parameters:
_to
: Recipient address_amount
: Number of nodes_isKyced
: KYC status of recipient
- Requirements:
- Only owner can call
- Must be within legacyNodeCount limit
- Behavior:
- Mints legacy nodes with special properties
- Sets KYC status
- Updates legacy node tracking
- Emits
NodeMinted
events
- Purpose: Burns a node and initiates token claiming process
- Parameters:
_nodeId
: ID of node to burn
- Requirements:
- Caller must be node owner
- Contract must not be paused
- Behavior:
- Burns the node token
- Updates burning tracking
- For legacy nodes:
- If KYCed: Initiates vesting schedule
- If non-KYCed: Enables one-time claim after cooldown
- Emits
NodeBurned
event
-
Purpose: Assigns a snapshotter address to a node
-
Parameters:
nodeId
: Target node IDsnapshotterAddress
: Address to assign
-
Requirements:
- Caller must be node owner
- Must respect cooldown period
-
Behavior:
- Updates snapshotter mapping
- Updates node active status
- Updates enabled node count
- Emits
allSnapshottersUpdated
event
-
Purpose: Admin version of snapshotter assignment
-
Behavior: Same as
assignSnapshotterToNode
but bypasses cooldown
- Purpose: Calculates claimable tokens for a node
- Parameters:
_nodeId
: Node ID to check
- Returns: Amount of tokens claimable
- Behavior:
- For regular nodes:
- Returns node price if cooldown passed
- For legacy nodes:
- KYCed: Calculates vested amount
- Non-KYCed: Returns full amount if cooldown passed
- For regular nodes:
- Purpose: Admin version of snapshotter assignment
- Behavior: Same as
assignSnapshotterToNode
but bypasses cooldown
- Purpose: Claims available tokens for a node
- Requirements:
- Node must be burned
- Appropriate cooldown must have passed
- Tokens must not be already claimed
- Behavior:
- Transfers claimable tokens
- Updates claim status
- Emits appropriate claim event
- Purpose: Calculates total vested tokens for legacy nodes
- Behavior:
- Considers vesting schedule
- Accounts for cliff period
- Uses precision factor for accurate calculations
- Purpose: Manages admin privileges
- Parameters:
_admins
: Array of admin addresses_status
: Array of boolean statuses
- Behavior:
- Adds/removes admin privileges
- Emits
AdminsUpdated
events
- Purpose: Allows owner to withdraw all funds in emergencies
- Behavior:
- Transfers all contract balance to owner
- Emits
EmergencyWithdraw
event
- Purpose: Emergency pause/unpause of contract functions
- Behavior:
- Stops/resumes critical operations
- Affects minting, burning, claiming
-
NodeMinted(address indexed to, uint256 nodeId)
- Triggered when: New node is minted (both regular and legacy)
-
NodeBurned(address indexed from, uint256 nodeId)
- Triggered when: Node is burned by its owner
-
LegacyNodeTokensClaimed(address indexed claimer, uint256 nodeId, uint256 amount)
- Triggered when: Legacy node tokens are claimed (both KYCed and non-KYCed)
-
SnapshotterTokensClaimed(address indexed claimer, uint256 nodeId, uint256 amount)
- Triggered when: Regular node tokens are claimed
-
ConfigurationUpdated(string paramName, uint256 newValue)
- Triggered when: Contract configuration parameters are updated
-
URIUpdated(string newUri)
- Triggered when: Token metadata URI is updated
-
NameUpdated(string newName)
- Triggered when: Contract name is updated
-
SnapshotterStateUpdated(address indexed newSnapshotterState)
- Triggered when: Snapshotter state changes
-
allSnapshottersUpdated(address snapshotterAddress, bool allowed)
- Triggered when: Snapshotter permissions are modified
-
AdminsUpdated(address adminAddress, bool allowed)
- Triggered when: Admin role permissions are modified
-
EmergencyWithdraw(address indexed owner, uint256 amount)
- Triggered when: Emergency withdrawal is executed by owner
-
Deposit(address indexed from, uint256 amount)
- Triggered when: ETH is deposited into the contract
-
Minting
- User pays
nodePrice
in $POWER - Contract holds funds
- Node is minted as SBT
- User pays
-
Claiming
- User burns node
- Waits for
snapshotterTokenClaimCooldown
- Claims original
nodePrice
-
Minting
- Admin mints with KYC status
- No immediate payment
- Node value is
legacyNodeValue
-
Claiming (KYCed)
- Initial claim:
legacyNodeInitialClaimPercentage
- Remaining: Vests over
legacyNodeVestingDays
- Multiple claims possible
- Initial claim:
-
Claiming (Non-KYCed)
- Single claim after
legacyNodeNonKycedCooldown
- Claims full
nodePrice
- Single claim after
-
Owner
- Contract upgrades
- Emergency functions
- Configuration changes
-
Admins
- Legacy node minting
- Snapshotter management
- No upgrade authority
-
Users
- Node minting (with payment)
- Node burning
- Token claiming
-
Reentrancy Guards
- All value transfers protected
- State changes before transfers
- Strict function ordering
-
Cooldown Periods
- Prevent rapid changes
- Protect against manipulation
- Different periods for different operations
-
Pausability
- Emergency stop mechanism
- Protects user funds
- Controlled by owner
ERC1155Upgradeable
: Base token functionalityOwnable2StepUpgradeable
: Access controlPausableUpgradeable
: Emergency stopsERC1155SupplyUpgradeable
: Supply trackingUUPSUpgradeable
: Upgrade patternReentrancyGuardUpgradeable
: Transaction safetyEnumerableSet
: Efficient set operations
-
Storage Layout
- Append-only storage pattern
- No reordering of variables
- No removal of existing storage
-
Function Changes
- Can add new functions
- Can modify internal logic
- Cannot remove public interfaces
-
Authorization
- Only owner can upgrade
- Must implement
_authorizeUpgrade
- Follows UUPS pattern