All files position.ts

100% Statements 31/31
100% Branches 18/18
100% Functions 2/2
100% Lines 31/31

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81              1x                         1x 16x 2x 2x   16x 2x 2x   16x   1x 1x     11x 11x     11x     11x 11x                         1x 10x 2x 2x   10x 2x 2x   10x   1x 1x     5x 5x     5x     5x 5x  
/**
 * Position profit calculations for Harberger staking.
 *
 * Positions earn profit through their proportional share of new token issuance.
 * This aligns with the Harberger tax economic model where stakers earn from protocol growth.
 */
 
import { formatUnits } from 'viem';
 
/**
 * Calculate profit for an active position.
 *
 * Active positions earn their proportional share of all new tokens minted
 * since the position was created.
 *
 * @param totalSupplyInit - Total token supply when position was created
 * @param currentTotalSupply - Current total token supply
 * @param positionShare - Position's proportional share (0-1)
 * @returns Profit in token units (not wei)
 */
export function calculateActivePositionProfit(totalSupplyInit: bigint, currentTotalSupply: bigint, positionShare: number): number {
  if (totalSupplyInit < 0n || currentTotalSupply < 0n) {
    throw new Error('Supply values must be non-negative');
  }
 
  if (positionShare < 0 || positionShare > 1) {
    throw new Error('Position share must be between 0 and 1');
  }
 
  if (currentTotalSupply < totalSupplyInit) {
    // If supply decreased (shouldn't happen in normal operation), return 0
    return 0;
  }
 
  // Convert to token units (assuming 18 decimals)
  const initSupply = Number(formatUnits(totalSupplyInit, 18));
  const currentSupply = Number(formatUnits(currentTotalSupply, 18));
 
  // Calculate new issuance since position creation
  const newIssuance = currentSupply - initSupply;
 
  // Position earns its share of new issuance
  return newIssuance * positionShare;
}
 
/**
 * Calculate profit for a closed position.
 *
 * Closed positions earned their proportional share of all new tokens minted
 * during the position's lifetime (from creation to closure).
 *
 * @param totalSupplyInit - Total token supply when position was created
 * @param totalSupplyEnd - Total token supply when position was closed
 * @param positionShare - Position's proportional share (0-1)
 * @returns Profit in token units (not wei)
 */
export function calculateClosedPositionProfit(totalSupplyInit: bigint, totalSupplyEnd: bigint, positionShare: number): number {
  if (totalSupplyInit < 0n || totalSupplyEnd < 0n) {
    throw new Error('Supply values must be non-negative');
  }
 
  if (positionShare < 0 || positionShare > 1) {
    throw new Error('Position share must be between 0 and 1');
  }
 
  if (totalSupplyEnd < totalSupplyInit) {
    // If supply decreased during position lifetime, return 0
    return 0;
  }
 
  // Convert to token units (assuming 18 decimals)
  const initSupply = Number(formatUnits(totalSupplyInit, 18));
  const endSupply = Number(formatUnits(totalSupplyEnd, 18));
 
  // Calculate new issuance during position lifetime
  const newIssuance = endSupply - initSupply;
 
  // Position earned its share of new issuance
  return newIssuance * positionShare;
}