# Controller

The **Controller** allows users to get the list of deployed **PalPools** & **PalTokens**, and also to check if a **Withdraw** or a **Borrow** is possible on a given **Pool** without asking the **Pool** directly, and hooks called by some **PalPool**’s method to verify that an action (**Deposit, Withdraw, Borrow**, …) executed correctly.<br>

The **Controlle**r is composed of 2 smart contracts, working in a Proxy & Implementation system. The Implementation can be changed to upgrade the Controller, and add more functions to it.

Users can also stake their PalTokens in the PaladinController, to take part in the [Liquidity Mining](/paladin-lending/liquidity-mining.md) program. Rewards distribution is different for the Supply side and the Borrow side :&#x20;

* For the Supply side, each PalPool gets a supplySpeed, representing the number of PAL distributed to stakers each block (for PalPool with no rewards, the supplySpeed is set as 0).
* For the Borrow side, PalPools get a borrowRatio, use to reward borrowers depending on how much fees were used by their PalLoans (for PalPool with no rewards, the borrowRatio is set as 0). For example, on a PalPool with a borrowRatio of 0.75, a PalLoan that paid 70 TOKEN of fees, but only used 50 TOKEN of those fees at closing, will receive a reward of 37.5 PAL.

All Supply Rewards are accrued to a claimable balance for the user, allowing to claim it all at any point.&#x20;

For the Borrow Rewards, some are directly accrued to the same claimable balance than the Supply Rewards, but for some PalPools (all the Pools having autoBorrowRewards set as false), users will have to manually claim rewards for each of their PalLoan.\ <br>

## Methods :

### Events :&#x20;

**NewPalPool**

`event NewPalPool(address palPool);`

When a new Pool is added to the Controller List<br>

**RemovePalPool**

`event RemovePalPool(address palPool, address palToken);`

When a new Pool is removed to the Controller List<br>

**Deposit**

`event Deposit(address indexed user, address palToken, uint amount);`

When an user deposits PalTokens in the Controller for Supply Rewards<br>

**Withdraw**

`event Withdraw(address indexed user, address palToken, uint amount);`

When an user withdraws PalTokens from the Controller<br>

**ClaimRewards**

`event ClaimRewards(address indexed user, uint amount);`

When an user claimed its reward tokens<br>

**PoolRewardsUpdated**

`event PoolRewardsUpdated(address palPool, uint newSupplySpeed, uint newBorrowRatio, bool autoBorrowReward);`

When a PalPool Rewards parameters (Speed, Ratio or both) were updated by the admin<br>

**NewPendingImplementation**

`event NewPendingImplementation(address oldPendingImplementation, address newPendingImplementation);`

When a new Implementation was proposed to the Proxy<br>

**NewImplementation**

`event NewImplementation(address oldImplementation, address newImplementation);`

When the pending Implementation was accepted for the Proxy\ <br>

### Useful methods :&#x20;

**isPalPool**

`function isPalPool(address _pool) external view returns(bool);`

&#x20;   Returns 'true' if the given address is a PalPool listed in the Controller<br>

**getPalTokens**

`function getPalTokens() external view returns(address[] memory);`

&#x20;   Returns the list of PalTokens stored by the Controller<br>

**getPalPools**

`function getPalPools() external view returns(address[] memory);`

&#x20;   Returns the list of PalPools stored by the Controller<br>

**palTokenToPalPool**

`function palTokenToPalPool(address palToken) external view returns(address);`

&#x20;   Returns the PalPool associated to the given PalToken<br>

**rewardTokenAddress**

`function rewardTokenAddress() external view returns(address);`

&#x20;   Returns the reward Token (PAL token)<br>

**supplyRewardState**

`function supplyRewardState(address palPool) external view returns(supplyRewardState);`

&#x20;   Returns the current SupplyRewardState for a given PalPool

&#x20;    ***SupplyRewardState struct :***&#x20;

| name        | type    | desc                                    |
| ----------- | ------- | --------------------------------------- |
| index       | uint224 | Current rewards index, from last update |
| blockNumber | uint32  | Last block this state was updated       |

<br>

**supplySpeeds**

`function supplySpeeds(address palPool) external view returns(uint);`

&#x20;   Returns the Supply Speed for a given PalPool<br>

**supplierDeposits**

`function supplierDeposits(address palPool, address user) external view returns(uint);`

&#x20;   Returns the amount of palToken deposited for a given PalPool by a given user<br>

**totalSupplierDeposits**

`function totalSupplierDeposits(address palPool) external view returns(uint);`

&#x20;   Returns the total amount of PalTokens deposited fir the given PalPool<br>

**borrowRatios**

`function borrowRatios(address palPool) external view returns(uint);`

&#x20;   Returns the Borrow Ratio for the given PalPool<br>

**autoBorrowRewards**

`function autoBorrowRewards(address palPool) external view returns(bool);`

&#x20;   Returns 'true' if the PalPool is auto-accruing Borrow Rewards to the user claimable amount. If 'false', users need to claim Borrow Rewards manually<br>

**isLoanRewardClaimed**

`function isLoanRewardClaimed(address palLoan) external view returns(bool);`

&#x20;   Returns 'true' if the PalLoan rewards were already claimed or distributed<br>

**withdrawPossible**

`function withdrawPossible(address palPool, uint amount) external view returns(bool);`

Check if a withdraw is possible on a given PalPool

#### *Parameters :*&#x20;

| name    | type    | desc                      |
| ------- | ------- | ------------------------- |
| palPool | address | the Pool to withdraw from |
| amount  | uint    | the amount to withdraw    |

**borrowPossible**

`function borrowPossible(address palPool, uint amount) external view returns(bool);`

Check if a borrow is possible on a given PalPool

#### *Parameters :*&#x20;

| name    | type    | desc                    |
| ------- | ------- | ----------------------- |
| palPool | address | the Pool to borrow from |
| amount  | uint    | the amount to withdraw  |

**deposit**

`function deposit(address palToken, uint amount) external returns(bool);`

Deposit PalTokens in the Controller to receive Supply Rewards

#### *Parameters :*&#x20;

| name     | type    | desc                          |
| -------- | ------- | ----------------------------- |
| palToken | address | Address of the PalToken       |
| amount   | uint    | amount of PalToken to deposit |

**withdraw**

`function withdraw(address palToken, uint amount) external returns(bool);`

Withdraw PalTokens staked in the Controller

#### *Parameters :*&#x20;

| name     | type    | desc                            |
| -------- | ------- | ------------------------------- |
| palToken | address | Address of the PalToken         |
| amount   | uint    | amount of PalTokens to withdraw |

**claimable**

`function claimable(address user) external view returns(uint);`

Return the amount of reward tokens accrued from last user state update

**estimateClaimable**

`function estimateClaimable(address user) external view returns(uint);`

Return the amount of reward tokens accrued from last user state update + an estimation of rewards to be accrued from last PalPools States updates (that are not accrued into the user claimable amount without an update of the user state)

**claim**

`function claim(address user) external;`

Update the user Reward State and claim all accrued rewards

**updateUserRewards**

`function updateUserRewards(address user) external;`

Updates the user Reward States for all PalPools the user is staking PalTokens.

**claimableLoanRewards**

`function claimableLoanRewards(address palPool, address loanAddress) external view returns(uint);`

Return the amount of reward tokens the user could claim for their PalLoan.

Return 0 if :&#x20;

* PalLoan is not Closed/Killed yet
* PalPool has the auto-accruing rewards system (no need to manually claim, rewards are already distributed)
* Rewards were already claimed for that PalLoan

#### *Parameters :*&#x20;

| name        | type    | desc                                           |
| ----------- | ------- | ---------------------------------------------- |
| palPool     | address | address fo the PalPool that issued the PalLoan |
| loanAddress | address | address of the PalLoan to claim rewards for    |

**claimLoanRewards**

`function claimLoanRewards(address palPool, address loanAddress) external;`

Claim the potential rewards for a PalLoan

Fails if :&#x20;

* PalLoan is not Closed/Killed yet
* PalPool has the auto-accruing rewards system (no need to manually claim, rewards are already distributed)
* Rewards were already claimed for that PalLoan

#### *Parameters :*&#x20;

| name        | type    | desc                                           |
| ----------- | ------- | ---------------------------------------------- |
| palPool     | address | address fo the PalPool that issued the PalLoan |
| loanAddress | address | address of the PalLoan to claim rewards for    |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.paladin.vote/paladin-lending/technical-docs/controller.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
