ZapRouter
Inherits: FlashLoanBase, Ownable2Step, Pausable, ReentrancyGuard
Title: ZapRouter
Efficient router for acquiring plDXY-BULL tokens using flash mints.
Primary path: flash mints plDXY-BEAR → swaps to USDC via Curve → mints pairs → keeps plDXY-BULL. Fallback (direct) path: when BEAR is overpriced on Curve and the flash path can’t close, mints pairs with user USDC → sells all BEAR on Curve → sends BULL + USDC refund to user. For plDXY-BEAR, users should swap directly on Curve instead.
Note: security-contact: contact@plether.com
Constants
MAX_SLIPPAGE_BPS
Maximum allowed slippage in basis points (1% = 100 bps).
uint256 public constant MAX_SLIPPAGE_BPS = 100
SAFETY_BUFFER_BPS
Safety buffer for flash loan repayment calculations (0.5% = 50 bps).
uint256 public constant SAFETY_BUFFER_BPS = 50
USDC_INDEX
USDC index in the Curve USDC/plDXY-BEAR pool.
uint256 public constant USDC_INDEX = 0
PLDXY_BEAR_INDEX
plDXY-BEAR index in the Curve USDC/plDXY-BEAR pool.
uint256 public constant PLDXY_BEAR_INDEX = 1
SPLITTER
SyntheticSplitter contract for minting/burning pairs.
ISyntheticSplitter public immutable SPLITTER
PLDXY_BEAR
plDXY-BEAR token (flash minted for swaps).
IERC20 public immutable PLDXY_BEAR
PLDXY_BULL
plDXY-BULL token (output of zap operations).
IERC20 public immutable PLDXY_BULL
USDC
USDC stablecoin.
IERC20 public immutable USDC
CURVE_POOL
Curve pool for USDC/plDXY-BEAR swaps.
ICurvePool public immutable CURVE_POOL
CAP
Protocol CAP price (8 decimals, oracle format).
uint256 public immutable CAP
CAP_PRICE
CAP price scaled for Curve comparison (6 decimals).
uint256 public immutable CAP_PRICE
ACTION_MINT
Flash loan action: mint plDXY-BULL.
uint256 private constant ACTION_MINT = 0
ACTION_BURN
Flash loan action: burn plDXY-BULL.
uint256 private constant ACTION_BURN = 1
Functions
constructor
Deploys ZapRouter with required protocol dependencies.
constructor(
address _splitter,
address _plDxyBear,
address _plDxyBull,
address _usdc,
address _curvePool
) Ownable(msg.sender);
Parameters
| Name | Type | Description |
|---|---|---|
_splitter | address | SyntheticSplitter contract address. |
_plDxyBear | address | plDXY-BEAR token address. |
_plDxyBull | address | plDXY-BULL token address. |
_usdc | address | USDC token address. |
_curvePool | address | Curve USDC/plDXY-BEAR pool address. |
zapMint
Buy plDXY-BULL using USDC with flash mint efficiency.
For plDXY-BEAR, swap directly on Curve instead.
function zapMint(
uint256 usdcAmount,
uint256 minAmountOut,
uint256 maxSlippageBps,
uint256 deadline
) external nonReentrant whenNotPaused;
Parameters
| Name | Type | Description |
|---|---|---|
usdcAmount | uint256 | The amount of USDC the user is sending. |
minAmountOut | uint256 | Minimum amount of plDXY-BULL tokens to receive. |
maxSlippageBps | uint256 | Maximum slippage tolerance in basis points (e.g., 100 = 1%). Capped at MAX_SLIPPAGE_BPS (1%) to limit MEV extraction. |
deadline | uint256 | Unix timestamp after which the transaction reverts. |
zapMintWithPermit
Buy plDXY-BULL using USDC with a permit signature (gasless approval).
function zapMintWithPermit(
uint256 usdcAmount,
uint256 minAmountOut,
uint256 maxSlippageBps,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external nonReentrant whenNotPaused;
Parameters
| Name | Type | Description |
|---|---|---|
usdcAmount | uint256 | The amount of USDC the user is sending. |
minAmountOut | uint256 | Minimum amount of plDXY-BULL tokens to receive. |
maxSlippageBps | uint256 | Maximum slippage tolerance in basis points. |
deadline | uint256 | Unix timestamp after which the permit and transaction revert. |
v | uint8 | Signature recovery byte. |
r | bytes32 | Signature r component. |
s | bytes32 | Signature s component. |
_zapMintCore
function _zapMintCore(
uint256 usdcAmount,
uint256 minAmountOut,
uint256 maxSlippageBps,
uint256 deadline
) internal;
zapBurn
Sell plDXY-BULL tokens for USDC using flash mint efficiency.
function zapBurn(
uint256 bullAmount,
uint256 minUsdcOut,
uint256 deadline
) external nonReentrant whenNotPaused;
Parameters
| Name | Type | Description |
|---|---|---|
bullAmount | uint256 | Amount of plDXY-BULL to sell. |
minUsdcOut | uint256 | Minimum USDC to receive (slippage protection). |
deadline | uint256 | Unix timestamp after which the transaction reverts. |
zapBurnWithPermit
Sell plDXY-BULL tokens for USDC with a permit signature (gasless approval).
function zapBurnWithPermit(
uint256 bullAmount,
uint256 minUsdcOut,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external nonReentrant whenNotPaused;
Parameters
| Name | Type | Description |
|---|---|---|
bullAmount | uint256 | Amount of plDXY-BULL to sell. |
minUsdcOut | uint256 | Minimum USDC to receive (slippage protection). |
deadline | uint256 | Unix timestamp after which the transaction reverts. |
v | uint8 | Signature recovery byte. |
r | bytes32 | Signature r component. |
s | bytes32 | Signature s component. |
_zapBurnCore
function _zapBurnCore(
uint256 bullAmount,
uint256 minUsdcOut,
uint256 deadline
) internal;
onFlashLoan
ERC-3156 flash loan callback. Routes to mint or burn handler.
function onFlashLoan(
address initiator,
address,
uint256 amount,
uint256 fee,
bytes calldata data
) external override returns (bytes32);
Parameters
| Name | Type | Description |
|---|---|---|
initiator | address | Address that initiated the flash loan (must be this contract). |
<none> | address | |
amount | uint256 | Amount of plDXY-BEAR borrowed. |
fee | uint256 | Flash loan fee (always 0 for SyntheticToken). |
data | bytes | Encoded operation parameters. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes32 | CALLBACK_SUCCESS on successful execution. |
onMorphoFlashLoan
Morpho flash loan callback - not used by ZapRouter.
Always reverts as ZapRouter only uses ERC-3156 flash mints.
function onMorphoFlashLoan(
uint256,
bytes calldata
) external pure override;
_handleMint
Executes mint operation within flash loan callback.
function _handleMint(
uint256 loanAmount,
uint256 fee,
bytes calldata data
) internal;
Parameters
| Name | Type | Description |
|---|---|---|
loanAmount | uint256 | Amount of plDXY-BEAR borrowed. |
fee | uint256 | Flash loan fee (always 0). |
data | bytes | Encoded mint parameters (action, user, usdcAmount, minSwapOut, minAmountOut, maxSlippageBps). |
_handleBurn
Executes burn operation within flash loan callback.
function _handleBurn(
uint256 loanAmount,
uint256 fee,
bytes calldata data
) internal;
Parameters
| Name | Type | Description |
|---|---|---|
loanAmount | uint256 | Amount of plDXY-BEAR borrowed. |
fee | uint256 | Flash loan fee (always 0). |
data | bytes | Encoded burn parameters (action, user, bullAmount, minUsdcOut). |
_zapMintDirect
Mints pairs, sells BEAR on Curve, sends BULL + USDC refund to user.
Used when the flash path can’t close (BEAR overpriced or high price impact).
function _zapMintDirect(
uint256 usdcAmount,
uint256 minAmountOut,
uint256 maxSlippageBps
) private;
previewZapMint
Preview the result of a zapMint operation.
When flashAmount == 0, the direct path is used: expectedSwapOut is the USDC refund from selling minted BEAR, and totalUSDC equals usdcAmount (no flash leverage).
function previewZapMint(
uint256 usdcAmount
)
external
view
returns (
uint256 flashAmount,
uint256 expectedSwapOut,
uint256 totalUSDC,
uint256 expectedTokensOut,
uint256 flashFee
);
Parameters
| Name | Type | Description |
|---|---|---|
usdcAmount | uint256 | The amount of USDC the user will send. |
Returns
| Name | Type | Description |
|---|---|---|
flashAmount | uint256 | Amount of plDXY-BEAR to flash mint (0 signals direct path). |
expectedSwapOut | uint256 | Expected USDC from swap (flash: contributes to minting; direct: refund to user). |
totalUSDC | uint256 | Total USDC for minting pairs (flash: user + swap; direct: user only). |
expectedTokensOut | uint256 | Expected plDXY-BULL tokens to receive. |
flashFee | uint256 | Flash mint fee (0 for direct path). |
previewZapBurn
Preview the result of a zapBurn operation.
function previewZapBurn(
uint256 bullAmount
)
external
view
returns (uint256 expectedUsdcFromBurn, uint256 usdcForBearBuyback, uint256 expectedUsdcOut, uint256 flashFee);
Parameters
| Name | Type | Description |
|---|---|---|
bullAmount | uint256 | The amount of plDXY-BULL tokens to sell. |
Returns
| Name | Type | Description |
|---|---|---|
expectedUsdcFromBurn | uint256 | USDC received from burning pairs via Splitter. |
usdcForBearBuyback | uint256 | USDC needed to buy back plDXY-BEAR for flash loan repayment. |
expectedUsdcOut | uint256 | Net USDC the user will receive. |
flashFee | uint256 | Flash mint fee (if any). |
_estimateUsdcForBearBuyback
function _estimateUsdcForBearBuyback(
uint256 bearAmount
) private view returns (uint256);
pause
Pause the router. Blocks zapMint and zapBurn.
function pause() external onlyOwner;
unpause
Unpause the router.
function unpause() external onlyOwner;
Events
ZapMint
Emitted when user acquires plDXY-BULL via zapMint.
event ZapMint(
address indexed user,
uint256 usdcIn,
uint256 tokensOut,
uint256 maxSlippageBps,
uint256 actualSwapOut,
uint256 usdcRefund
);
ZapBurn
Emitted when user sells plDXY-BULL via zapBurn.
event ZapBurn(address indexed user, uint256 tokensIn, uint256 usdcOut);
Errors
ZapRouter__ZeroAddress
error ZapRouter__ZeroAddress();
ZapRouter__ZeroAmount
error ZapRouter__ZeroAmount();
ZapRouter__Expired
error ZapRouter__Expired();
ZapRouter__SlippageExceedsMax
error ZapRouter__SlippageExceedsMax();
ZapRouter__SplitterNotActive
error ZapRouter__SplitterNotActive();
ZapRouter__InsufficientOutput
error ZapRouter__InsufficientOutput();
ZapRouter__SolvencyBreach
error ZapRouter__SolvencyBreach();
ZapRouter__PermitFailed
error ZapRouter__PermitFailed();