RewardDistributor
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
| Name | Type | Description |
|---|---|---|
_splitter | address | SyntheticSplitter contract address. |
_usdc | address | USDC token address. |
_plDxyBear | address | plDXY-BEAR token address. |
_plDxyBull | address | plDXY-BULL token address. |
_stakedBear | address | StakedToken vault for BEAR. |
_stakedBull | address | StakedToken vault for BULL. |
_curvePool | address | Curve USDC/plDXY-BEAR pool. |
_zapRouter | address | ZapRouter for BULL acquisition. |
_oracle | address | BasketOracle for price data. |
_pythAdapter | address | Optional PythAdapter for SEK/USD updates (address(0) if not used). |
_invarCoin | address | Optional 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
| Name | Type | Description |
|---|---|---|
callerReward | uint256 | Amount of USDC sent to caller as incentive. |
_distributeRewardsInternal
Internal implementation of reward distribution.
function _distributeRewardsInternal() internal returns (uint256 callerReward);
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
| Name | Type | Description |
|---|---|---|
pythUpdateData | bytes[] | Price update data from Pyth Hermes API. |
Returns
| Name | Type | Description |
|---|---|---|
callerReward | uint256 | Amount 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
| Name | Type | Description |
|---|---|---|
bearPct | uint256 | Expected percentage to BEAR stakers (basis points). |
bullPct | uint256 | Expected percentage to BULL stakers (basis points). |
usdcBalance | uint256 | Current USDC balance available for distribution. |
callerReward | uint256 | Expected caller reward. |
_calculateSplit
Calculates reward split based on price discrepancy.
function _calculateSplit(
uint256 absBasketPrice
) internal view returns (uint256 bearPct, uint256 bullPct);
Parameters
| Name | Type | Description |
|---|---|---|
absBasketPrice | uint256 | Validated basket price (8 decimals, positive). |
Returns
| Name | Type | Description |
|---|---|---|
bearPct | uint256 | Percentage for BEAR stakers (basis points). |
bullPct | uint256 | Percentage 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
| Name | Type | Description |
|---|---|---|
bearUsdc | uint256 | USDC allocated to BEAR acquisition. |
bullUsdc | uint256 | USDC allocated to BULL acquisition. |
absBasketPrice | uint256 | Validated basket price (8 decimals, positive). |
Returns
| Name | Type | Description |
|---|---|---|
bearAmount | uint256 | Amount of plDXY-BEAR acquired. |
bullAmount | uint256 | Amount 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
| Name | Type | Description |
|---|---|---|
bearUsdc | uint256 | Total USDC allocated to the BEAR side. |
absBasketPrice | uint256 | Validated basket price (8 decimals, positive). |
_calculateMintAmount
Converts USDC amount to 18-decimal mint amount.
function _calculateMintAmount(
uint256 usdcAmount
) internal view returns (uint256 mintAmount);
Parameters
| Name | Type | Description |
|---|---|---|
usdcAmount | uint256 | USDC amount (6 decimals). |
Returns
| Name | Type | Description |
|---|---|---|
mintAmount | uint256 | Token amount to mint (18 decimals). |