> ## Documentation Index
> Fetch the complete documentation index at: https://docs.eco.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Borrow on Aave V3 with a health-factor floor

> One Base transaction that supplies WETH to Aave V3, borrows USDC against it, requires a minimum health factor and sends the USDC to a recipient.

The program supplies `collateral` WETH from the Pot to Aave V3, borrows `borrowUsdc` USDC at the variable rate against it, reads the Pot's health factor, and sends the USDC to `recipient`. If the health factor after the borrow is below `minHealthFactor`, the borrow delivers a different amount, or Aave refuses the supply or the borrow, the cook reverts and nothing moves.

**Target chains:** Base. The example uses `WETH`, `USDC` and `AaveV3.Pool`; the recorded simulation is on a Base fork.

## Prerequisites

Install the [Sauce CLI](https://docs.eco.com/sauce-sdk/installation.md) to compile and simulate. To send the transaction, configure a wallet with WETH for the program and native coin for gas and the Kitchen fee.

## Program

`pot` is the Pot the program runs on, available without declaring it ([Names](https://docs.eco.com/sauce/names.md#balances)).

```ts aave-borrow-guard.sauce.ts theme={null}
// Supplies `collateral` WETH from the Pot to Aave V3 for the Pot, borrows `borrowUsdc` USDC at the
// variable rate against it, also for the Pot, and sends the USDC to `recipient`. After the borrow
// it reads the Pot's health factor from AaveV3.Pool.getUserAccountData. The cook reverts, and
// nothing moves, when the health factor is below `minHealthFactor` or Aave refuses the borrow.
//
//   sauce simulate aave-borrow-guard.sauce.ts --chain base --owner <address> \
//     --assume-balance WETH:<collateral>n \
//     --args <collateral> <borrowUsdc> <minHealthFactor> <recipient>
//   sauce run aave-borrow-guard.sauce.ts --chain base --wallet <name> \
//     --fund WETH:<collateral>n --args <collateral> <borrowUsdc> <minHealthFactor> <recipient>
//
//   collateral: Uint256       the WETH to supply, in wei (18 decimals):
//                             1000000000000000000 is 1 WETH
//   borrowUsdc: Uint256       the USDC to borrow, in USDC's base units (6 decimals):
//                             500000000 is 500 USDC
//   minHealthFactor: Uint256  the lowest health factor to accept after the borrow, as Aave states
//                             it (times 1e18): 2000000000000000000 is 2.0
//   recipient: Address        the account that receives the borrowed USDC
//
// On Base, supply 1 WETH, borrow 500 USDC, keep the health factor at 2.0 or more:
//
//   sauce run aave-borrow-guard.sauce.ts --chain base --wallet me --fund WETH:1 \
//     --args 1000000000000000000 500000000 2000000000000000000 \
//     <recipient>

function main(
  collateral: Uint256,
  borrowUsdc: Uint256,
  minHealthFactor: Uint256,
  recipient: Address,
): { healthFactor: Uint256; borrowed: Uint256 } {
  require(collateral > 0, "collateral is zero");
  require(borrowUsdc > 0, "borrowUsdc is zero");
  require(recipient != 0, "no recipient");
  require(pot.WETH >= collateral, "not enough WETH in the Pot");

  // The position is the Pot's: supplied for it and borrowed against its own collateral.
  WETH.approve(AaveV3.Pool, collateral);
  AaveV3.Pool.supply(WETH, collateral, pot, 0);

  const usdcBefore = pot.USDC;
  AaveV3.Pool.borrow(USDC, borrowUsdc, 2, 0, pot);
  const borrowed = pot.USDC - usdcBefore;
  require(borrowed == borrowUsdc, "borrow delivered a different amount");

  const healthFactor = AaveV3.Pool.getUserAccountData(pot).healthFactor;
  require(healthFactor >= minHealthFactor, "health factor below minHealthFactor");

  USDC.transfer(recipient, borrowed);
  return { healthFactor, borrowed };
}
```

## How it works

* `supply` and `borrow` both name `pot` as `onBehalfOf`: the aWETH collateral and the USDC debt are the Pot's, and Aave checks the borrow against the Pot's own collateral.
* The health factor is read with `AaveV3.Pool.getUserAccountData(pot)` after the borrow, in the same transaction, so the `require` sees the position the borrow left. Aave treats a health factor below 1.0 (`1000000000000000000`) as liquidatable; `minHealthFactor` is the higher floor this cook enforces.
* `borrowed` is the change in the Pot's USDC, required to equal `borrowUsdc` before any USDC leaves the Pot.

> [!WARNING]
>
> The program checks the health factor once, inside this cook. After it, the position stays in the Pot and its health factor moves with the prices Aave reads and with the interest the debt accrues. Repaying or withdrawing takes another cook.

## Run the example

**1. Compile**

```bash theme={null}
sauce compile aave-borrow-guard.sauce.ts --chain base
```

**2. Simulate**

```bash theme={null}
sauce simulate aave-borrow-guard.sauce.ts --chain base --owner <your-address> \
  --assume-balance WETH:1 \
  --args 1000000000000000000 500000000 2000000000000000000 <recipient>
```

`--assume-balance WETH:1` gives the Pot 1 WETH for this simulation only. The result lists the health factor and what the cook left in the Pot.

**3. Send**

```bash theme={null}
sauce run aave-borrow-guard.sauce.ts --chain base --wallet <name> \
  --fund WETH:1 --args 1000000000000000000 500000000 2000000000000000000 <recipient>
```

`--fund WETH:1` pulls 1 WETH from your wallet into the Pot in the same cook. `sauce tx` prints the unsigned transactions instead, for your own signer: the Pot's deployment if it has no code yet, the transfer of the WETH into the Pot, then the cook.

```bash theme={null}
sauce tx aave-borrow-guard.sauce.ts --chain base --owner <your-address> \
  --fund WETH:1 --args 1000000000000000000 500000000 2000000000000000000 <recipient>
```

## Simulation result

Simulated on a local fork of Base at block 52965104 with the current contracts, with the command above. Nothing was signed or sent.

```text theme={null}
main returns { healthFactor: Uint256, borrowed: Uint256 }: { healthFactor: 3955762009927256756, borrowed: 500000000 }
Left in the Pot, not in the owner's wallet:
  0.999999999999999999 aBasWETH
  500.000002 variableDebtBasUSDC
...
What moved, in order:
...
  [3] Pot                -> aBasWETH 0xD4a0…8bb7  1 WETH
  [4] mint               -> Pot                   0.999999999999999999 aBasWETH
  [5] mint               -> Pot                   500.000002 variableDebtBasUSDC
  [6] 0x4e65…c0AB        -> Pot                   500 USDC
  [7] Pot                -> 0x7099…79C8           500 USDC
```

With 1 WETH supplied and 500 USDC borrowed, the health factor was 3.96, above the 2.0 floor, so the program sent the 500 USDC to the recipient. The Pot keeps the aBasWETH collateral and 500.000002 variableDebtBasUSDC of debt. The cook used 533,175 gas.

On the same fork, a borrow of 1,500 USDC passes Aave's checks but leaves the health factor below 2.0, and the cook reverts:

```bash theme={null}
sauce simulate aave-borrow-guard.sauce.ts --chain base --owner <your-address> \
  --assume-balance WETH:1 \
  --args 1000000000000000000 1500000000 2000000000000000000 <recipient> \
  --expect-revert "health factor below minHealthFactor"
```

```text theme={null}
As expected, the cook reverts: the program threw "health factor below minHealthFactor"
```

## Next steps

* [Repay by health factor](https://docs.eco.com/quickstarts/sauce/aave-repay-by-health.md): repays the Pot's USDC debt when its health factor is below a target.
* [Supply idle USDC](https://docs.eco.com/quickstarts/sauce/supply-idle.md): keeps a USDC reserve in the Pot and supplies the rest to Aave V3.
* [`sauce simulate`](https://docs.eco.com/sauce-sdk/cli/simulate), [Pot](https://docs.eco.com/sauce/pot.md), [Protocols reference](https://docs.eco.com/sauce-sdk/reference/protocols.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.