# LpETH docs

This page provides developer documentation for the most important endpoints of the `LpETH` contract. The `LpETH` contract facilitates liquidity pooling of ETH, allowing users to deposit ETH and receive LP tokens, withdraw ETH, swap assets, and participate in the protocol's liquidity mechanisms.

### Table of Contents

* Swap
* Quote
* Deposit
* Withdraw
* Claim Withdraw Request
* Redeem Unlock
* Buy Unlock
* Claim Relayer Rewards
* Events
* Disclaimer

***

### Swap

#### `swap(address asset, uint256 amount, uint256 minOut)`

Swaps a supported asset for ETH.

```solidity
swap(address asset, uint256 amount, uint256 minOut) external nonreentrant returns (uint256 out, uint256 fee)
```

**Parameters:**

* `asset` (`address`): The address of the asset to swap.
* `amount` (`uint256`): The amount of the asset to swap.
* `minOut` (`uint256`): The minimum amount of ETH the user expects to receive.

**Returns:**

* `out` (`uint256`): The amount of ETH received.
* `fee` (`uint256`): The fee charged for the swap.

**Description:**

* Transfers the specified asset from the user to the contract.
* Approves the `UnsETH` contract to handle the asset.
* Requests withdrawal from `UnsETH`, receiving a token ID and expected amount.
* Calculates the ETH output and fee.
* Reverts if the ETH output is less than `minOut` to prevent slippage.
* Transfers the ETH to the user.

**Events:**

* `Swap(address indexed caller, address indexed asset, uint256 amountIn, uint256 fee, uint256 unlockId)`

**Errors:**

* `ErrorInvalidAsset(address asset)`: Thrown if the asset is not supported.
* `ErrorSlippage(uint256 out, uint256 minOut)`: Thrown if the ETH output is less than `minOut`.

***

### Quote

#### `quote(address asset, uint256 amount)`

Provides an estimate of the ETH amount and fee for swapping a given asset.

```solidity
quote(address asset, uint256 amount) external view returns (uint256 out, uint256 fee)
```

**Parameters:**

* `asset` (`address`): The address of the asset to swap.
* `amount` (`uint256`): The amount of the asset to swap.

**Returns:**

* `out` (`uint256`): The estimated amount of ETH the user will receive.
* `fee` (`uint256`): The estimated fee for the swap.

**Description:**

* Calculates the expected ETH output and fee based on the current pool state.
* Useful for users to understand the swap outcome before executing.

**Errors:**

* `ErrorInvalidAsset(address asset)`: Thrown if the asset is not supported.

***

### Deposit

#### `deposit(uint256 minLpShares)`

Allows users to deposit ETH into the pool and receive LP tokens in return.

```solidity
deposit(uint256 minLpShares) external payable returns (uint256 lpShares)
```

**Parameters:**

* `minLpShares` (`uint256`): The minimum amount of LP tokens the user expects to receive to prevent slippage.

**Returns:**

* `lpShares` (`uint256`): The number of LP tokens minted to the user.

**Description:**

* Users send ETH along with this function call.

* Calculates the number of LP tokens to mint based on the pool's current liabilities and total supply.

* Mints LP tokens to the user.

**Events:**

* `Deposit(address indexed from, uint256 amount, uint256 lpSharesMinted)`

**Errors:**

* `ErrorSlippage(uint256 out, uint256 minOut)`: Thrown if the LP shares to mint are less than `minLpShares`.
* `ErrorDepositSharesZero()`: Thrown if the calculated LP shares are zero.

***

### Withdraw

#### `withdraw(uint256 amount, uint256 maxLpSharesBurnt)`

Allows users to withdraw ETH by burning their LP tokens.

```solidity
withdraw(uint256 amount, uint256 maxLpSharesBurnt) external nonreentrant returns (uint256 requestId)
```

**Parameters:**

* `amount` (`uint256`): The amount of ETH the user wants to withdraw.
* `maxLpSharesBurnt` (`uint256`): The maximum number of LP tokens the user is willing to burn to prevent slippage.

**Returns:**

* `requestId` (`uint256`): The ID of the withdrawal request if applicable.

**Description:**

* Calculates the number of LP tokens to burn based on the withdrawal amount.
* Reverts if the LP shares to burn exceed `maxLpSharesBurnt`.
* If there's insufficient liquidity, creates a withdrawal request for the remaining amount.
* Burns the user's LP tokens.
* Transfers available ETH to the user.

**Events:**

* `Withdraw(address indexed to, uint256 amount, uint256 lpSharesBurnt, uint256 requestId)`

**Errors:**

* `DepositedInCurrentTx()`: Thrown if a withdrawal is attempted in the same transaction as a deposit.
* `ErrorSlippage(uint256 out, uint256 maxLpSharesBurnt)`: Thrown if the LP shares to burn exceed `maxLpSharesBurnt`.
* `ErrorDepositSharesZero()`: Thrown if the calculated LP shares are zero.

***

### Claim Withdraw Request

#### `claimWithdrawRequest(uint256 id)`

Allows users to claim their finalized withdrawal requests.

```solidity
claimWithdrawRequest(uint256 id) external returns (uint256 amount)
```

**Parameters:**

* `id` (`uint256`): The ID of the withdrawal request.

**Returns:**

* `amount` (`uint256`): The amount of ETH claimed.

**Description:**

* Finalizes the withdrawal request and transfers the ETH to the requester.
* Updates the pool's liabilities.

**Events:**

* `ClaimWithdrawRequest(uint256 indexed requestId, address indexed to, uint256 amount)`

***

### Redeem Unlock

#### `redeemUnlock()`

Allows relayers to redeem finalized unlocks and claim rewards.

```solidity
redeemUnlock() external nonreentrant
```

**Description:**

* Retrieves the oldest unlock from the queue.
* Checks if the unlock is finalized.
* Claims the withdrawal from the `UnsETH` contract.

**Events:**

* `UnlockRedeemed(address indexed relayer, uint256 tokenId, uint256 amount, uint256 reward, uint256 lpFees)`

**Errors:**

* `ErrorNotFinalized(uint256 tokenId)`: Thrown if the unlock is not finalized.

***

### Buy Unlock

#### `buyUnlock(uint256 expectedTokenId)`

Allows users to purchase unfinalized unlocks at a discounted rate.

```solidity
buyUnlock(uint256 expectedTokenId) external payable nonreentrant returns (uint256 tokenId)
```

**Parameters:**

* `expectedTokenId` (`uint256`): The expected token ID of the unlock to purchase.

**Returns:**

* `tokenId` (`uint256`): The actual token ID of the unlock purchased.

**Description:**

* Retrieves the newest unlock from the queue.
* Checks if the unlock is not finalized and not expired.
* Verifies that the token ID matches `expectedTokenId`.
* Calculates the reward (discount) for purchasing the unlock.
* Transfers the unlock to the buyer.

**Events:**

* `UnlockBought(address indexed caller, uint256 tokenId, uint256 amount, uint256 reward, uint256 lpFees)`

**Errors:**

* `UnexpectedTokenId()`: Thrown if the token ID does not match `expectedTokenId`.
* `ErrorIsFinalized(uint256 tokenId)`: Thrown if the unlock is already finalized.
* `ErrorRecoveryMode()`: Thrown if the pool is in recovery mode.
* `ErrorInsufficientAmount()`: Thrown if the sent ETH is insufficient.

***

### Claim Relayer Rewards

#### `claimRelayerRewards()`

Allows relayers to claim their accumulated rewards.

```solidity
claimRelayerRewards() external returns (uint256 relayerReward)
```

**Returns:**

* `relayerReward` (`uint256`): The amount of rewards claimed.

**Description:**

* Transfers the accumulated rewards to the relayer.
* Resets the relayer's reward balance.
* Emits a `RelayerRewardsClaimed` event.

**Events:**

* `RelayerRewardsClaimed(address indexed relayer, uint256 rewards)`

***

### Events

* `Deposit(address indexed from, uint256 amount, uint256 lpSharesMinted)`
* `Withdraw(address indexed to, uint256 amount, uint256 lpSharesBurnt, uint256 requestId)`
* `ClaimWithdrawRequest(uint256 indexed requestId, address indexed to, uint256 amount)`
* `Swap(address indexed caller, address indexed asset, uint256 amountIn, uint256 fee, uint256 unlockId)`
* `UnlockRedeemed(address indexed relayer, uint256 tokenId, uint256 amount, uint256 reward, uint256 lpFees)`
* `UnlockBought(address indexed caller, uint256 tokenId, uint256 amount, uint256 reward, uint256 lpFees)`
* `RelayerRewardsClaimed(address indexed relayer, uint256 rewards)`

***

### Notes

* **Access Control:** Some functions are restricted using modifiers like `onlyOwner` and `nonreentrant`.
* **Upgradeable Contract:** The contract uses OpenZeppelin's upgradeable pattern via `UUPSUpgradeable`.
* **External Contracts:** Interacts with external contracts like `UnsETH`, `Registry`, and `LPToken`.
* **Mathematical Libraries:** Utilizes libraries like `FixedPointMathLib` and `UD60x18` for precise calculations.
* **ETH Handling:** Functions are marked `payable` where necessary, and ETH transfers are handled carefully to prevent issues.

***

**Disclaimer:** This documentation provides a high-level overview of the most important endpoints of the `LpETH` contract. Developers should refer to the actual contract code and conduct thorough testing before interacting with the contract in a production environment.
