SyntheticSplitter
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
| Name | Type | Description |
|---|---|---|
_oracle | address | Chainlink-compatible price feed for plDXY basket. |
_usdc | address | USDC token address (6 decimals). |
_yieldAdapter | address | ERC4626-compliant yield adapter for USDC deposits. |
_cap | uint256 | Maximum plDXY price (8 decimals). Triggers liquidation when breached. |
_treasury | address | Treasury address for fee distribution. |
_sequencerUptimeFeed | address | L2 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
| Name | Type | Description |
|---|---|---|
mintAmount | uint256 | The amount of TokenA/B the user wants to mint |
Returns
| Name | Type | Description |
|---|---|---|
usdcRequired | uint256 | Total USDC needed from user |
depositToAdapter | uint256 | Amount that will be sent to Yield Source |
keptInBuffer | uint256 | Amount 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
| Name | Type | Description |
|---|---|---|
amount | uint256 | The 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
| Name | Type | Description |
|---|---|---|
burnAmount | uint256 | The amount of TokenA/B the user wants to burn |
Returns
| Name | Type | Description |
|---|---|---|
usdcRefund | uint256 | Total USDC user will receive |
withdrawnFromAdapter | uint256 | Amount 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
| Name | Type | Description |
|---|---|---|
amount | uint256 | The amount of token pairs to burn (18 decimals). |
_withdrawFromAdapter
Withdraws USDC from yield adapter with redeem fallback.
function _withdrawFromAdapter(
uint256 amount
) internal;
Parameters
| Name | Type | Description |
|---|---|---|
amount | uint256 | USDC 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
| Name | Type | Description |
|---|---|---|
amount | uint256 | The 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
| Name | Type | Description |
|---|---|---|
amount | uint256 | Desired 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
| Name | Type | Description |
|---|---|---|
canHarvest | bool | True if surplus exceeds MIN_SURPLUS_THRESHOLD. |
totalSurplus | uint256 | Available surplus (total assets - liabilities). |
callerReward | uint256 | Caller incentive (0.1% of harvest). |
treasuryShare | uint256 | Treasury allocation (20% of remaining). |
stakingShare | uint256 | Staking 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
| Name | Type | Description |
|---|---|---|
_treasury | address | New treasury address. |
_staking | address | New 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
| Name | Type | Description |
|---|---|---|
_newAdapter | address | Address 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
| Name | Type | Description |
|---|---|---|
token | address | The ERC20 token to rescue. |
to | address | The recipient address. |
currentStatus
Returns the current protocol lifecycle status.
function currentStatus() external view override returns (Status);
Returns
| Name | Type | Description |
|---|---|---|
<none> | Status | The current Status enum value (ACTIVE, PAUSED, or SETTLED). |
getSystemStatus
Returns comprehensive system metrics for dashboards.
function getSystemStatus() external view returns (SystemStatus memory status);
Returns
| Name | Type | Description |
|---|---|---|
status | SystemStatus | Struct 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
}