Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

RewardDistributor

Git Source

Inherits: IRewardDistributor, ReentrancyGuard

Title: RewardDistributor

Distributes staking rewards based on price discrepancy between oracle and Curve EMA.

Receives USDC from SyntheticSplitter.harvestYield() and allocates to StakedToken vaults proportionally based on which token is underperforming relative to theoretical price.

Note: security-contact: contact@plether.com

Constants

DISCREPANCY_THRESHOLD_BPS

Discrepancy threshold for 100% allocation (2% = 200 bps).

uint256 public constant DISCREPANCY_THRESHOLD_BPS = 200;

MIN_DISTRIBUTION_INTERVAL

Minimum time between distributions (1 hour).

uint256 public constant MIN_DISTRIBUTION_INTERVAL = 1 hours;

CALLER_REWARD_BPS

Reward for calling distributeRewards (0.1% = 10 bps).

uint256 public constant CALLER_REWARD_BPS = 10;

USDC_INDEX

USDC index in Curve pool.

uint256 public constant USDC_INDEX = 0;

PLDXY_BEAR_INDEX

plDXY-BEAR index in Curve pool.

uint256 public constant PLDXY_BEAR_INDEX = 1;

MAX_SWAP_SLIPPAGE_BPS

Maximum slippage for Curve swaps (1% = 100 bps).

uint256 public constant MAX_SWAP_SLIPPAGE_BPS = 100;

MAX_ORACLE_ZAP_SLIPPAGE_BPS

Maximum slippage for oracle-based zap estimates (3% = 300 bps).

Wider than MAX_SWAP_SLIPPAGE_BPS because ZapRouter’s flash mint loop adds fees.

uint256 public constant MAX_ORACLE_ZAP_SLIPPAGE_BPS = 300;

ORACLE_TIMEOUT

Maximum age for oracle price data (24 hours to match Chainlink CHF/CAD heartbeat).

uint256 public constant ORACLE_TIMEOUT = 24 hours;

SPLITTER

SyntheticSplitter contract.

ISyntheticSplitter public immutable SPLITTER;

USDC

USDC stablecoin.

IERC20 public immutable USDC;

PLDXY_BEAR

plDXY-BEAR token.

IERC20 public immutable PLDXY_BEAR;

PLDXY_BULL

plDXY-BULL token.

IERC20 public immutable PLDXY_BULL;

STAKED_BEAR

Staked plDXY-BEAR vault.

StakedToken public immutable STAKED_BEAR;

STAKED_BULL

Staked plDXY-BULL vault.

StakedToken public immutable STAKED_BULL;

CURVE_POOL

Curve USDC/plDXY-BEAR pool.

ICurvePool public immutable CURVE_POOL;

ZAP_ROUTER

ZapRouter for acquiring plDXY-BULL.

ZapRouter public immutable ZAP_ROUTER;

ORACLE

BasketOracle for theoretical price.

AggregatorV3Interface public immutable ORACLE;

PYTH_ADAPTER

Optional PythAdapter for SEK/USD price updates (address(0) if not used).

PythAdapter public immutable PYTH_ADAPTER;

INVAR_COIN

Optional InvarCoin vault that receives a share of BEAR rewards (address(0) if not used).

IInvarCoin public immutable INVAR_COIN;

CAP

Protocol CAP price (8 decimals).

uint256 public immutable CAP;

State Variables

lastDistributionTime

Timestamp of last distribution.

uint256 public lastDistributionTime;

Functions

constructor

Deploys RewardDistributor with all required dependencies.

constructor(
    address _splitter,
    address _usdc,
    address _plDxyBear,
    address _plDxyBull,
    address _stakedBear,
    address _stakedBull,
    address _curvePool,
    address _zapRouter,
    address _oracle,
    address _pythAdapter,
    address _invarCoin
);

Parameters

NameTypeDescription
_splitteraddressSyntheticSplitter contract address.
_usdcaddressUSDC token address.
_plDxyBearaddressplDXY-BEAR token address.
_plDxyBulladdressplDXY-BULL token address.
_stakedBearaddressStakedToken vault for BEAR.
_stakedBulladdressStakedToken vault for BULL.
_curvePooladdressCurve USDC/plDXY-BEAR pool.
_zapRouteraddressZapRouter for BULL acquisition.
_oracleaddressBasketOracle for price data.
_pythAdapteraddressOptional PythAdapter for SEK/USD updates (address(0) if not used).
_invarCoinaddressOptional InvarCoin vault for BEAR reward split (address(0) if not used).

receive

receive() external payable;

distributeRewards

Permissionless function to distribute accumulated USDC rewards.

Calculates price discrepancy, acquires tokens, and donates to vaults.

function distributeRewards() external nonReentrant returns (uint256 callerReward);

Returns

NameTypeDescription
callerRewarduint256Amount of USDC sent to caller as incentive.

_distributeRewardsInternal

Internal implementation of reward distribution.

function _distributeRewardsInternal() internal returns (uint256 callerReward);

_allocateRewards

function _allocateRewards(
    uint256 distributableUsdc,
    uint256 bearPct,
    uint256 bullPct
) internal pure returns (uint256 bearUsdc, uint256 bullUsdc);

_prepareBearAllocation

function _prepareBearAllocation(
    uint256 bearUsdc,
    uint256 absBasketPrice
) internal returns (uint256 stakedBearUsdc, uint256 invarUsdcAmount);

_distributeAcquiredTokens

function _distributeAcquiredTokens(
    uint256 bearAmount,
    uint256 bullAmount
) internal;

distributeRewardsWithPriceUpdate

Distributes rewards after updating the Pyth oracle price.

Bundles Pyth price update with reward distribution to save gas. Caller receives the same reward as distributeRewards().

function distributeRewardsWithPriceUpdate(
    bytes[] calldata pythUpdateData
) external payable nonReentrant returns (uint256 callerReward);

Parameters

NameTypeDescription
pythUpdateDatabytes[]Price update data from Pyth Hermes API.

Returns

NameTypeDescription
callerRewarduint256Amount of USDC sent to caller as incentive.

previewDistribution

Preview the distribution without executing.

function previewDistribution()
    external
    view
    returns (uint256 bearPct, uint256 bullPct, uint256 usdcBalance, uint256 callerReward);

Returns

NameTypeDescription
bearPctuint256Expected percentage to BEAR stakers (basis points).
bullPctuint256Expected percentage to BULL stakers (basis points).
usdcBalanceuint256Current USDC balance available for distribution.
callerRewarduint256Expected caller reward.

_calculateSplit

Calculates reward split based on price discrepancy.

function _calculateSplit(
    uint256 absBasketPrice
) internal view returns (uint256 bearPct, uint256 bullPct);

Parameters

NameTypeDescription
absBasketPriceuint256Validated basket price (8 decimals, positive).

Returns

NameTypeDescription
bearPctuint256Percentage for BEAR stakers (basis points).
bullPctuint256Percentage for BULL stakers (basis points).

_acquireTokens

Acquires tokens using optimal combination of minting and swapping/zapping.

function _acquireTokens(
    uint256 bearUsdc,
    uint256 bullUsdc,
    uint256 absBasketPrice
) internal returns (uint256 bearAmount, uint256 bullAmount);

Parameters

NameTypeDescription
bearUsdcuint256USDC allocated to BEAR acquisition.
bullUsdcuint256USDC allocated to BULL acquisition.
absBasketPriceuint256Validated basket price (8 decimals, positive).

Returns

NameTypeDescription
bearAmountuint256Amount of plDXY-BEAR acquired.
bullAmountuint256Amount of plDXY-BULL acquired.

rescueUsdc

Rescues USDC trapped after protocol liquidation.

Only callable when Splitter is SETTLED. Sends full USDC balance to Splitter treasury.

function rescueUsdc() external;

_splitBearAllocation

Splits BEAR-side USDC allocation between StakedBear and InvarCoin proportional to BEAR exposure.

function _splitBearAllocation(
    uint256 bearUsdc,
    uint256 absBasketPrice
) internal view returns (uint256 stakedUsdc, uint256 invarUsdc);

Parameters

NameTypeDescription
bearUsdcuint256Total USDC allocated to the BEAR side.
absBasketPriceuint256Validated basket price (8 decimals, positive).

_calculateMintAmount

Converts USDC amount to 18-decimal mint amount.

function _calculateMintAmount(
    uint256 usdcAmount
) internal view returns (uint256 mintAmount);

Parameters

NameTypeDescription
usdcAmountuint256USDC amount (6 decimals).

Returns

NameTypeDescription
mintAmountuint256Token amount to mint (18 decimals).