# Perp (/docs/risex/contracts/contract-interface/perp)

### Deposit

**Description**

Deposits collateral tokens into the specified account. The caller must have approved the PerpsManager contract to spend
the tokens.

```solidity
function deposit(address to, address token, uint256 amount) external;
```

**Example**

```solidity
// Approve tokens first
IERC20(usdc).approve(perpsManager, amount);

// Deposit USDC
perpsManager.deposit(account, usdc, amount);
```

***

### Withdraw

**Description**

Withdraws collateral tokens from the caller's account to the specified address. The withdrawable amount is limited by
the account's free margin balance.

```solidity
function withdraw(address to, address token, uint256 amount) external;
```

**Parameters**

* `to`: The address to withdraw tokens to
* `token`: The address of the collateral token to withdraw
* `amount`: The amount of tokens to withdraw (in token's native decimals)

**Example**

```solidity
// Get the withdrawable amount
uint256 withdrawableAmount = perpsManager.getWithdrawableAmount(account, usdc);

// Withdraw USDC to the recipient
perpsManager.withdraw(recipient, usdc, withdrawableAmount);
```

***

### Place Order

**Description**

Places a trading order (market or limit) in the specified market. The order data is encoded in a packed binary format
for gas efficiency.

```solidity
function placeOrder(bytes calldata placeOrderData) external returns (uint256 orderId);
```

**Parameters**

* `placeOrderData`: Encoded order data (47 bytes) containing:
  * `marketId` (uint64, 8 bytes): The market ID
  * `size` (uint128, 16 bytes): The order size (in 18 decimals)
  * `price` (uint128, 16 bytes): The limit price (0 for market orders) (in 18 decimals)
  * `flags` (uint8, 1 byte): Packed flags:
    * bit 0: side (0 = Buy, 1 = Sell)
    * bit 1: postOnly
    * bit 2: reduceOnly
    * bits 3-4: stpMode (0 = ExpireMaker, 1 = ExpireTaker, 2 = ExpireBoth, 3 = None)
  * `orderType` (uint8, 1 byte): OrderType enum (0 = Market, 1 = Limit)
  * `timeInForce` (uint8, 1 byte): TimeInForce enum (0 = GoodTillCancelled, 1 = GoodTillTime, 2 = FillOrKill, 3 =
    ImmediateOrCancel)
  * `expiry` (uint32, 4 bytes): Expiry timestamp (for GoodTillTime orders) (0 for other order types)

**Example**

```solidity
// Encode place order data
uint64 marketId = 1; // BTC
uint128 size = 1e18; // 1 BTC
uint128 price = 100_000e18; // $100,000

uint8 side = 0; // Buy
uint8 postOnly = 0; // False
uint8 reduceOnly = 0; // False
uint8 stpMode = 0; // ExpireMaker
uint8 flags = (side << 0) | (postOnly << 1) | (reduceOnly << 2) | (stpMode << 3);

bytes memory placeOrderData = abi.encodePacked(marketId, size, price, flags, OrderType.Limit, TimeInForce.GoodTillCancelled, 0);

uint256 orderId = perpsManager.placeOrder(placeOrderData);
```

***

### Place Order With Permit

**Description**

Places an order with EIP-712 typed data signature, allowing gasless approvals for trading. The signer must be registered
in the `RISExAuthorization` contract.

```solidity
function placeOrderWithPermit(
    bytes calldata placeOrderData,
    InputTypes.PermitParams calldata permit
) external returns (uint256 orderId);
```

**Parameters**

* `placeOrderData`: Encoded order data (same as `placeOrder`)
* `permit`: Permit parameters:
  * `account`: The account address
  * `signer`: The signer address
  * `deadline`: Signature expiry timestamp
  * `signature`: EIP-712 signature
  * `nonce`: The unique nonce for the signature to prevent replay attacks

**Example**

```solidity
// Encode place order data
uint64 marketId = 1; // BTC
uint128 size = 1e18; // 1 BTC
uint128 price = 100_000e18; // $100,000

uint8 side = 0; // Buy
uint8 postOnly = 0; // False
uint8 reduceOnly = 0; // False
uint8 stpMode = 0; // ExpireMaker
uint8 flags = (side << 0) | (postOnly << 1) | (reduceOnly << 2) | (stpMode << 3);

bytes memory placeOrderData = abi.encodePacked(marketId, size, price, flags, OrderType.Limit, TimeInForce.GoodTillCancelled, 0);

// Prepare permit parameters
uint256 nonce = 123;
uint256 deadline = block.timestamp + 1 hours;
bytes32 verifySignatureHash = keccak256(
    abi.encode(
        VERIFY_SIGNATURE_TYPEHASH, // "VerifySignature(address account,address target,bytes32 hash,uint256 nonce,uint256 deadline)"
        account,
        address(perpsManager),
        keccak256(placeOrderData),
        nonce,
        deadline
    )
);
bytes memory permitSignature = _signTypedDataHash(signerPrivateKey, verifySignatureHash);

InputTypes.PermitParams memory permit = InputTypes.PermitParams({
    account: account,
    signer: signer,
    deadline: deadline,
    signature: permitSignature,
    nonce: nonce
});

uint256 orderId = perpsManager.placeOrderWithPermit(placeOrderData, permit);
```

***

### Cancel Order

**Description**

Cancels an open limit order in the specified market.

```solidity
function cancelOrder(bytes32 cancelOrderData) external;
```

**Parameters**

* `cancelOrderData`: Encoded cancel order data (32 bytes) containing:
  * `marketId` (uint64, 8 bytes): The market ID
  * `orderId` (uint192, 24 bytes): The order ID to cancel

**Example**

```solidity
bytes32 cancelOrderData = bytes32(abi.encodePacked(
    uint64(marketId),
    uint192(orderId)
));

perpsManager.cancelOrder(cancelOrderData);
```

***

### Cancel Order With Permit

**Description**

Cancels an order with EIP-712 typed data signature. The signer must be registered in the `RISExAuthorization` contract.

```solidity
function cancelOrderWithPermit(
    bytes32 cancelOrderData,
    InputTypes.PermitParams calldata permit
) external;
```

**Parameters**

* `cancelOrderData`: Encoded cancel order data (same as `cancelOrder`)
* `permit`: Permit parameters (same as `placeOrderWithPermit`)

**Example**

```solidity
// Encode cancel order data
bytes32 cancelOrderData = bytes32(abi.encodePacked(
    uint64(marketId),
    uint192(orderId)
));

// Prepare permit parameters
uint256 nonce = 456;
uint256 deadline = block.timestamp + 1 hours;
bytes32 verifySignatureHash = keccak256(
    abi.encode(
        VERIFY_SIGNATURE_TYPEHASH, // "VerifySignature(address account,address target,bytes32 hash,uint256 nonce,uint256 deadline)"
        account,
        address(perpsManager),
        keccak256(cancelOrderData),
        nonce,
        deadline
    )
);
bytes memory permitSignature = _signTypedDataHash(signerPrivateKey, verifySignatureHash);

InputTypes.PermitParams memory permit = InputTypes.PermitParams({
    account: account,
    signer: signer,
    deadline: deadline,
    signature: permitSignature,
    nonce: nonce
});

perpsManager.cancelOrderWithPermit(cancelOrderData, permit);
```

***

### Update Margin Mode

**Description**

Updates the margin mode (Cross or Isolated) for an account in a specific market.

```solidity
function updateMarginMode(InputTypes.UpdateMarginModeParams calldata params) external;
```

**Parameters**

* `params`: UpdateMarginModeParams struct:
  * `marketId`: The market ID
  * `marginMode`: The new margin mode (0 = Cross, 1 = Isolated)

**Example**

```solidity
InputTypes.UpdateMarginModeParams memory params = InputTypes.UpdateMarginModeParams({
    marketId: marketId,
    marginMode: Market.MarginMode.Isolated
});

perpsManager.updateMarginMode(params);
```

***

### Update Margin Mode With Permit

**Description**

Updates margin mode with EIP-712 typed data signature. The signer must be registered in the `RISExAuthorization`
contract.

```solidity
function updateMarginModeWithPermit(
    InputTypes.UpdateMarginModeParams calldata params,
    InputTypes.PermitParams calldata permit
) external;
```

**Parameters**

* `params`: UpdateMarginModeParams struct
* `permit`: Permit parameters

**Example**

```solidity
// Encode update margin mode params
uint64 marketId = 1; // BTC
uint8 marginMode = 1; // Isolated

InputTypes.UpdateMarginModeParams memory params = InputTypes.UpdateMarginModeParams({
    marketId: marketId,
    marginMode: Market.MarginMode(marginMode)
});

// Prepare permit parameters
uint256 nonce = 456;
uint256 deadline = block.timestamp + 1 hours;
bytes32 verifySignatureHash = keccak256(
    abi.encode(
        VERIFY_SIGNATURE_TYPEHASH, // "VerifySignature(address account,address target,bytes32 hash,uint256 nonce,uint256 deadline)"
        account,
        address(perpsManager),
        keccak256(abi.encode(params)),
        nonce,
        deadline
    )
);
bytes memory permitSignature = _signTypedDataHash(signerPrivateKey, verifySignatureHash);

InputTypes.PermitParams memory permit = InputTypes.PermitParams({
    account: account,
    signer: signer,
    deadline: deadline,
    signature: permitSignature,
    nonce: nonce
});

perpsManager.updateMarginModeWithPermit(params, permit);
```

***

### Update Leverage

**Description**

Updates the leverage for an account in a specific market. Leverage determines the maximum position size relative to
margin.

```solidity
function updateLeverage(InputTypes.UpdateLeverageParams calldata params) external;
```

**Parameters**

* `params`: UpdateLeverageParams struct:
  * `marketId`: The market ID
  * `leverage`: The new leverage (as a multiplier, e.g., 10 for 10x)

**Example**

```solidity
InputTypes.UpdateLeverageParams memory params = InputTypes.UpdateLeverageParams({
    marketId: marketId,
    leverage: 20 // 20x leverage
});

perpsManager.updateLeverage(params);
```

***

### Update Leverage With Permit

**Description**

Updates leverage with EIP-712 typed data signature. The signer must be registered in the `RISExAuthorization` contract.

```solidity
function updateLeverageWithPermit(
    InputTypes.UpdateLeverageParams calldata params,
    InputTypes.PermitParams calldata permit
) external;
```

**Parameters**

* `params`: UpdateLeverageParams struct
* `permit`: Permit parameters

**Example**

```solidity
// Encode update leverage params
uint64 marketId = 1; // BTC
uint128 leverage = 10e18; // 10x leverage

InputTypes.UpdateLeverageParams memory params = InputTypes.UpdateLeverageParams({
    marketId: marketId,
    leverage: leverage
});

// Prepare permit parameters
uint256 nonce = 456;
uint256 deadline = block.timestamp + 1 hours;
bytes32 verifySignatureHash = keccak256(
    abi.encode(
        VERIFY_SIGNATURE_TYPEHASH, // "VerifySignature(address account,address target,bytes32 hash,uint256 nonce,uint256 deadline)"
        account,
        address(perpsManager),
        keccak256(abi.encode(params)),
        nonce,
        deadline
    )
);
bytes memory permitSignature = _signTypedDataHash(signerPrivateKey, verifySignatureHash);

InputTypes.PermitParams memory permit = InputTypes.PermitParams({
    account: account,
    signer: signer,
    deadline: deadline,
    signature: permitSignature,
    nonce: nonce
});

perpsManager.updateLeverageWithPermit(params, permit);
```

***

### Update Isolated Position Margin Balance

**Description**

Adds or removes margin from an isolated position. Positive amount adds margin, negative amount removes margin.

```solidity
function updateIsolatedPositionMarginBalance(
    InputTypes.UpdateIsolatedPositionMarginBalanceParams calldata params
) external;
```

**Parameters**

* `params`: UpdateIsolatedPositionMarginBalanceParams struct:
  * `marketId`: The market ID
  * `amount`: The delta amount to add (if positive) or remove (if negative), in USDC with 18 decimals

**Example**

```solidity
// Add 100 USDC to isolated position
InputTypes.UpdateIsolatedPositionMarginBalanceParams memory params = InputTypes.UpdateIsolatedPositionMarginBalanceParams({
    marketId: marketId,
    amount: 100e18 // Positive to add
});

perpsManager.updateIsolatedPositionMarginBalance(params);

// Remove 50 USDC from isolated position
params.amount = -50e18; // Negative to remove
perpsManager.updateIsolatedPositionMarginBalance(params);
```

***

### Update Isolated Position Margin Balance With Permit

**Description**

Updates isolated position margin balance with EIP-712 typed data signature. The signer must be registered in the
`RISExAuthorization` contract.

```solidity
function updateIsolatedPositionMarginBalanceWithPermit(
    InputTypes.UpdateIsolatedPositionMarginBalanceParams calldata params,
    InputTypes.PermitParams calldata permit
) external;
```

**Parameters**

* `params`: UpdateIsolatedPositionMarginBalanceParams struct
* `permit`: Permit parameters

**Example**

```solidity
// Encode update isolated position margin balance params
uint64 marketId = 1; // BTC
int256 amount = 1000e18; // 1000 USDC

InputTypes.UpdateIsolatedPositionMarginBalanceParams memory params = InputTypes.UpdateIsolatedPositionMarginBalanceParams({
    marketId: marketId,
    amount: amount
});

// Prepare permit parameters
uint256 nonce = 456;
uint256 deadline = block.timestamp + 1 hours;
bytes32 verifySignatureHash = keccak256(
    abi.encode(
        VERIFY_SIGNATURE_TYPEHASH, // "VerifySignature(address account,address target,bytes32 hash,uint256 nonce,uint256 deadline)"
        account,
        address(perpsManager),
        keccak256(abi.encode(params)),
        nonce,
        deadline
    )
);
bytes memory permitSignature = _signTypedDataHash(signerPrivateKey, verifySignatureHash);

InputTypes.PermitParams memory permit = InputTypes.PermitParams({
    account: account,
    signer: signer,
    deadline: deadline,
    signature: permitSignature,
    nonce: nonce
});

perpsManager.updateIsolatedPositionMarginBalanceWithPermit(params, permit);
```

***

## View Functions

### Get Balance

**Description**

Returns the collateral balance for a specific token for an account.

```solidity
function getBalance(address account, address token) external view returns (int256);
```

**Parameters**

* `account`: The account address
* `token`: The token address

**Returns**

* `int256`: The balance (can be negative in edge cases)

**Example**

```solidity
int256 balance = perpsManager.getBalance(account, usdc);
```

***

### Get Position

**Description**

Returns the position for an account in a market.

```solidity
function getPosition(uint256 marketId, address account) external view returns (Market.Position memory);
```

**Parameters**

* `marketId`: The market ID
* `account`: The account address

**Returns**

* `Market.Position`: The position struct containing:
  * `size`: Position size (positive for long, negative for short)
  * `quoteAmount`: Quote amount
  * `marginMode`: Current margin mode
  * `side`: Position side (Buy = long, Sell = short)
  * `isolatedUsdcBalance`: Isolated margin balance (if isolated mode)
  * `lastFundingPayment`: Last funding payment
  * `leverage`: Current leverage

**Example**

```solidity
Market.Position memory position = perpsManager.getPosition(marketId, account);
```

***

### Get Leverage

**Description**

Returns the leverage for an account in a market.

```solidity
function getLeverage(uint256 marketId, address account) external view returns (uint256);
```

**Parameters**

* `marketId`: The market ID
* `account`: The account address

**Returns**

* `uint256`: The leverage multiplier

**Example**

```solidity
uint256 leverage = perpsManager.getLeverage(marketId, account);
```

***

### Get Market Config

**Description**

Returns the configuration for a market.

```solidity
function getMarketConfig(uint256 marketId) external view returns (Market.Config memory);
```

**Parameters**

* `marketId`: The market ID

**Returns**

* `Market.Config`: The market configuration containing:
  * `name`: Market name
  * `quote`: Quote token address
  * `stepSize`: Minimum order size step
  * `stepPrice`: Minimum price step
  * `maintenanceMarginFactor`: Maintenance margin factor
  * `maxLeverage`: Maximum allowed leverage
  * `minOrderSize`: Minimum order size
  * `unlocked`: Whether the market is unlocked

**Example**

```solidity
Market.Config memory config = perpsManager.getMarketConfig(marketId);
```

***

### Get Best Price

**Description**

Returns the best bid or ask price in a market.

```solidity
function getBestPrice(uint256 marketId, OrderSide side) external view returns (uint256);
```

**Parameters**

* `marketId`: The market ID
* `side`: OrderSide (Buy for bid, Sell for ask)

**Returns**

* `uint256`: The best price, or 0 if no orders exist

**Example**

```solidity
uint256 bestBid = perpsManager.getBestPrice(marketId, OrderSide.Buy);
uint256 bestAsk = perpsManager.getBestPrice(marketId, OrderSide.Sell);
```

***

### Get Order

**Description**

Returns an order by market ID and order ID.

```solidity
function getOrder(uint256 marketId, uint256 orderId) external view returns (Order memory);
```

**Parameters**

* `marketId`: The market ID
* `orderId`: The order ID

**Returns**

* `Order`: The order struct

**Example**

```solidity
Order memory order = perpsManager.getOrder(marketId, orderId);
```

***

### Get Open Orders

**Description**

Returns a paginated list of open order IDs for an account in a market.

```solidity
function getOpenOrders(
    uint256 marketId,
    address account,
    uint256 startIndex,
    uint256 limit
) external view returns (uint256[] memory);
```

**Parameters**

* `marketId`: The market ID
* `account`: The account address
* `startIndex`: The starting index (0-based)
* `limit`: Maximum number of orders to return

**Returns**

* `uint256[]`: Array of order IDs

**Example**

```solidity
uint256[] memory orderIds = perpsManager.getOpenOrders(marketId, account, 0, 10);
```

***

### Get Withdrawable Amount

**Description**

Returns the maximum withdrawable amount for a specific token for an account, considering margin requirements.

```solidity
function getWithdrawableAmount(address account, address token) external view returns (uint256);
```

**Parameters**

* `account`: The account address
* `token`: The token address

**Returns**

* `uint256`: The withdrawable amount (in token's native decimals)

**Example**

```solidity
uint256 withdrawable = perpsManager.getWithdrawableAmount(account, usdc);
```

***

### Get Account Equity

**Description**

Returns the total account equity in USDC, including all positions and collateral.

```solidity
function getAccountEquity(address account) external view returns (int256);
```

**Parameters**

* `account`: The account address

**Returns**

* `int256`: The account equity (can be negative if underwater)

**Example**

```solidity
int256 equity = perpsManager.getAccountEquity(account);
```

***

### Get Cross Margin Balance

**Description**

Returns the cross margin balance for an account.

```solidity
function getCrossMarginBalance(address account) external view returns (int256);
```

**Parameters**

* `account`: The account address

**Returns**

* `int256`: The cross margin balance

**Example**

```solidity
int256 crossMargin = perpsManager.getCrossMarginBalance(account);
```

***

### Get Free Cross Margin Balance

**Description**

Returns the free (available for withdrawal) cross margin balance for an account.

```solidity
function getFreeCrossMarginBalance(address account) external view returns (uint256);
```

**Parameters**

* `account`: The account address

**Returns**

* `uint256`: The free cross margin balance

**Example**

```solidity
uint256 freeMargin = perpsManager.getFreeCrossMarginBalance(account);
```
