Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/reserve-protocol/reserve-index-dtf/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The FolioLens contract provides convenient read-only functions for analyzing Folio state. It’s designed for off-chain use by frontends, analytics tools, and indexers. These functions are gas-intensive and should not be called on-chain.

Key Features

  • Spot Weight Calculation: Compute current token weights from balances
  • Batch Bid Queries: Get all auction bids at once
  • Surplus/Deficit Analysis: Calculate which tokens need buying or selling
  • Off-Chain Optimized: Not intended for on-chain calls
FolioLens functions are designed for off-chain analysis only. Do not call these functions from other smart contracts as they may consume excessive gas.

Analysis Functions

Get Spot Weights

Calculate token weights based on current Folio balances.
folio
Folio
Folio contract to analyze
FolioLens.sol
function getSpotWeights(
    Folio folio
) external view returns (
    address[] memory tokens,
    uint256[] memory weights
)
Returns:
  • tokens: Array of token addresses in the basket
  • weights: Token weights in D27 format (tokens per share)
Weights are calculated as: (D27 * tokenBalance) / totalSupply. This gives the actual composition by current holdings, which may differ from target weights during rebalancing.

Get All Bids

Retrieve all possible bids for an auction in a single call.
folio
Folio
Folio contract with active auction
auctionId
uint256
ID of the auction to query
FolioLens.sol
function getAllBids(
    Folio folio,
    uint256 auctionId
) external view returns (SingleBid[] memory bids)
Returns:
  • Array of SingleBid structs for all valid token pairs
This function attempts to call getBid() for all N² token pairs. Invalid pairs (those that would revert) are filtered out. Only returns bids with non-zero amounts.

Surpluses and Deficits

Calculate which tokens are over/under the target limits.
folio
Folio
Folio contract to analyze
sellLimit
uint256
Upper BU limit for selling (D18 format)
buyLimit
uint256
Lower BU limit for buying (D18 format)
FolioLens.sol
function surplusesAndDeficits(
    Folio folio,
    uint256 sellLimit,
    uint256 buyLimit
) external view returns (
    address[] memory tokens,
    uint256[] memory surpluses,
    uint256[] memory deficits
)
Returns:
  • tokens: Array of token addresses
  • surpluses: Amount above sell limit for each token (0 if not surplus)
  • deficits: Amount below buy limit for each token (0 if not deficit)
Requires sellLimit >= buyLimit. A token cannot have both a surplus and deficit - if one is non-zero, the other is always zero.

Data Structures

SingleBid

Represents a single auction bid for a token pair.
sellToken
address
Token being sold by the Folio
buyToken
address
Token being bought by the Folio
sellAmount
uint256
Amount of sell token available
bidAmount
uint256
Amount of buy token required
price
uint256
Price in D27 format (buyTok/sellTok)
struct SingleBid {
    address sellToken;
    address buyToken;
    uint256 sellAmount;  // {sellTok}
    uint256 bidAmount;   // {buyTok}
    uint256 price;       // D27{buyTok/sellTok}
}

Usage Examples

Analyze Current Composition

// Get current token weights
(address[] memory tokens, uint256[] memory weights) = 
    lens.getSpotWeights(folio);

for (uint256 i = 0; i < tokens.length; i++) {
    // weights[i] is in D27 format
    // Divide by 1e27 to get tokens per share
    uint256 tokensPerShare = weights[i] / 1e27;
}

Find Best Auction Bids

// Get all bids for current auction
FolioLens.SingleBid[] memory bids = lens.getAllBids(folio, auctionId);

for (uint256 i = 0; i < bids.length; i++) {
    FolioLens.SingleBid memory bid = bids[i];
    
    // Calculate price impact
    uint256 priceImpact = calculatePriceImpact(
        bid.sellToken,
        bid.buyToken,
        bid.price
    );
    
    // Execute profitable bids
    if (isProfitable(priceImpact)) {
        folio.bid(
            auctionId,
            IERC20(bid.sellToken),
            IERC20(bid.buyToken),
            bid.sellAmount,
            bid.bidAmount,
            false,
            ""
        );
    }
}

Calculate Rebalancing Needs

// Get current rebalance limits
(, , , IFolio.RebalanceLimits memory limits, , ) = folio.getRebalance();

// Calculate surpluses and deficits
(
    address[] memory tokens,
    uint256[] memory surpluses,
    uint256[] memory deficits
) = lens.surplusesAndDeficits(folio, limits.high, limits.low);

for (uint256 i = 0; i < tokens.length; i++) {
    if (surpluses[i] > 0) {
        // Token needs to be sold
        console.log("Sell", surpluses[i], "of", tokens[i]);
    } else if (deficits[i] > 0) {
        // Token needs to be bought
        console.log("Buy", deficits[i], "of", tokens[i]);
    }
}

Constants

D18
uint256
default:"1e18"
18-decimal fixed point scaling factor
D27
uint256
default:"1e27"
27-decimal fixed point scaling factor (used for weights and prices)

Integration Notes

Frontend Integration: Use these functions via eth_call (read-only RPC calls). Never send transactions to FolioLens.
Indexing: These functions are useful for building subgraphs or analytics dashboards. Call them periodically to track Folio state changes.
The getAllBids() function may be expensive for Folios with many tokens (N² complexity). Consider using pagination or filtering for large baskets.

Error Handling

Functions use try/catch to gracefully handle invalid states:
try folio.getBid(...) returns (...) {
    // Process valid bid
} catch {
    // Skip invalid pair
}
This ensures functions don’t revert on temporary invalid states (e.g., ended auctions, removed tokens).

Build docs developers (and LLMs) love