Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/node-ops/staking-and-delegation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ This page explains how staking and delegation works, including how to stake as a
The Lit Protocol employs a dual reward structure to compensate node operators:

1. **Cost-Based Component**
A baseline reward is allocated to each node operator to offset the expenses associated with the required hardware and infrastructure. The baseline reward amount may be adjusted periodically via governance to cover the real-world costs associated with node operations (e.g., server hosting) in their entirety, ensuring operators always break even on the costs associated with running a node and never operate at a net loss. The goal is to preserve a stable pool of node operators even during periods of market volatility, essential for maintaining the shared cryptographic secrets maintained by the network in perpetuity.
A baseline reward of $1,500 in LITKEY tokens is allocated to each node operator to offset the expenses associated with the required hardware and infrastructure. The baseline reward amount may be adjusted periodically via governance to cover the real-world costs associated with node operations (e.g., server hosting) in their entirety, ensuring operators always break even on the costs associated with running a node and never operate at a net loss. The goal is to preserve a stable pool of node operators even during periods of market volatility, essential for maintaining the shared cryptographic secrets maintained by the network in perpetuity.

Several configurable parameters go into setting the cost-based component of the Lit node rewards budget, including the price of the \$LITKEY token, the costs associated with running a node (denominated in USD), and a target profit margin factor.

Expand Down
1 change: 0 additions & 1 deletion docs/snippets/CurrentPricesTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export const CurrentPricesTable = ({ priceData }) => {
const PRODUCT_IDS = [
ProductId.PkpSign,
ProductId.EncSign,
ProductId.LitAction,
ProductId.SignSessionKey,
];

Expand Down
53 changes: 49 additions & 4 deletions docs/snippets/PriceProvider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -265,13 +265,58 @@ export const PriceProvider = ({ children, component: Component }) => {
const basePrice = basePricesResult[0];
const maxPrice = maxPricesResult[0];

// Calculate usage percent: (current - base) / (max - base) * 100
// Average the prices from all nodes
// Calculate usage percent by finding which usage percentage produces the current price
// Use median price from all nodes to get current market price
let calculatedUsage = 0;
if (nodePriceData.length > 0 && !maxPrice.eq(basePrice)) {
const avgPrice = nodePriceData.reduce((sum, node) => sum.add(node.price), ethers.BigNumber.from(0)).div(nodePriceData.length);
calculatedUsage = avgPrice.sub(basePrice).mul(100).div(maxPrice.sub(basePrice)).toNumber();
// Extract and sort all node prices
const prices = nodePriceData.map(node => ethers.BigNumber.from(node.price));
prices.sort((a, b) => {
if (a.lt(b)) return -1;
if (a.gt(b)) return 1;
return 0;
});

// Calculate median
let medianPrice;
const mid = Math.floor(prices.length / 2);
if (prices.length % 2 === 0) {
// Even number of prices: average the two middle values
medianPrice = prices[mid - 1].add(prices[mid]).div(2);
} else {
// Odd number of prices: use the middle value
medianPrice = prices[mid];
}

// Debug: log values to understand why calculation might fail
console.log('Usage calculation:', {
nodePrices: nodePriceData.map(n => n.price.toString()),
sortedPrices: prices.map(p => p.toString()),
medianPrice: medianPrice.toString(),
basePrice: basePrice.toString(),
maxPrice: maxPrice.toString(),
medianVsBase: medianPrice.lt(basePrice) ? 'median < base' : medianPrice.eq(basePrice) ? 'median = base' : 'median > base',
});

// If medianPrice equals basePrice, usage is 0%
if (medianPrice.lte(basePrice)) {
calculatedUsage = 0;
}
// If medianPrice equals or exceeds maxPrice, usage is 100%
else if (medianPrice.gte(maxPrice)) {
calculatedUsage = 100;
}
// Otherwise, calculate: (medianPrice - basePrice) * 100 / (maxPrice - basePrice)
else {
const priceDiff = medianPrice.sub(basePrice);
const maxBaseDiff = maxPrice.sub(basePrice);
// Calculate percentage (0-100) with integer precision
calculatedUsage = priceDiff.mul(100).div(maxBaseDiff).toNumber();
// Ensure it's between 0 and 100
calculatedUsage = Math.max(0, Math.min(100, calculatedUsage));
}
}
console.log('Calculated usage:', calculatedUsage);
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug console.log statement should be removed before merging to production. This will pollute the browser console for end users viewing the documentation.

Suggested change
console.log('Calculated usage:', calculatedUsage);

Copilot uses AI. Check for mistakes.
setUsagePercent(calculatedUsage);
const currentPricesResult = await contract.usagePercentToPrices(calculatedUsage, PRODUCT_IDS);

Expand Down
Loading