# .validateBorrow

## Overview

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2FYLfyJEi2Nv99n8CBOZwd%2Fimage.png?alt=media&#x26;token=9b5204d3-c965-4245-9cc5-f00f42155f62" alt=""><figcaption></figcaption></figure>

* [x] <mark style="color:orange;">cache</mark>
* [x] <mark style="color:orange;">updateState</mark>
* [x] getIsolationMode
* [ ] validateBorrow
* [ ] mint debt token
* [ ] setBorrowing&#x20;
* [ ] update IsolationMode debt
* [ ] <mark style="color:orange;">updateInterestRates</mark>
* [ ] transfer underlying to user

<img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2F3984GgczZMzsMTldH5Ai%2Ffile.excalidraw.svg?alt=media&#x26;token=541b634e-30b6-40dd-96aa-c6934f1ae62e" alt="" class="gitbook-drawing">

## validateBorrow()

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2FYO6w1gZt33g2AKHKdorX%2Fimage.png?alt=media&#x26;token=30ae7f84-7355-4432-a97c-cd530d3c37ea" alt=""><figcaption></figcaption></figure>

1. getFlags (status check)
2. L2 priceOracleSentinel check
3. InterestRateMode check (stable or variable)
4. Get decimals & borrowCap
5. Check borrowCap is not exceeded
6. If in Isolation Mode&#x20;
   * check if asset is borrowable in Isolation mode and,&#x20;
   * total exposure is less than the collateral debt ceiling
7. if in E-Mode&#x20;
   * check reserve is in the same E-mode as user,&#x20;
   * get eModePriceSource
8. CalculateUserAccountData:&#x20;
   * HF, LTV, userDebt, userCollateral...
   * ensure account health is sound
9. Check if new total debt can be supported by collateral
   1. Convert new borrow into Base CCY
   2. Calculate total collateral required in Base CCY
   3. check if sufficient collateral
10. If stable borrow -> check if requirements are met
11. If user is already borrowing ANY reserve -> check if in siloed borrowing state

### getFlags

Asset must be

* Active
* NOT PAUSED
* NOT FROZEN
* Borrowing enabled

{% hint style="info" %}
For in-depth explanation see: see [getFlags](../common-functions/getflags)
{% endhint %}

### L2 priceOracleSentinel check

{% code overflow="wrap" %}
```solidity
require(params.priceOracleSentinel == 
    address(0) ||     
    IPriceOracleSentinel(params.priceOracleSentinel).isBorrowAllowed(),        
    Errors.PRICE_ORACLE_SENTINEL_CHECK_FAILED);
```
{% endcode %}

priceOracleSentinel is for L2 markets, when sequencer fails/lags.

* address(0) -> none set, since L1
* if address set -> check that borrow is allowed

### InterestRateMode check (stable or variable)

```solidity
//validate interest rate mode
require(
  params.interestRateMode == DataTypes.InterestRateMode.VARIABLE ||
    params.interestRateMode == DataTypes.InterestRateMode.STABLE,
  Errors.INVALID_INTEREST_RATE_MODE_SELECTED
);
```

`params.interestRateMode` is an enum; representation of user input via UIUX.

* either variable or stable must be selected
* else transaction reverts with error

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2FMxEC0Pg9DGWzNVjjloEm%2Fimage.png?alt=media&#x26;token=a67b3fbd-94ad-4fa8-b4f2-39f4a68b5b95" alt=""><figcaption></figcaption></figure>

### Get decimals & borrowCap&#x20;

```solidity
vars.reserveDecimals = params.reserveCache.reserveConfiguration.getDecimals();
vars.borrowCap = params.reserveCache.reserveConfiguration.getBorrowCap();
unchecked {
  vars.assetUnit = 10 ** vars.reserveDecimals;
}
```

* retrieve the asset's decimals and borrow cap, for which the user wishes to borrow.
* To understand `getDecimals`: see [getDecimals](../common-functions/getreservefactor-getdecimals) under common functions
* To understand `getBorrowCap`: see [SupplyCap, BorrowCap](../common-functions/supplycap-borrowcap) under common functions

{% hint style="info" %}
what assets have borrowCaps, and wen?
{% endhint %}

Once we have the decimals for the asset, we can define 1 unit of the asset in terms of decimals:

```solidity
vars.assetUnit = 10 ** vars.reserveDecimals;
```

This is important because assets can have different definitions of 1 unit, due to inconsistent use of decimals:

* Most typical ERC20 tokens: 1 unit = `1e18`
* USDC: 1 unit = `1e6`

### Check borrowCap

* If (borrowCap != 0) {...check that its not exceeded with this new borrow action...}
*   if there is borrowCap set, `vars.borrowCap` will be some non-zero value, thereby moving to execute the code within the if block.

    ```solidity
    if (vars.borrowCap != 0) {
      vars.totalSupplyVariableDebt = params.reserveCache.currScaledVariableDebt.rayMul(
        params.reserveCache.nextVariableBorrowIndex
      );

      vars.totalDebt =
        params.reserveCache.currTotalStableDebt +
        vars.totalSupplyVariableDebt +
        params.amount;

      unchecked {
        require(vars.totalDebt <= vars.borrowCap * vars.assetUnit, Errors.BORROW_CAP_EXCEEDED);
      }
    }
    ```


* Check that borrowCap is not exceeded with latest `variableBorrowIndex`&#x20;
* `currentDebt * newVariableIndex` (index updated in `updateState`)&#x20;

**Ignores incoming borrow action:**

* only checks that preexisting debt compounded with the most recent interest does not exceed borrow cap.
* If so, can move forward and validate the incoming borrow action.

{% hint style="info" %}
If existing debt (variable + stable) accounting for latest interest, exceeds borrow cap -> to hell with your borrow
{% endhint %}

{% hint style="info" %}
Remember that totalStableDebt was obtained in .cache via `getSupplyData()`

* ```
  reserveCache.currTotalStableDebt = _calcTotalSupply(avgRate)
  ```
{% endhint %}

### If in Isolation Mode&#x20;

* check if asset is borrowable in Isolation mode and,&#x20;
* total exposure is less than the collateral debt ceiling

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2FE6gflwedRvMWICBCptOj%2Fimage.png?alt=media&#x26;token=652e1b1a-4a3e-4b22-805a-6d17f8f21df2" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2FIqydKHRX4ynAaau6vVDi%2Fimage.png?alt=media&#x26;token=e46b2e61-163b-4cbc-8b2d-3f33c9db7d10" alt=""><figcaption></figcaption></figure>

* Extracts bit 80 - 115 in the bitmap `ReserveConfigurationMap`
* For in-depth explanation see: see [getFlags](../common-functions/getflags)

### If in E-Mode&#x20;

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2FHcnFYoZmSNz4e1xo1D7r%2Fimage.png?alt=media&#x26;token=83d74ee6-98f1-435b-8f50-77ae3c483ee5" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2FZHyEnPc8GQsdLlsLYurS%2Fimage.png?alt=media&#x26;token=7b2a9b91-c339-4efd-b4c7-d9f66393597b" alt=""><figcaption></figcaption></figure>

* See [getReserveFactor](../../common-functions/getreservefactor-getdecimals#getreservefactor), the process is similar.

### calculateUserAccountData

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2FMgN2MWNUJYqi1y05yGMY%2Fimage.png?alt=media&#x26;token=c7ed0775-799f-4ac3-866b-48e3c5504cd0" alt=""><figcaption></figcaption></figure>

* See [calculateUserAccountData](../common-functions/calculateuseraccountdata)
* Serves to validate account health; healthFactor > 1

### Check if new total debt can be supported by collateral

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2FLcHGAP98NsqEfo7kHauo%2Fimage.png?alt=media&#x26;token=973550e5-42e0-4f32-aa49-cdae86cf8366" alt=""><figcaption></figcaption></figure>

* Convert new borrow into Base CCY
* Calculate total collateral required in Base CCY
* Check if sufficient collateral

{% hint style="info" %}
What is the base currency on Aave?

* It depends on the market, V2 ETH Mainnet and V2 Polygon use ETH-based oracles, and all other markets use USD-based oracles
* Each market has an AaveOracle contract where you can query token prices in the base currency.
{% endhint %}

### If stable borrow -> check if requirements are met

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2F7KlVIHCDQ7MWGqUPkRRQ%2Fimage.png?alt=media&#x26;token=6e35003b-47cc-4c68-a883-072389724969" alt=""><figcaption></figcaption></figure>

1. reserve must be enabled for stable rate borrowing
2. (user should not be using reserve as collateral) || (LTV for reserve should be 0) || borrowAmount < user's Atoken balance
3. Users can only borrow only a portion of total available liquidity

User can only borrow up to 25% of `availableLiquidity`, in a single stable borrow transaction.&#x20;

### If user is already borrowing ANY reserve -> check if in siloed borrowing state

<figure><img src="https://1829638638-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0k7YXwFGMFZcsyqkM4q1%2Fuploads%2FOPYhEPkV274OD8ZSSGNr%2Fimage.png?alt=media&#x26;token=4c4ffd60-6fb9-469a-8cdb-1df018bae77a" alt=""><figcaption></figcaption></figure>

If the user already has a borrowing position, check if the user is in siloed borrowing mode.&#x20;

If user is in siloed borrowing mode, ensure that they are borrowing more of the siloed asset, not some other asset.
