# LongShortSpell

The ShortLongSpell contract is a factory contract that defines how Blueberry Protocol interacts for leveraging an asset either long or short. It extends the BasicSpell contract and is responsible for depositing and withdrawing assets, as well as opening and closing positions. The contract utilizes OpenZeppelin's SafeERC20Upgradeable and SafeCast libraries, as well as interfaces from other contracts like ISoftVault, IWERC20, and libraries from Paraswap.

### Dependencies

* OpenZeppelin Contracts Upgradeable
* BasicSpell.sol
* Interfaces (ISoftVault.sol, IWERC20.sol)
* Libraries (Paraswap/PSwapLib.sol)

### Contract Overview

#### State Variables

* `wrapper`: An instance of IWERC20 that represents the wrapped ERC20 token.
* `augustusSwapper`: The address of the paraswap AugustusSwapper.
* `tokenTransferProxy`: The address of the paraswap TokenTransferProxy.

### Initialization

The `initialize` function takes the following arguments:

* `IBank bank_`: Instance of the Bank contract
* `address werc20_`: Address of the WERC20 token contract
* `address weth_`: Address of the wrapped Ether (WETH) contract
* `address augustusSwapper_`: Address of the Paraswap AugustusSwapper contract
* `address tokenTransferProxy_`: Address of the Paraswap TokenTransferProxy contract

This function initializes the contract by setting the address for the AugustusSwapper, TokenTransferProxy, and Wrapper contracts, and calling the `__BasicSpell_init` function.

### Deposit

The `_deposit` function takes the following parameters:

* `OpenPosParam calldata param`: Struct containing the parameters for opening a position
* `Utils.MegaSwapSellData calldata swapData`: Struct containing the swap data for the MegaSwap operation

This internal function handles the process of depositing assets by performing the following steps:

1. Depositing isolated collateral in the Blueberry Money Market
2. Borrowing a specified amount of tokens from the Blueberry Money Market
3. Swapping the borrowed tokens to the strategy token
4. Depositing the swapped tokens to the SoftVault
5. Validating the maximum Loan-to-Value (LTV) ratio
6. Validating the maximum position size

### Open Position

The `openPosition` function takes the following parameters:

* `OpenPosParam calldata param`: Struct containing the parameters for opening a position
* `Utils.MegaSwapSellData calldata swapData`: Struct containing the swap data for the MegaSwap operation

This external function is used for opening a new position. It calls the internal `_deposit` function to handle the deposit process, puts collateral and handles refunds.

### Withdraw

The `_withdraw` function takes the following parameters:

* `ClosePosParam calldata param`: Struct containing the parameters for closing a position
* `Utils.MegaSwapSellData calldata swapData`: Struct containing the swap data for the MegaSwap operation

This internal function handles the process of withdrawing assets by performing the following steps:

1. Calculate the actual amount to remove from the position
2. Withdraw assets from the SoftVault
3. Swap the strategy token to the isolated collateral token
4. Withdraw the isolated collateral from the Blueberry Money Market
5. Repay the debt and refund the remaining amount to the user
6. Validate the maximum LTV ratio

### Close Position

The `closePosition` function takes the following parameters:

* `ClosePosParam calldata param`: Struct containing the parameters for closing a position
* `Utils.MegaSwapSellData calldata swapData`: Struct containing the swap data for the MegaSwap operation

This external function is used for closing a position. It checks for correct strategy and collateral tokens, takes out collateral, and calls the internal `_withdraw` function to handle the withdrawal process.

### Add Strategy

The `addStrategy` function takes the following parameters:

* `address swapToken`: Address of the token for the given strategy
* `uint256 maxPosSize`: USD price of the maximum position size for the given strategy, based on 1e18

This external function is used for adding a strategy to the spell. It can only be called by the contract owner. It calls the internal `_addStrategy` function to add a strategy with the specified `swapToken` address and `maxPosSize`.

### Additional Functions

The contract also contains several utility functions such as `_doLend`, `_doBorrow`, `_ensureApprove`, `_validateMaxLTV`, `_validateMaxPosSize`, `_doPutCollateral`, `_doWithdraw`, `_doRepay`, and `_doRefund`. These functions help with various operations related to lending, borrowing, approving tokens, validating LTV ratios, validating position sizes, putting collateral, withdrawing, repaying debts, and refunding assets.

### Modifiers

The contract includes the following modifiers to validate the input parameters for certain functions:

* `existingStrategy`: Ensures that the strategy ID provided as a parameter exists
* `existingCollateral`: Ensures that the collateral token provided as a parameter exists for the specified strategy
