NexusMutual / smart-contracts

GNU General Public License v3.0
170 stars 62 forks source link

DRAFT: chore: add StakingProducts contract documentation #1285

Open rackstar opened 4 days ago

rackstar commented 4 days ago

Closes #1264

StakingProducts Contract Developer Documentation

Overview

The StakingProducts contract is a core component of the protocol, responsible for managing staking pools, their associated products, and dynamic pricing mechanisms for cover products. This contract enables the creation and management of staking pools, configuration of products within those pools, and calculation of premiums based on capacity and utilization.

Key Concepts

Product Weights

Each product within a staking pool has two key weight metrics:

Understanding these weights is crucial for managing capacity allocation and ensuring fair distribution among products.

Pricing Dynamics

The contract employs a sophisticated pricing mechanism that includes:

Staking Pool Management

The StakingProducts contract allows for:

Mutative Functions

setProducts

Configures products for a specific staking pool and updates their parameters.

function setProducts(uint poolId, StakedProductParam[] memory params) external;
Parameter Description
poolId The ID of the staking pool.
params An array of StakedProductParam structs containing product parameters.

recalculateEffectiveWeights

Dynamically adjusts effective weights for specified products based on current capacity and utilization.

function recalculateEffectiveWeights(uint poolId, uint[] calldata productIds) external;
Parameter Description
poolId The ID of the staking pool to update.
productIds The IDs of the products within the pool whose weights will be recalculated.

Description: Recalculates effectiveWeight for each specified product. Ensures fair capacity allocation among products.

recalculateEffectiveWeightsForAllProducts

Recalculates effective weights for all products within a staking pool.

function recalculateEffectiveWeightsForAllProducts(uint poolId) external;
Parameter Description
poolId The ID of the staking pool.

Description: Useful for comprehensive updates after significant changes.

getPremium

Calculates the premium for a cover product based on current pricing dynamics.

function getPremium(
    uint poolId,
    uint productId,
    uint period,
    uint coverAmount,
    uint initialCapacityUsed,
    uint totalCapacity,
    uint globalMinPrice,
    bool useFixedPrice,
    uint nxmPerAllocationUnit,
    uint allocationUnitsPerNXM
) public returns (uint premium);
Parameter Description
poolId The ID of the staking pool.
productId The ID of the specific cover product.
period The cover duration in seconds.
coverAmount The coverage amount requested (in the protocol's units).
initialCapacityUsed The capacity already used before this cover.
totalCapacity The total capacity available in the pool.
globalMinPrice The global minimum price ratio for the cover product.
useFixedPrice Boolean indicating if a fixed price should be used.
nxmPerAllocationUnit The amount of NXM per allocation unit.
allocationUnitsPerNXM The number of allocation units per NXM token.

Description: Typically called internally by the staking pool during cover purchase. Updates the product's bumped price and timestamp.

createStakingPool

Creates a new staking pool with specified configurations.

function createStakingPool(
    bool isPrivatePool,
    uint initialPoolFee,
    uint maxPoolFee,
    ProductInitializationParams[] memory productInitParams,
    string calldata ipfsHash
) external returns (uint poolId, address stakingPoolAddress);
Parameter Description
isPrivatePool Indicates if the pool is private (true) or public (false).
initialPoolFee The initial fee for the pool (in basis points).
maxPoolFee The maximum allowable fee for the pool (in basis points).
productInitParams Initial parameters for products in the pool.
ipfsHash IPFS hash for the pool's metadata.

Description: Initializes a new staking pool and sets up initial products. The pool manager role is assigned to the caller.

setPoolMetadata

Updates the metadata for a staking pool.

function setPoolMetadata(uint poolId, string calldata ipfsHash) external;
Parameter Description
poolId The ID of the staking pool.
ipfsHash New IPFS hash for the pool's metadata.

getProduct

Retrieves detailed information about a specific product in a pool.

function getProduct(uint poolId, uint productId) external view returns (
    uint lastEffectiveWeight,
    uint targetWeight,
    uint targetPrice,
    uint bumpedPrice,
    uint bumpedPriceUpdateTime
);
Parameter Description
poolId The ID of the staking pool.
productId The ID of the product.

Returns:

getProductTargetWeight

Gets the target weight for a specific product in a pool.

function getProductTargetWeight(uint poolId, uint productId) external view returns (uint);
Parameter Description
poolId The ID of the staking pool.
productId The ID of the product.

getTotalTargetWeight

Gets the total target weight for all products in a pool.

function getTotalTargetWeight(uint poolId) external view returns (uint);
Parameter Description
poolId The ID of the staking pool.

getTotalEffectiveWeight

Gets the total effective weight for all products in a pool.

function getTotalEffectiveWeight(uint poolId) external view returns (uint);
Parameter Description
poolId The ID of the staking pool.

getPoolManager

Retrieves the address of the manager for a staking pool.

function getPoolManager(uint poolId) public view returns (address);
Parameter Description
poolId The ID of the staking pool.

getPoolMetadata

Retrieves the IPFS hash of the pool's metadata.

function getPoolMetadata(uint poolId) external view returns (string memory ipfsHash);
Parameter Description
poolId The ID of the staking pool.

Pricing Functions

calculatePremium

Calculates the premium for a cover product and updates the product's bumped price.

function calculatePremium(
    StakedProduct memory product,
    uint period,
    uint coverAmount,
    uint initialCapacityUsed,
    uint totalCapacity,
    uint targetPrice,
    uint currentBlockTimestamp,
    uint nxmPerAllocationUnit,
    uint allocationUnitsPerNxm,
    uint targetPriceDenominator
) public pure returns (uint premium, StakedProduct memory);

Description: Computes the premium based on current pricing dynamics (price bumps, surge pricing)

calculatePremiumPerYear

Calculates the annualized premium for a cover product, including surge pricing if applicable.

function calculatePremiumPerYear(
    uint basePrice,
    uint coverAmount,
    uint initialCapacityUsed,
    uint totalCapacity,
    uint nxmPerAllocationUnit,
    uint allocationUnitsPerNxm,
    uint targetPriceDenominator
) public pure returns (uint);

Description: Calculates the premium per year considering base price and capacity utilization

calculateSurgePremium

Calculates the surge premium for the capacity used above the surge threshold.

function calculateSurgePremium(
    uint amountOnSurge,
    uint totalCapacity,
    uint allocationUnitsPerNxm
) public pure returns (uint);

Description: Computes additional premium due to surge pricing. Applied when capacity usage exceeds 90%.

getBasePrice

Calculates the base price of a product, adjusting towards the target price over time.

function getBasePrice(
    uint productBumpedPrice,
    uint productBumpedPriceUpdateTime,
    uint targetPrice,
    uint timestamp
) public pure returns (uint basePrice);

Description: Applies daily adjustments towards the target price ensuring smooth price transitions over time.

calculateFixedPricePremium

Calculates the premium using a fixed price, bypassing dynamic pricing mechanisms.

function calculateFixedPricePremium(
    uint coverAmount,
    uint period,
    uint fixedPrice,
    uint nxmPerAllocationUnit,
    uint targetPriceDenominator
) public pure returns (uint);

Description: Used when a fixed price is required. Does not consider capacity or utilization.

Events

Integration Guidelines

Frequently Asked Questions

How are product weights determined?

Product weights are determined based on:

Effective weight ensures that actual allocation reflects current conditions, promoting fair resource distribution.

Can I create a private or public staking pool?

Yes. When creating a staking pool using createStakingPool, you can specify:

How often should effective weights be recalculated?

It's recommended to recalculate effective weights:

Regular recalculations help maintain optimal resource allocation and pricing accuracy.

How is the premium calculated?

Premiums are calculated based on:

The getPremium function encapsulates this calculation, considering all relevant factors to determine the final premium.

What is surge pricing and when does it apply?

Surge pricing is a mechanism that increases premiums when capacity usage exceeds 90%. It:

How can I update the pool metadata?

As a pool manager, you can update your pool's metadata by:

function setPoolMetadata(uint poolId, string calldata ipfsHash) external;

Note: The IPFS hash must not be empty.

Who can set or update products in a pool?

Only the pool manager can set or update products within their pool. The pool manager is assigned upon pool creation and has exclusive rights to manage the pool's products and settings.

Contact and Support

If you have questions or need assistance integrating with the StakingProducts contract or other parts of the protocol, please reach out through the official support channels or developer forums.

Disclaimer: This documentation provides a high-level overview of the StakingProducts contract's functionality. It is intended for developers integrating with the protocol and may omit internal details not relevant to external interactions. Always refer to the latest contract code and official resources