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

SyntheticSplitter

Git Source

Inherits: ISyntheticSplitter, Ownable2Step, Pausable, ReentrancyGuard

Title: SyntheticSplitter

Core protocol contract for minting/burning synthetic plDXY tokens.

Accepts USDC collateral to mint equal amounts of plDXY-BEAR + plDXY-BULL tokens. Maintains 10% liquidity buffer locally, 90% deployed to yield adapters. Three lifecycle states: ACTIVE → PAUSED → SETTLED (liquidated).

State Variables

TOKEN_A

SyntheticToken public immutable TOKEN_A

TOKEN_B

SyntheticToken public immutable TOKEN_B

USDC

IERC20 public immutable USDC

ORACLE

AggregatorV3Interface public immutable ORACLE

CAP

uint256 public immutable CAP

USDC_MULTIPLIER

uint256 public immutable USDC_MULTIPLIER

BUFFER_PERCENT

uint256 public constant BUFFER_PERCENT = 10

yieldAdapter

IERC4626 public yieldAdapter

pendingAdapter

address public pendingAdapter

adapterActivationTime

uint256 public adapterActivationTime

treasury

address public treasury

staking

address public staking

pendingFees

FeeConfig public pendingFees

feesActivationTime

uint256 public feesActivationTime

ORACLE_TIMEOUT

uint256 public constant ORACLE_TIMEOUT = 8 hours

TIMELOCK_DELAY

uint256 public constant TIMELOCK_DELAY = 7 days

lastUnpauseTime

uint256 public lastUnpauseTime

HARVEST_REWARD_BPS

uint256 public constant HARVEST_REWARD_BPS = 10

MIN_SURPLUS_THRESHOLD

uint256 public constant MIN_SURPLUS_THRESHOLD = 50 * 1e6

isLiquidated

bool public isLiquidated

SEQUENCER_UPTIME_FEED

AggregatorV3Interface public immutable SEQUENCER_UPTIME_FEED

SEQUENCER_GRACE_PERIOD

uint256 public constant SEQUENCER_GRACE_PERIOD = 1 hours

Functions

constructor

Deploys the SyntheticSplitter and creates plDXY-BEAR and plDXY-BULL tokens.

constructor(
    address _oracle,
    address _usdc,
    address _yieldAdapter,
    uint256 _cap,
    address _treasury,
    address _sequencerUptimeFeed
) Ownable(msg.sender);

Parameters

NameTypeDescription
_oracleaddressChainlink-compatible price feed for plDXY basket.
_usdcaddressUSDC token address (6 decimals).
_yieldAdapteraddressERC4626-compliant yield adapter for USDC deposits.
_capuint256Maximum plDXY price (8 decimals). Triggers liquidation when breached.
_treasuryaddressTreasury address for fee distribution.
_sequencerUptimeFeedaddressL2 sequencer uptime feed (address(0) for L1/testnets).

previewMint

Simulates a mint to see required USDC input

function previewMint(
    uint256 mintAmount
) external view returns (uint256 usdcRequired, uint256 depositToAdapter, uint256 keptInBuffer);

Parameters

NameTypeDescription
mintAmountuint256The amount of TokenA/B the user wants to mint

Returns

NameTypeDescription
usdcRequireduint256Total USDC needed from user
depositToAdapteruint256Amount that will be sent to Yield Source
keptInBufferuint256Amount that will stay in Splitter contract

mint

Mint plDXY-BEAR and plDXY-BULL tokens by depositing USDC collateral.

function mint(
    uint256 amount
) external nonReentrant whenNotPaused;

Parameters

NameTypeDescription
amountuint256The amount of token pairs to mint (18 decimals).

previewBurn

Simulates a burn to see USDC return

function previewBurn(
    uint256 burnAmount
) external view returns (uint256 usdcRefund, uint256 withdrawnFromAdapter);

Parameters

NameTypeDescription
burnAmountuint256The amount of TokenA/B the user wants to burn

Returns

NameTypeDescription
usdcRefunduint256Total USDC user will receive
withdrawnFromAdapteruint256Amount pulled from Yield Source to cover shortage

burn

Burn plDXY-BEAR and plDXY-BULL tokens to redeem USDC collateral.

function burn(
    uint256 amount
) external nonReentrant;

Parameters

NameTypeDescription
amountuint256The amount of token pairs to burn (18 decimals).

_withdrawFromAdapter

Withdraws USDC from yield adapter with redeem fallback.

function _withdrawFromAdapter(
    uint256 amount
) internal;

Parameters

NameTypeDescription
amountuint256USDC amount to withdraw (6 decimals).

triggerLiquidation

Locks the protocol into liquidated state when price >= CAP.

Permissionless. Prevents system revival if price drops after breach.

function triggerLiquidation() external nonReentrant;

emergencyRedeem

Emergency redemption when protocol is liquidated (price >= CAP).

Only burns plDXY-BEAR tokens at CAP price. plDXY-BULL becomes worthless.

function emergencyRedeem(
    uint256 amount
) external nonReentrant;

Parameters

NameTypeDescription
amountuint256The amount of plDXY-BEAR tokens to redeem (18 decimals).

ejectLiquidity

Emergency exit: withdraws all funds from yield adapter.

Bypasses timelock. Auto-pauses protocol. Use if adapter is compromised.

function ejectLiquidity() external onlyOwner;

withdrawFromAdapter

Withdraws a specific amount from yield adapter while paused.

Requires protocol to be paused. Use for gradual liquidity extraction when full ejectLiquidity() fails due to adapter liquidity constraints.

function withdrawFromAdapter(
    uint256 amount
) external nonReentrant onlyOwner;

Parameters

NameTypeDescription
amountuint256Desired USDC amount to withdraw. Capped by adapter’s maxWithdraw.

previewHarvest

Previews yield harvest amounts and eligibility.

function previewHarvest()
    external
    view
    returns (
        bool canHarvest,
        uint256 totalSurplus,
        uint256 callerReward,
        uint256 treasuryShare,
        uint256 stakingShare
    );

Returns

NameTypeDescription
canHarvestboolTrue if surplus exceeds MIN_SURPLUS_THRESHOLD.
totalSurplusuint256Available surplus (total assets - liabilities).
callerRewarduint256Caller incentive (0.1% of harvest).
treasuryShareuint256Treasury allocation (20% of remaining).
stakingShareuint256Staking allocation (79.9% of remaining).

harvestYield

Permissionless yield harvesting from the adapter.

Distributes surplus: 0.1% to caller, 20% to treasury, 79.9% to staking.

function harvestYield() external nonReentrant whenNotPaused;

_checkLiveness

Enforces 7-day cooldown after unpause for governance actions.

function _checkLiveness() internal view;

proposeFeeReceivers

Propose new fee receiver addresses (7-day timelock).

function proposeFeeReceivers(
    address _treasury,
    address _staking
) external onlyOwner;

Parameters

NameTypeDescription
_treasuryaddressNew treasury address.
_stakingaddressNew staking address (can be zero to send all to treasury).

finalizeFeeReceivers

Finalize pending fee receiver change after timelock expires.

function finalizeFeeReceivers() external onlyOwner;

proposeAdapter

Propose a new yield adapter (7-day timelock).

function proposeAdapter(
    address _newAdapter
) external onlyOwner;

Parameters

NameTypeDescription
_newAdapteraddressAddress of the new ERC4626-compliant adapter.

finalizeAdapter

Finalize adapter migration after timelock. Migrates all funds atomically.

function finalizeAdapter() external nonReentrant onlyOwner;

pause

Pause the protocol. Blocks minting and harvesting.

function pause() external onlyOwner;

unpause

Unpause the protocol. Starts 7-day governance cooldown.

function unpause() external onlyOwner;

rescueToken

Rescue accidentally sent tokens. Cannot rescue core assets.

function rescueToken(
    address token,
    address to
) external onlyOwner;

Parameters

NameTypeDescription
tokenaddressThe ERC20 token to rescue.
toaddressThe recipient address.

currentStatus

Returns the current protocol lifecycle status.

function currentStatus() external view override returns (Status);

Returns

NameTypeDescription
<none>StatusThe current Status enum value (ACTIVE, PAUSED, or SETTLED).

getSystemStatus

Returns comprehensive system metrics for dashboards.

function getSystemStatus() external view returns (SystemStatus memory status);

Returns

NameTypeDescription
statusSystemStatusStruct containing price, collateral ratio, and liquidity data.

_getTotalLiabilities

Calculates total liabilities based on TOKEN_A supply at CAP price.

function _getTotalLiabilities() internal view returns (uint256);

_getTotalAssets

Calculates total assets (local USDC + adapter value).

function _getTotalAssets() internal view returns (uint256);

_requireSolventIfPaused

Reverts if paused and insolvent (assets < liabilities).

function _requireSolventIfPaused() internal view;

_getOraclePrice

Oracle price validation using OracleLib.

function _getOraclePrice() internal view returns (uint256);

Events

Minted

event Minted(address indexed user, uint256 amount);

Burned

event Burned(address indexed user, uint256 amount);

AdapterProposed

event AdapterProposed(address indexed newAdapter, uint256 activationTime);

AdapterMigrated

event AdapterMigrated(address indexed oldAdapter, address indexed newAdapter, uint256 transferredAmount);

LiquidationTriggered

event LiquidationTriggered(uint256 price);

EmergencyRedeemed

event EmergencyRedeemed(address indexed user, uint256 amount);

YieldHarvested

event YieldHarvested(uint256 totalSurplus, uint256 treasuryAmt, uint256 stakingAmt);

FeesProposed

event FeesProposed(address indexed treasury, address indexed staking, uint256 activationTime);

FeesUpdated

event FeesUpdated(address indexed treasury, address indexed staking);

EmergencyEjected

event EmergencyEjected(uint256 amountRecovered);

AdapterWithdrawn

event AdapterWithdrawn(uint256 requested, uint256 withdrawn);

TokenRescued

event TokenRescued(address indexed token, address indexed to, uint256 amount);

Errors

Splitter__ZeroAddress

error Splitter__ZeroAddress();

Splitter__InvalidCap

error Splitter__InvalidCap();

Splitter__ZeroAmount

error Splitter__ZeroAmount();

Splitter__ZeroRefund

error Splitter__ZeroRefund();

Splitter__AdapterNotSet

error Splitter__AdapterNotSet();

Splitter__AdapterInsufficientLiquidity

error Splitter__AdapterInsufficientLiquidity();

Splitter__LiquidationActive

error Splitter__LiquidationActive();

Splitter__NotLiquidated

error Splitter__NotLiquidated();

Splitter__TimelockActive

error Splitter__TimelockActive();

Splitter__InvalidProposal

error Splitter__InvalidProposal();

Splitter__NoSurplus

error Splitter__NoSurplus();

Splitter__GovernanceLocked

error Splitter__GovernanceLocked();

Splitter__InsufficientHarvest

error Splitter__InsufficientHarvest();

Splitter__AdapterWithdrawFailed

error Splitter__AdapterWithdrawFailed();

Splitter__Insolvent

error Splitter__Insolvent();

Splitter__NotPaused

error Splitter__NotPaused();

Splitter__CannotRescueCoreAsset

error Splitter__CannotRescueCoreAsset();

Splitter__MigrationLostFunds

error Splitter__MigrationLostFunds();

Structs

FeeConfig

struct FeeConfig {
    address treasuryAddr;
    address stakingAddr;
}

SystemStatus

struct SystemStatus {
    uint256 currentPrice;
    uint256 capPrice;
    bool liquidated;
    bool isPaused;
    uint256 totalAssets; // Local + Adapter
    uint256 totalLiabilities; // Bear Supply * CAP
    uint256 collateralRatio; // Basis points
    uint256 adapterAssets; // USDC value held in yield adapter
}