Router
The Router serves as a central entry point for user interactions with the Satoshi Perps protocol. It manages plugins, handles token approvals, and provides functionality for token swapping and position modifications through authorized plugins.
Contract Overview
The Router handles:
Managing plugin registrations and permissions
Handling token approvals for the Vault
Wrapping and unwrapping ETH for interactions
Providing interfaces for plugins to modify positions
Facilitating token swaps through the Vault
The Router uses a plugin-based architecture to allow modular extensions of functionality while maintaining security.
Key Functions
Plugin Management
function addPlugin ( address _plugin ) external ;
Allows users to register a plugin address that can execute actions on their behalf.
function removePlugin ( address _plugin ) external ;
Removes a previously registered plugin.
Token Approvals
function approvePlugin ( address _plugin ) external ;
Approves a plugin to use the user’s tokens via the Router.
function approvePlugin ( address _token , address _spender ) external ;
Approves a specific token to be spent by the specified spender.
Position Management via Plugins
function pluginIncreasePosition (
address _account ,
address _collateralToken ,
address _indexToken ,
uint256 _sizeDelta ,
bool _isLong
) external ;
Allows an authorized plugin to increase a position for the specified account.
function pluginDecreasePosition (
address _account ,
address _collateralToken ,
address _indexToken ,
uint256 _collateralDelta ,
uint256 _sizeDelta ,
bool _isLong ,
address _receiver
) external returns ( uint256 );
Allows an authorized plugin to decrease a position for the specified account.
Token Swapping
function swap (
address [] memory _path ,
uint256 _amountIn ,
uint256 _minOut ,
address _receiver
) external ;
Swaps tokens through the Vault’s swap mechanism.
function swapETHToTokens (
address [] memory _path ,
uint256 _minOut ,
address _receiver
) external payable ;
Swaps ETH to tokens through the Vault’s swap mechanism.
Plugin Architecture
The Router implements a permission system that allows plugins to execute actions on behalf of users:
Users must first register a plugin using addPlugin
Then they must approve the plugin using approvePlugin
Only after both steps can a plugin execute actions on behalf of the user
Only approve plugins that you trust, as they will have significant control over your funds and positions in the protocol.
Plugin Authorization Flow
ETH Handling
The Router provides convenience functions for handling ETH:
function sendETHToVault ( uint256 _amount ) external ;
Converts ETH to WETH and sends it to the Vault.
function unwrapETH ( uint256 _amount , address _receiver ) external ;
Unwraps WETH to ETH and sends it to the specified receiver.
Integration with Vault
The Router interacts with the Vault in several ways:
Position Management : Forwards position modifications to the Vault
Token Swaps : Uses the Vault’s swap functionality
Token Approvals : Manages approvals for the Vault to use tokens
Security Considerations
The Router implements several security features:
Plugin Validation : Ensures plugins are authorized by the user
Permission System : Only approved plugins can execute actions
Reentrancy Protection : Prevents reentrancy attacks
Access Controls : Restricts sensitive functions to authorized callers
The Router does not store user funds directly. Funds are always managed by the Vault contract.
Example: Using the Router with PositionManager
Register the PositionManager
First, a user registers the PositionManager as a plugin. // Add the position manager as a plugin
await router . addPlugin ( positionManagerAddress );
// Approve the position manager plugin
await router . approvePlugin ( positionManagerAddress );
Approve Tokens
The user approves tokens to be used by the Router. // Approve WETH
await weth . approve ( routerAddress , ethers . constants . MaxUint256 );
// Approve USDC
await usdc . approve ( routerAddress , ethers . constants . MaxUint256 );
Interact via PositionManager
Now the user can interact with the PositionManager, which uses the Router as an intermediary. // Open a long position through the position manager
await positionManager . increasePosition (
[ wethAddress ], // Token path
wethAddress , // Index token (ETH)
ethers . utils . parseEther ( "1" ), // Amount in
0 , // Min output amount (no swap)
ethers . utils . parseUnits ( "5" , 30 ), // Size delta (5x leverage)
true , // Is long
ethers . utils . parseUnits ( "2000" , 30 ) // Acceptable price
);
Common Use Cases
Position Manager Integration The Router enables the PositionManager to modify positions in the Vault on behalf of users
Order Book Integration The Router allows the OrderBook to execute limit orders when conditions are met
Position Router Integration Enables the PositionRouter to process queued position requests
Custom Plugins Developers can create custom plugins that interact with the protocol via the Router
Extending with Custom Plugins
The Router’s plugin architecture enables developers to extend the protocol’s functionality:
// Example of a simple custom plugin that automatically adds collateral
// when a position's leverage exceeds a threshold
contract LeverageGuardian {
Router public router;
Vault public vault;
constructor ( address _router , address _vault ) {
router = Router (_router);
vault = Vault (_vault);
}
function guardPosition (
address _collateralToken ,
address _indexToken ,
bool _isLong
) external {
// Get position info
( uint256 size, uint256 collateral, , , , , , ) = vault. getPosition (
msg.sender ,
_collateralToken,
_indexToken,
_isLong
);
// Check if leverage is too high (e.g., > 10x)
if (size > collateral * 10 ) {
// Calculate additional collateral needed
uint256 additionalCollateral = size / 5 - collateral;
// Add collateral through the router
router. pluginIncreasePosition (
msg.sender ,
_collateralToken,
_indexToken,
0 , // No size increase
_isLong
);
}
}
}