<!--
Parallel Documentation — this page, as markdown.
Index of every page: https://docs.parallel.best/llms.txt
The whole documentation in one file: https://docs.parallel.best/llms-full.txt
-->

# Contracts

## 1. Contracts

### 1.1 Fees

This section contains the contracts related to the fees distribution and collection.

#### &#x31;**.1.1** [**FeeCollectorCore**](https://github.com/parallel-protocol/parallel-tokenomics/blob/main/contracts/fees/FeeCollectorCore.sol)

This abstract contract is used to handle the common logic between the MainFeeDistributor and the SideChainFeeDistributor contracts. All the functions are restricted to the AccessManager.

**function details**:

* `emergencyRescue(address _token, address _to, uint256 _amount)` | **Restricted** : Allow to rescue tokens from the contract.
* `pause()` | **Restricted** : Allow to pause the contract.
* `unpause()` | **Restricted** : Allow to unpause the contract.

#### &#x31;**.1.2** [**MainFeeDistributor**](https://github.com/parallel-protocol/parallel-tokenomics/blob/main/contracts/fees/MainFeeDistributor.sol)

This contract is deployed on the chain that distributes the fees to users and fees receivers. Inherits from FeeCollectorCore. It will receive the fee token bridge from the SideChainFeeDistributor and distribute it to the fee receivers. As Parallel Tunnel can transfer lz-XXX instead of the fee token if credit limits are reached, this contract can call the bridgeableToken contract to swap the lz-XXX to the fee token.

**function details**:

* `release()` | **Permissionless** : Allow to release the fees to the fee receivers.
* `swapLzToken()` | **Permissionless** : Will swap as much lz-XXX as possible to the fee token by calling the bridgeableToken contract.
* `updateBridgeableToken(address _newBridgeableToken)`| **Restricted** : Allow to update the bridgeable token contract (parallel tunnel).
* `updateFeeReceivers(address[] memory _feeReceivers, uint256[] memory _shares)` | **Restricted** : Allow to update the list of the fee receivers and their shares.

#### &#x31;**.1.3** [**SideChainFeeDistributor**](https://github.com/parallel-protocol/parallel-tokenomics/blob/main/contracts/fees/SideChainFeeCollector.sol)

This contract is deployed on side chains and is used to distribute the fees to the MainFeeDistributor by bridging them using Parallel Tunnel. Inherits from FeeCollectorCore. In the code, the contract is named `SideChainFeeCollector`.

**function details**:

* `release()` | **Restricted** : Will create a LayerZero message and transfer the balance of fee token owned by the contract to the BridgeableToken contract.
* `updateBridgeableToken(address _newBridgeableToken)`| **Restricted** : Allow to update the bridgeable token contract (parallel tunnel).
* `updateDestinationReceiver(address _newDestinationReceiver)` | **Restricted** : Allow to update the destination receiver address.

### 1.2 Staking

This section contains the contracts related to the staking part of the protocol.

#### &#x31;**.2.1** [**TimeLockPenaltyERC20**](https://github.com/parallel-protocol/parallel-tokenomics/blob/main/contracts/sPRL/TimeLockPenaltyERC20.sol)

This abstract contract is used to handle commun logic between sPRL1 and sPRL2. The main feature of it, it's to apply a lock time duration for withdrawals. Users is also able to withdraw their tokens before the lock time but will be penalized by a penalty fee on the withdraw amount that is calculated based on the time left before the lock time.

**Parameters**:

* Lock Duration: Configurable
* Penalty Start Percentage: Configurable
* Penalty Decay: Linear

**function details**:

* `requestWithdraw(uint256 _unlockingAmount)` | **Permissionless** : Request a withdrawal of the deposited underlying ERC20.
* `cancelWithdrawalRequests(uint256[] calldata _ids)` | **Permissionless** : Allow to cancel single and multiple withdrawal requests.
* `updateTimeLockDuration(uint64 _newTimeLockDuration)` | **Restricted** : Allow to update the time lock duration.
* `updateStartPenaltyPercentage(uint256 _newStartPenaltyPercentage)` | **Restricted** : Allow to update the start penalty percentage.
* `updateFeeReceiver(address _newFeeReceiver)` | **Restricted** : Allow to update the fee receiver.
* `pause()` | **Restricted** : Allow to pause the contract.
* `unpause()` | **Restricted** : Allow to unpause the contract.

#### &#x31;**.2.2** [**sPRL1**](https://github.com/parallel-protocol/parallel-tokenomics/blob/main/contracts/sPRL/sPRL1.sol)

This contract allow users to stake their PRL tokens to receive sPRL1 tokens and be able to get rewards from the RewardMerkleDistributor. Inherits from TimeLockPenaltyERC20 without addidtional features.

**function details**:

* `deposit(uint256 _amount)` | **Permissionless** : Allow to deposit PRLs and mint the equivalent amount of sPRL1.
* `depositWithPermit(uint256 _amount, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s)` | **Permissionless** : Allow to deposit PRLs using ERC20Permit and mint the equivalent amount of sPRL1.
* `withdraw(uint256[] calldata _ids, uint256 _maxAcceptablePenalty)` | **Permissionless** : Allow to withdraw single and multiple withdrawal requests. If the user withdraw before the lock time, the penalty will be applied. Reverts when the start penalty percentage is above `_maxAcceptablePenalty`.
* `emergencyWithdraw(uint256 _unlockingAmount)` | **Permissionless** : Allow to emergency withdraw assets without penalties. Only callable when the contract is paused.

#### &#x31;**.2.3** [**sPRL2 (v1, paused)**](https://github.com/parallel-protocol/parallel-tokenomics/blob/main/contracts/sPRL/sPRL2.sol)

The first sPRL2 vault, deployed on Ethereum only. It is paused since Tokenomics v2.1 (PIP-68): its holders move their position to sPRL2V2 through the sPRL2Migrator, or leave with `emergencyWithdraw`.

This contract allow users to stake either their Balancer BPT or their PRL/ETH. BPT will be staked into Aura.finance and user will receive sPRL2 tokens equal to their BPT amount. This contract is also able to directly deposit PRL and ETH (or WETH) into the Balancer pool and to deposit the BPT into the Aura.finance pool. On the withdraw side, users can withdraw their the BPT or the amount of PRL/ETH or PRL/WETH linked to the BPT.

**function details**:

* `depositBPT(uint256 _amount)` | **Permissionless** : Allow to deposit BPT and mint the equivalent amount of sPRL2 to the user.
* `depositPRLAndWeth(uint256 _maxPrlAmount, uint256 _maxWethAmount, uint256 _exactBptAmount, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s)` | **Permissionless** : Allow to deposit PRL and WETH and mint the equivalent amount of sPRL2 to the user.
* `depositPRLAndEth(uint256 _maxPrlAmount, uint256 _exactBptAmount, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s)` | **Permissionless** : Allow to deposit PRL and ETH and mint the equivalent amount of sPRL2 to the user.
* `withdrawPRLAndWeth(uint256[] calldata _requestIds, uint256 _minPrlAmount, uint256 _minWethAmount, uint256 _maxPenaltyPercentage)` | **Permissionless** : Allow to withdraw single and multiple requests of PRL and WETH from the Balancer pool attached to the sPRL2 token.
* `withdrawBPT(uint256[] calldata _requestIds, uint256 _maxAcceptablePenalty)` | **Permissionless** : Allow to withdraw single and multiple requests of BPT from the Aura.finance pool attached to the sPRL2 token.
* `claimRewards()` | **Permissionless** : Allow to claim the rewards generated by the BPT staked into Aura.finance and to send them to the fee receiver.
* `emergencyWithdraw(uint256 _unlockingAmount)` | **Permissionless** : Allow to emergency withdraw assets without penalties. Only callable when the contract is paused.

#### &#x31;**.2.4** [**sPRL2V2**](https://github.com/parallel-protocol/parallel-tokenomics/blob/dev/contracts/sPRL/sPRL2V2.sol)

The sPRL2 vault since Tokenomics v2.1 (PIP-68), deployed on Ethereum and Base. It takes the BPT of the chain's 80PRL/20WETH Balancer V3 pool, or PRL with WETH or ETH, which it adds to the pool, and mints sPRL2V2 1:1 with the BPT. The BPT stays in the contract: nothing is staked on Aura.finance, so there are no reward functions. Inherits from the TimeLockPenaltyERC20 of the same release, which adds a restricted `recoverERC20(IERC20 _token)` to rescue idle tokens.

**function details**:

* `depositBPT(uint256 _amount)` | **Permissionless** : Allow to deposit BPT and mint the equivalent amount of sPRL2V2 to the user.
* `depositPRLAndWeth(uint256 _maxPrlAmount, uint256 _maxWethAmount, uint256 _exactBptAmount, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s)` | **Permissionless** : Allow to add PRL and WETH to the Balancer pool and mint sPRL2V2 for the BPT received. What the pool does not take is returned.
* `depositPRLAndEth(uint256 _maxPrlAmount, uint256 _exactBptAmount, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s)` | **Permissionless** : Same with ETH, wrapped to WETH by the contract.
* `withdrawBPT(uint256[] calldata _requestIds, uint256 _maxAcceptablePenalty)` | **Permissionless** : Allow to withdraw single and multiple requests as BPT. The penalty, if any, is sent to the fee receiver in BPT.
* `withdrawPRLAndWeth(uint256[] calldata _requestIds, uint256 _minPrlAmount, uint256 _minWethAmount, uint256 _maxPenaltyPercentage)` | **Permissionless** : Allow to withdraw single and multiple requests as PRL and WETH, removed from the Balancer pool.
* `emergencyWithdraw(uint256 _amount)` | **Permissionless** : Allow to emergency withdraw BPT without penalties. Only callable when the contract is paused.

#### &#x31;**.2.5** [**sPRL2Migrator**](https://github.com/parallel-protocol/parallel-tokenomics/blob/dev/contracts/sPRL/sPRL2Migrator.sol)

Moves a position from the paused sPRL2 vault to sPRL2V2 in one transaction, on Ethereum. It takes the user's sPRL2, withdraws the BPT through `emergencyWithdraw`, without penalty, deposits it into sPRL2V2 and sends the sPRL2V2 to the user.

**function details**:

* `migrate(uint256 _amount)` | **Permissionless** : Allow to migrate an amount of sPRL2 to sPRL2V2. The user approves the migrator to spend the sPRL2 first.

### 1.3 Rewards

This section contains the contracts related to the rewards distribution of the protocol.

#### &#x31;**.3.1** [**RewardMerkleDistributor**](https://github.com/parallel-protocol/parallel-tokenomics/blob/main/contracts/rewardMerkleDistributor/RewardMerkleDistributor.sol)

This contract will receive fees from the MainFeeDistributor and distribute them to users using merkle proofs managed by the protocol. Since Tokenomics v2.1 (PIP-68), it distributes USDp on Base; the one on Polygon PoS holds the PAR epochs published before, which stay claimable there.

**Functions Details**

* `claims(ClaimCallData[] calldata _claimsData)` | **Permissionless** : Allow user to claim the rewards of one or several epochs using merkle proofs.
* `forwardExpiredRewards(uint64[] calldata _epochIds)` | **Permissionless** : Allow to forward the expired rewards to the expiredRewardsRecipient.
* `updateMerkleDrop(uint64 _epoch, MerkleDrop memory _merkleDrop)` | **Restricted** : Allow to update the merkle drop for a specific epoch.
* `updateExpiredRewardsRecipient(address _newExpiredRewardsRecipient)` | **Restricted** : Allow to update the destination receiver of the expired rewards.
* `emergencyRescue(address _token, address _to, uint256 _amount)` | **Restricted** : Allow to rescue tokens from the contract.
* `pause()` | **Restricted** : Allow to pause the contract.
* `unpause()` | **Restricted** : Allow to unpause the contract.
