# Borrow & Repay & Liquidate

### Borrow

#### `borrow`

```solidity
function borrow(
    address asset,
    uint256 amount,
    uint256 interestRateMode,
    uint16 referralCode,
    address onBehalfOf
) external
```

Allows a user to **borrow** a specific amount of an underlying asset from the pool, provided they have sufficient collateral deposited (or they have credit delegation allowance from someone with collateral). The borrowed amount results in the user incurring a debt obligation in the protocol.

* **Collateral requirement:** The caller (or the `onBehalfOf` address if borrowing on behalf of someone else) must have supplied enough collateral to cover the new loan according to the asset’s Loan-to-Value (LTV) and their current obligations. Borrowing will reduce the user’s health factor. If taking this loan would push the health factor below 1 (i.e., violate collateralization ratios), the borrow will fail. Users should maintain a healthy buffer above the minimum collateral requirement to avoid liquidation.
* **Debt tokens:** When the borrow is executed, Helios **mints debt tokens** to track the debt. In Aave V3 (and similarly in Helios), there are separate debt tokens per asset (e.g., variable debt tokens). If a user borrows 100 USDC, they receive 100 USDC in their wallet and concurrently 100 units of **variable debt USDC** are minted to their address to represent their debt. The debt token balance will increase over time as interest accrues on the loan.
* **Interest rate mode:** Helios may support different interest rate modes. In Aave v3, only variable rate is supported (interestRateMode = 2) and stable rate borrowing is unavailable by default. In Helios, if only a variable rate is available, this parameter should be set to the designated constant (e.g. `2` for variable). The borrow will occur at the variable interest rate for that asset, which can fluctuate over time based on supply and demand in the market.
* **`onBehalfOf`:** If borrowing for oneself, `onBehalfOf` should be the same as `msg.sender`. If a user is performing a **credit delegation**, `onBehalfOf` will be the address of the person who **supplied collateral** and enabled the caller to borrow against that collateral. In the credit delegation scenario, the collateral provider (onBehalfOf) must have pre-approved the caller (msg.sender) to borrow a certain amount via the debt token’s `approveDelegation()` function. This allows one address to incur debt using another address’s collateral within permitted limits.
* **Referral code:** Similar to `supply`, an optional referral code can be passed to `borrow`. This code is currently not active in Helios (use 0), but is recorded for potential future referral reward programs.

Once the assets are borrowed, they are transferred to the borrower’s (or designated onBehalfOf) address for use freely. The borrower’s debt will accrue interest until it is repaid.

*Example:* If a user supplies collateral (say, 2 BTC worth of various assets) and then borrows 1 BTC worth of USDC, they will receive that USDC to their address. At the same time, their account’s health factor will drop according to the new debt, and a corresponding debt token balance is created for them representing the 1 BTC worth of USDC debt at the current exchange rate.

### Repay

#### `repay`

```solidity
function repay(
    address asset,
    uint256 amount,
    uint256 interestRateMode,
    address onBehalfOf
) external returns (uint256)
```

Repays a borrowed amount on a specific reserve, reducing the debt of the borrower and burning the corresponding debt tokens. This function can be used to **pay back loans**, either by the borrower themselves or by someone else on their behalf.

* The caller must have enough of the underlying asset to cover the repayment amount, and must **approve** the Helios Pool contract to pull the repayment amount (unless using a permit version of repay). When `repay` is executed, the Pool transfers the `amount` of the asset from the payer and uses it to cancel out an equivalent amount of the borrower’s debt.
* If `onBehalfOf` is set to the borrower’s own address, the function will repay the caller’s debt. If `onBehalfOf` is set to another user’s address, the caller is effectively repaying someone else’s loan. This is allowed in Helios: one address can repay debt for another (commonly used by liquidators or automated systems, but also possible manually if you wish to help repay someone’s loan).
* The `interestRateMode` should match the type of debt being repaid. In Helios (like Aave v3), only variable-rate debt exists, so this should be `2`. (If fixed-rate debt were enabled in the future, a different code might be used, but currently this parameter will always be the variable rate indicator.)
* **Full vs Partial Repay:** The `amount` is specified in the underlying asset’s smallest units. A user can repay **the entire loan** by passing `type(uint256).max` as the amount. In this case, the protocol will figure out the exact outstanding debt of the `onBehalfOf` and attempt to repay all of it.
  * When repaying one’s **own debt**, using `uint256.max` is a convenient way to clear the whole debt. The function will return the actual amount that was needed and taken for the payoff.
  * **Important:** When repaying on behalf of someone else, it is recommended not to rely on `uint256.max` alone (since it’s interpreted as a very large number in the context of someone else’s debt and could just attempt to pull an excessive amount up to that limit). Instead, you might send an explicit amount slightly higher than the expected debt to ensure the loan is fully covered (any excess sent will be returned to the payer). This accounts for any interest that may accrue between the time of calculation and the on-chain transaction execution.
* On success, the borrower’s debt is reduced (their debt token balance is burned). If the repayment fully covers the outstanding loan for that interest rate type, the debt token balance will go to zero (meaning that asset is completely paid off for that user).

**Return value:** `repay` returns a `uint256` representing the actual amount of the underlying asset that was used to repay the debt. This is useful because if the user attempted to repay more than the outstanding debt, the contract will only take what is needed. The return value lets the caller know how much was actually deducted and applied to the loan.

*Example:* A user has a variable-rate debt of 500 USDC. They call `repay(asset = USDC, amount = 600, interestRateMode = 2, onBehalfOf = self)`. Assuming 500 USDC is still the outstanding amount at execution time, the contract will pull 500 USDC from the user (provided it was approved) to clear the debt. The extra 100 USDC in the allowance is not used. The function returns 500 (the actual repaid amount). The user’s USDC variable debt is now 0, and they are free of that loan.

### Liquidate

#### `liquidationCall` (Liquidate)

```solidity
function liquidationCall(
    address collateralAsset,
    address debtAsset,
    address user,
    uint256 debtToCover,
    bool receiveHToken
) external
```

*(Function name in Helios Pool contract: `liquidationCall`. This is the **liquidation** function.)*

Liquidates an unhealthy loan position. When a borrower’s **Health Factor** falls below 1.0 (meaning the value of their collateral is no longer sufficient to cover their debt), their position becomes liquidatable. A liquidator (any external account) can call this function to repay a portion of the borrower’s debt and seize an equivalent portion of the borrower’s collateral at a discount.

Key mechanics of liquidation in Helios:

* **Trigger condition:** Health Factor (HF) < 1.0. The health factor is calculated based on the borrower’s total collateral value vs total borrowed value, considering asset-specific collateralization ratios. If HF < 1, the loan is undercollateralized and eligible for liquidation. (Anyone can check a user’s HF via a data helper or by calling `getUserAccountData` in Aave/Helios if available.)
* **Debt to cover:** The liquidator specifies `debtAsset` (which asset to repay on behalf of the borrower) and an amount `debtToCover`. The protocol allows a liquidator to repay **up to a certain portion of the outstanding debt** — this portion is defined by the **close factor**. By default, the close factor is 50% (0.5) of the borrower’s debt *per liquidation call*. This means the liquidator can cover at most 50% of each kind of debt in one go. If the liquidator passes an amount larger than the maximum allowed (or uses `type(uint256).max` for `debtToCover`), the contract will internally limit the repayment to the maximum permitted by the close factor for that asset.
* **Collateral seized:** In return for repaying the debt, the liquidator receives a portion of the borrower’s collateral. The `collateralAsset` specifies which asset the liquidator will take from the user’s supplied assets. The protocol applies a **liquidation bonus** (or **discount**) to the collateral, meaning the liquidator can obtain slightly more value in collateral than the debt they repaid (the difference incentivizes liquidators and accounts for market risk). For example, if the liquidation bonus is 10%, repaying $100 of debt allows the liquidator to seize $110 worth of the collateral asset.
* **Receive hToken or underlying:** The `receiveHToken` flag lets the liquidator choose how they want to receive the collateral.
  * If `receiveHToken = false`, the liquidator will receive the **underlying tokens** of the collateral asset (e.g., if collateralAsset is BTC, they get BTC transferred to them). This is the common case if the liquidator wants to take possession of the tokens (perhaps to sell them on the market).
  * If `receiveHToken = true`, the liquidator instead receives **hTokens** corresponding to the collateral asset. This means essentially the liquidator steps into a portion of the borrower’s deposit position. The liquidator becomes the owner of those hTokens (and can later withdraw the underlying or keep earning interest on them). Receiving hTokens is useful if the liquidator prefers to keep the collateral supplied in Helios (maybe to avoid withdrawal or because they believe it’s beneficial to continue earning interest).
* The liquidator must provide the `debtAsset` in the transaction. Just like a normal repay, the Pool contract will pull the specified amount of `debtAsset` from the liquidator’s address (so the liquidator must have approved the Pool to spend the tokens they are using for repayment). Essentially, the liquidator is paying off the borrower's loan (up to the allowed amount) on their behalf.
* After a successful liquidation, the borrower’s outstanding debt for that asset is reduced by the amount covered, and their collateral is reduced by the amount seized. This will typically **improve the borrower’s health factor**, hopefully bringing it back above 1 (if only a portion of debt was liquidated, the user might still have other debt remaining, but at least the ratio is improved). If the user remains below HF 1, further liquidation calls can occur (by the same or other liquidators) until the position is stable or fully liquidated.

**Important points for liquidation:**

* A liquidator can profit from the spread between the collateral seized (with bonus) and the debt repaid. In most cases, a rational liquidator will aim to repay the maximum allowed (50% of debt) to seize as much discounted collateral as possible in one transaction.
* Helios (like Aave) enforces the close factor per liquidation to prevent complete drain of a user’s collateral in one call and to give the borrower a chance to recover. The default close factor is 50%. If `debtToCover` is set to the maximum value (`type(uint256).max`), the protocol will automatically calculate the maximum repayable amount (50% of the debt for that asset) and use that.
* Liquidations incur no direct fee besides gas costs, but the liquidator’s gain is the liquidation bonus on collateral. The parameters like close factor and bonus are configured per asset (or globally) and can be adjusted via Helios governance if needed to maintain market stability.
* All involved transfers (debt repayment from liquidator and collateral transfer to liquidator) happen within this single transaction. If anything fails (e.g., not enough allowance, or the position isn’t actually liquidatable, or other checks fail), the whole liquidation call reverts.

After the liquidation, the `liquidationCall` will emit events documenting the debt repaid and collateral liquidated. Observers can track these events for record-keeping or UIs. Borrowers who got liquidated will see a reduced collateral balance and a lower debt, but also incur a penalty (losing more collateral value than debt repaid, due to the bonus given to the liquidator).
