Ensure existing loans are collateralized

Overview

isBorrowingAny

This function checks if a user has been borrowing any asset.

  • Takes UserConfigurationMap as input, which contains a bitmap of the user's collaterals and borrows.

Uses BORROWING_MASK, which is a bitmask that isolates the borrowing bits within data. BORROWING_MASK has a specific pattern of bits, with alternating 1 and 0.

// UserConfiguration.sol
uint256 internal constant BORROWING_MASK = 
0x5555555555555555555555555555555555555555555555555555555555555555;

// 0x55 -> Binary(1010101)

The function applies this mask to data using a bitwise AND operation (&). This effectively keeps only the bits in data that correspond to borrowing positions, while setting all other bits to 0.

If the result of the bitwise AND operation between self.data and BORROWING_MASK is not equal to 0, it means that at least one bit in the borrowing position is set to 1. This indicates that the user has been borrowing from at least one reserve.

Illustrated Explanation

To understand how the BORROWING_MASK works as a bitmask, let's take a closer look at its binary representation:

BORROWING_MASK: 0x5555555555555555555555555555555555555555555555555555555555555555

In binary: 0101010101010101010101010101010101010101010101010101010101010101

Each '0' represents a bit that will be set to 0 when the BORROWING_MASK is applied, and each '1' represents a bit that will be preserved. When the BORROWING_MASK is applied to the data field using a bitwise AND operation (&), the resulting value will have only the borrowing-related bits preserved, while all other bits will be set to 0.

For example, let's assume the data field contains the following binary representation:

data: 1111111111111111111111111111111111111111111111111111111111111111

Applying the BORROWING_MASK using a bitwise AND operation:

data & BORROWING_MASK:

1111111111111111111111111111111111111111111111111111111111111111 & 0101010101010101010101010101010101010101010101010101010101010101

=> 0101010101010101010101010101010101010101010101010101010101010101

The resulting value preserves only the bits in the borrowing positions, while setting all other bits to 0. In this case, the preserved bits represent the borrowing positions, indicating which assets are borrowed by the user.

To summarize, BORROWING_MASK is a bitmask that preserves only the borrowing-related bits within the data field. Applying the BORROWING_MASK using a bitwise AND operation helps identify the borrowed assets by setting all non-borrowing bits to 0 and preserving the borrowing bits.

If the user is borrowing any asset, AND has been using the asset about to be withdrawn as collateral => need to validate HF and LTV.

Check loans (validate HF and LTV)

  • calls on validateHealthFactor to return the bool hasZeroLTVCollateral

Etiher one of the following two conditions must be true for this function to not revert:

  1. !hasZeroLtvCollateral: user has a non-zero LTV value across all assets

  2. Asset being withdrawn has an LTV of 0

Condition 1 serves as a sanity check, given that validateHFAndLtv is executed in the context that the user isBorrowingAny .

validateHealthFactor

This function is primarily a wrapper around .calculateUserAccountDataParams.

The require statement ensures that the calculated health factor (after withdrawal) is above the liquidation threshold. If its not, user will be unable to withdraw asset.

.calculateUserAccountDataParams

This function calculates and returns the following user data across all the assets:

  • totalCollateralInBaseCurrency

  • totalDebtInBaseCurrency

  • avgLTV

  • avgLiquidationThreshold

  • healthFactor

  • hasZeroLtvCollateral

See calculateUserAccountDataParams for the full breakdown explanation.

Last updated