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

# Integration Guide

> How to integrate with Monolith contracts from Solidity and JavaScript

## Overview

Monolith is a permissionless stablecoin factory. There is no off-chain API, SDK, or indexer — all interactions go through on-chain contracts. This guide shows the core flows.

Before reading, make sure you have the [contract addresses](/developers/contract-addresses) for your chain.

## Core contracts

| Contract   | Role                                                     |
| ---------- | -------------------------------------------------------- |
| `Factory`  | Deploys new instances; manages protocol fees             |
| `Lender`   | Per-instance core: borrow, repay, liquidate, redeem, PSM |
| `Coin`     | Per-instance ERC‑20 stablecoin                           |
| `Vault`    | Per-instance ERC‑4626 staked vault (yield-bearing)       |
| `Lens`     | Read-only helpers (preview redeem, synced debt)          |
| `Metadata` | Per-Lender branding (URLs, logos, description)           |

## Deploying a new instance

`Factory.deploy(DeployParams)` creates a `Lender`, `Coin`, and `Vault` in a single transaction and returns their addresses.

```solidity theme={null}
interface IFactory {
    struct DeployParams {
        string  name;
        string  symbol;
        address collateral;
        address psmAsset;                   // address(0) to disable PSM
        address psmVault;                   // address(0) or ERC4626
        address feed;                       // Chainlink-style
        uint256 collateralFactor;           // max 8500 (85%)
        uint256 minDebt;                    // must be >= factory.minDebtFloor()
        uint256 timeUntilImmutability;      // seconds, max 1460 days (~4 years)
        address operator;
        address manager;
        uint64  halfLife;                   // 12 hours .. 30 days
        uint16  targetFreeDebtRatioStartBps; // >= 500, <= end
        uint16  targetFreeDebtRatioEndBps;   // <= 9500
        uint16  redeemFeeBps;               // <= 500 (5%)
        uint32  stalenessThreshold;         // oracle max staleness (seconds)
        uint16  maxBorrowDeltaBps;          // 50..200
        uint128 psmVaultMinTotalSupply;     // required if psmVault != 0
    }

    function deploy(DeployParams memory params) external returns (address lender, address coin, address vault);
}
```

See [Stablecoin Factory](/protocol/stablecoin-factory) for parameter guidance.

## Borrowing and managing a position

`Lender.adjust` is the single entry point for all position changes: deposit/withdraw collateral, borrow/repay debt, switch between paid and free (redeemable) debt modes.

```solidity theme={null}
interface ILender {
    // collateralDelta and debtDelta are signed: positive = deposit/borrow, negative = withdraw/repay.
    function adjust(
        address account,
        int256  collateralDelta,
        int256  debtDelta,
        bool    chooseRedeemable
    ) external;

    // Overload without the status flag (keeps current setting).
    function adjust(
        address account,
        int256  collateralDelta,
        int256  debtDelta
    ) external;
}
```

Example — deposit 1 WETH and borrow 1,000 Coin in paid-debt mode:

```solidity theme={null}
IERC20(weth).approve(lender, 1 ether);
ILender(lender).adjust(msg.sender, int256(1 ether), int256(1_000e18), false);
```

Example — repay all debt and withdraw all collateral:

```solidity theme={null}
uint256 debt       = ILender(lender).getDebtOf(msg.sender);
uint256 collateral = ILender(lender).collateralBalances(msg.sender);
IERC20(coin).approve(lender, debt);
ILender(lender).adjust(msg.sender, -int256(collateral), -int256(debt), false);
```

Delegation (`lender.delegate(address, bool)`) lets another address manage the position on the owner's behalf.

## Staking the Coin

`Vault` is a standard ERC‑4626. Yield comes from interest paid by borrowers in paid-debt mode.

```solidity theme={null}
// Stake
IERC20(coin).approve(vault, amount);
uint256 shares = IERC4626(vault).deposit(amount, msg.sender);

// Unstake
uint256 assets = IERC4626(vault).redeem(shares, msg.sender, msg.sender);
```

Note: the first depositor burns `1e16` shares (`MIN_SHARES`) to prevent the ERC‑4626 inflation attack.

## Redemption (arbitrage)

Anyone can redeem `Coin` for a redeemable borrower's collateral at oracle price minus `redeemFeeBps`.

```solidity theme={null}
interface ILender {
    function redeem(address borrower, uint amountIn, uint minAmountOut)
        external returns (uint amountOut);
}
```

Preview the outcome off-chain via `Lens` (simulates without mutating state):

```solidity theme={null}
interface ILens {
    function previewRedeem(address lender, address borrower, uint256 amountIn)
        external view returns (uint256 coinIn, uint256 amountOut);
}
```

See [Redemptions](/protocol/redemptions) for the mechanism.

## PSM (if enabled on the instance)

If `psmAsset` was configured at deployment, anyone can convert between `Coin` and the PSM asset at 1:1 (decimals-adjusted).

```solidity theme={null}
interface ILender {
    function sell(uint coinIn, uint minAssetOut) external returns (uint assetOut);         // no fee
    function buy (uint assetIn, uint minCoinOut) external returns (uint coinOut);          // pre-deadline, small ramping fee
}
```

## Querying state

`Lender` exposes direct getters; `Lens` provides a version that simulates accrual before reading.

```solidity theme={null}
// Already-accrued debt (from Lender)
uint256 debt = ILender(lender).getDebtOf(account);

// Debt including pending interest (from Lens)
uint256 syncedDebt = ILens(lens).getDebtOf(lender, account);

// Oracle state
(uint price, bool reduceOnly, bool allowLiquidations) = ILender(lender).getCollateralPrice();
```

## Liquidating a position

```solidity theme={null}
interface ILender {
    function liquidate(address borrower, uint repayAmount, uint minCollateralOut)
        external returns (uint collateralOut);
}
```

Up to 25% of a position's debt (or the full position if smaller) can be liquidated per call, with a minimum chunk of `10_000e18`. Incentive scales from 0% at the collateral factor up to 10% at `collateralFactor + 500 bps`. See [Liquidations](/protocol/liquidations).

## Events to index

Factory:

* `Deployed(address indexed lender, address indexed coin, address indexed vault)`

Per Lender (subset most integrators care about):

* `PositionAdjusted(address indexed account, int collateralDelta, int debtDelta)`
* `RedemptionStatusUpdated(address indexed account, bool isRedeemable)`
* `Liquidated(address indexed borrower, address indexed liquidator, uint repayAmount, uint collateralOut)`
* `Redeemed(address indexed account, address indexed borrower, uint amountIn, uint amountOut)`
* `Sold(address indexed account, uint coinIn, uint assetOut)`
* `Bought(address indexed account, uint assetIn, uint coinOut)`
* `WrittenOff(address indexed borrower, address indexed to, uint debt, uint collateral)`

See the [Lender reference](/reference/Lender) for the full list.

## JavaScript example (ethers v6)

```javascript theme={null}
import { ethers } from "ethers";

const provider = new ethers.BrowserProvider(window.ethereum);
const signer   = await provider.getSigner();

const lender = new ethers.Contract(lenderAddress, lenderAbi, signer);
const coin   = new ethers.Contract(coinAddress,   erc20Abi,  signer);

// Deposit 1 WETH, borrow 1000 Coin, paid-debt mode
await (await weth.approve(lenderAddress, ethers.parseEther("1"))).wait();
await (await lender.adjust(
  await signer.getAddress(),
  ethers.parseEther("1"),          // +1 WETH
  ethers.parseUnits("1000", 18),   // +1000 Coin debt
  false,                           // chooseRedeemable = false (paid debt)
)).wait();
```

## Source

ABIs and Solidity sources: [github.com/MonolithMarket/Monolith](https://github.com/MonolithMarket/Monolith).
