# Introduction

Introduction to the Fathom Protocol

**What is the Fathom Protocol?**

The Fathom Protocol is a pioneering decentralized finance platform. Its primary aim is to bolster the liquidity by positioning FXD, an over-collateralized and soft-pegged stablecoin. The other parts of the Fathom ecosystem are built around FXD: Vaults, Lending, DEX and Oracles. Fathom is operated in the DAO framework..

**Key Highlights of the Fathom Protocol**

1. **Fathom's FXD: The Over-Collateralized, Soft-Pegged Stablecoin**: FXD stands as a cornerstone of the Fathom Protocol, being soft-pegged to the US dollar. This approach provides a stable and reliable digital currency, aiming to minimize cryptocurrency's inherent volatility.
2. **Fathom's Vaults:** Platform designed for astute investors seeking to enhance their digital asset portfolio. Vaults offer a secure and dynamic way to grow cryptocurrency investments through robust yield strategies.
3. **Fathom's Lending**: Decentralized non-custodial liquidity market where users can participate as suppliers or borrowers. Suppliers provide liquidity to the market to earn a passive income, while borrowers can borrow in an over-collateralized (perpetually) or under-collateralized (one-block liquidity) fashion.
4. **Fathom's Decentralized Exchange (DEX)**: As the central trading hub within the Fathom ecosystem, the DEX enhances the liquidity of both XDC and FXD. It's a key platform for facilitating secure and efficient trading activities.
5. **Fathom's Oracles**: Decentralized oracle network powered by Fathom's FXD with high availability, reliability, and data accuracy.
6. **Governance through Fathom DAO**: The Fathom protocol is driven by the Decentralized Autonomous Organization (DAO), which integrates the FTHM token, governance, and staking. This framework empowers FTHM token holders with voting rights and a say in the protocol's governance and future direction.

**Vision for DeFi Evolution**: The Fathom Protocol is uniquely positioned to contribute significantly to the evolution of DeFi. Its focus on providing a stable digital currency and a fluid trading environment underscores its commitment to advancing decentralized finance.


# FXD Stablecoin

Introduction to Fathom's FXD Stablecoin

**Overview of Fathom's FXD Stablecoin Smart Contracts**

The Fathom stablecoin smart contracts form the technical backbone of the Fathom stablecoin (FXD), a crucial component of the Fathom Protocol. These contracts are engineered to provide a secure, efficient, and transparent mechanism for stablecoin operations, aligning with the broader goals of the Fathom Protocol to enhance liquidity and stability within the DeFi ecosystem.

**Key Technical Aspects**

1. **Smart Contract Architecture**: The Fathom stablecoin smart contracts are built on a modular architecture, ensuring scalability, upgradability, and maintainability. This architecture comprises several interlinked contracts, each handling specific aspects of the stablecoin's lifecycle, including minting, burning, and transaction processing.
2. **Minting and Burning Mechanisms with LTV Ratio**: At the heart of the smart contracts are the mechanisms for minting and burning FXD. Minting occurs when users collateralize their position, with the amount of FXD minted governed by the Loan-to-Value (LTV) ratio. This ensures a balanced issuance of FXD, aligning with the value of the collateral. Conversely, burning happens when FXD is returned to the protocol, particularly during position closures or liquidation events, to maintain the supply in line with market dynamics and collateral value.
3. **Soft-Pegging to the US Dollar**: The smart contracts implement a soft-pegging mechanism that ties the value of FXD to the US dollar. This is achieved through the StableSwapModule, which creates arbitrage opportunities that incentivize price pegging towards $1. As a result, the stablecoin’s value remains consistently close to the pegged asset.
4. **Advanced Fixed-Spread Liquidation (AFSL):** A liquidator can repay a fraction of the borrower's debt and acquire its collateral at a discount. Additionally, to the basic model of AFSL, FXD implements batch liquidation processing as part of the migration to [Dynamic Spread Tiered Liquidation (DSTL)](https://medium.com/@anton.grigorev.dev/advancing-liquidation-mechanisms-the-journey-to-dynamic-spread-tiered-liquidation-dstl-in-fathom-d35f14074ef3).


# FXD Smart Contract Architecture

<figure><img src="/files/3NY0FJtQYqEDorM1vxGO" alt=""><figcaption><p>FXD Stablecoin Smart Contract System Design</p></figcaption></figure>

<figure><img src="/files/uVrfgVdipZER3UMCSljH" alt=""><figcaption><p>FXD Stablecoin Smart Contract Architecture</p></figcaption></figure>

#### Fathom Protocol Smart Contract Architecture

The structure comprises distinct modules, each responsible for a set of defined operations.

**Core Components**

1. **Proxy Module**: Interfaces for the core contracts of the protocol.
   * **ProxyWallet**: Calls functions within the FathomProxyActions contract for user interactions.
   * **ProxyActionsStorage**: Stores the address of the FathomProxyActions contract.
   * **ProxyWalletRegistry**: Oversees the creation of proxy wallets owned by users.
2. **Position Module**: Handles the creation and tracking of user positions.
   * **PositionManager**: Initiates user positions and maintains a record of them.
3. **Stablecoin Core Module**: Central to the management of the FXD stablecoin's lifecycle.
   * **BookKeeper**: Monitors and manages each position's locked collateral and debt share.
   * **CollateralPoolConfig**: Manages configurations for collateral pools.
   * **StablecoinAdapter**: Oversees the minting and burning functions of the FathomStablecoin contract.
4. **StableSwapModule**: Supports the provision of liquidity and the execution of FXD<->xUSDT 1:1 swaps.
   * **StableSwapModuleWrapper**: Integrates and administers the protocol's liquidity pools.
5. **Price Module**: Delivers accurate price information for assets.
   * **PriceFeed**: Gathers price data from price source and feeds it into the protocol.
   * **PriceOracle**: Transforms raw price from PriceFeed to include a safety margin, using the LTV ratio.
6. **Liquidation Module**: Maintains the protocol's financial health by managing under-collateralized positions.
   * **LiquidationEngine**: Carries out the liquidation process according to predefined rules.
   * **FixedSpreadLiquidationStrategy**: Directs liquidation activities, ensuring consistency through a fixed spread.
7. **Emergency Module**: Pause or Terminate the protocol.
   * **ShowStopper**: Stops and terminates the whole protocol and executes the emergency shutdown process to return collateral
   * **AdminControls**: Pauses the protocol at once.


# Minting and Burning Mechanisms with LTV Ratio

**Minting Mechanism with LTV Ratio Consideration**

1. **Collateralization and LTV Ratio**: In the Fathom Protocol, users provide collateral to borrow FXD. The Loan-to-Value (LTV) ratio determines the maximum loan amount. This ratio specifies the maximum proportion of the borrowed value relative to the collateral's value.
2. **Example of LTV-Based Minting**: For instance, if a user collateralizes $100 worth of collateral asset and the LTV ratio is 65%, the user can borrow up to $65 worth of FXD. This system ensures that the minting of FXD is always in alignment with the value of the collateral based on the predetermined LTV ratio.
3. **Ensuring Balanced Issuance**: The LTV ratio is a crucial parameter in smart contracts, ensuring that the issuance of FXD is balanced and proportionate to the underlying collateral. This prevents over-minting and maintains the protocol’s financial stability.

**Burning Mechanism and Liquidation Process**

1. **Position Closure and FXD Return**: When users close their positions, they return the borrowed FXD to the protocol. The smart contracts immediately burn this returned FXD, removing it from circulation.
2. **Liquidation Trigger and Process**: If the market value of the collateralized asset falls such that the LTV ratio is breached (i.e., the value of the borrowed FXD exceeds the adjusted permissible limit), a liquidation process may be initiated. This process involves the sale of the collateralized asset to liquidators in exchange for FXD.
3. **FXD Burning Post-Liquidation**: The FXD acquired by the liquidator in exchange for the asset is then burned. This step is crucial for offsetting the outstanding debt and maintaining the financial equilibrium of the Fathom Protocol.


# Soft-Pegging to the US Dollar

Soft-Pegging of FXD's market price to $1 is done by arbitrageurs. This section explains FXD pegging mechanism.

**How pegging works**

When the price of FXD on some market (DEX or CEX) is less than $1, the arbitrageurs are looking for an incentive to arbitrage it with the market, which has a price closer to or more than $1. The below images show how the FXD price is pegged from time 0 to time 2.

<div><figure><img src="/files/a1ADjA5SQhDf44gD1Kn0" alt=""><figcaption></figcaption></figure> <figure><img src="/files/TFthge5edtYHU82GYwZ0" alt=""><figcaption><p>Pegging when FXD &#x3C; $1</p></figcaption></figure> <figure><img src="/files/2l3OVDwWEEQki72j1EH8" alt=""><figcaption></figcaption></figure></div>

When the market price of FXD is greater than $1, it provides an incentive to sell FXD in the market. The below images show how the FXD price is pegged from time 0 to time 2.

<div><figure><img src="/files/UWfWWOpbC9O9ruwNuAhW" alt=""><figcaption></figcaption></figure> <figure><img src="/files/a2hNaRkKN5Ef7igVC2Wm" alt=""><figcaption><p>Pegging when FXD > $1</p></figcaption></figure> <figure><img src="/files/QF4FPPUzxHKlgF6ka3SC" alt=""><figcaption></figcaption></figure></div>

StableSwapModule (SSM) is the special mechanism developed by the Fathom team to provide an additional incentive for arbitrageurs.

<figure><img src="/files/A5BbywhW0I34Cgjg6KcD" alt=""><figcaption><p>Stable Swap Module (SSM</p></figcaption></figure>


# Opening and closing position flows

The images below depict the functional flows for opening and closing positions.

<figure><img src="/files/dHXbVlpzAP23D61y1orj" alt=""><figcaption><p>Position opening flow</p></figcaption></figure>

<figure><img src="/files/PDmEn4142mZWGCC9nDEC" alt=""><figcaption><p>Position closure flow</p></figcaption></figure>


# BookKeeping mechanism

In Fathom's FXD stablecoin system, two important accounting mechanisms are central: stablecoin accounting and collateral accounting.


# Stablecoin Accounting

This section provides a deep understanding of how the accounting of issued stablecoin is done in the BookKeeper contract.

[totalStablecoinIssued](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol#L38)

***

$$
totalStablecoinIssued = poolStablecoinIssued + totalUnbackedStablecoin
$$

***

The formula mentioned above is used in all the functions that manipulate the `totalStablecoinIssued` and *`poolStablecoinIssued`* variables. If the value on the right-hand side of the equation changes, the value on the left side must be changed exactly the same way.

Now, let's delve deeper into the functions that manipulate the `poolStablecoinIssued` and `totalStablecoinIssued` variables. We will see how the above mentioned equation affects each function, starting with `poolStablecoinIssued`.

### [poolStablecoinIssued](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol#L32C61-L32C61)

The variable `poolStablecoinIssued` is stored in the **`BookKeeper`** contract. Three functions manipulate `poolStablecoinIssued`.

#### [fn adjustPosition](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol#L291)

This function manipulates both `poolStablecoinIssued` and `totalStablecoinIssued`.

The `adjustPosition` function changes the `lockedCollateral` and `debtShare` values mapped to each position. When the `debtShare` in a position decreases, `poolStablecoinIssued` also decreases. Conversely, when the `debtShare` in a position increases, the value of `poolStablecoinIssued` increases. It calculates the amount by which the debt value in a position has increased or decreased and adjusts the `poolStablecoinIssued` value accordingly. The `adjustPosition` function also manipulates the `totalStablecoinIssued` variable.

For example:

If debtShare in position, which is of collateral XYZ, decreases by 10, then

* `poolStablecoinissued`\[XYZ] decreases by 10\*`debtAccumulatedRate`
* `totalStablecoinIssued` decreases by 10\*`debtAccumulatedRate`

$$
totalStablecoinIssued ↓ = poolStablecoinIssued↓ + totalUnbackedStablecoin
$$

#### [fn confiscatePosition](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol#L412)

This function manipulates both `poolStablecoinIssued` and `totalUnbackedStablecoin` but not `totalStablecoinIssued`.

The `confiscatePosition` function removes collateral and debt from a position and transfers them to addresses specified in the function arguments. During this process, the pool-specific balance is deducted. The amount of debt deducted from `poolStablecoinIssued` results in an increase in both the `systemBadDebt[_stablecoinDebtor]` and `totalUnbackedStablecoin`.

However, the `totalStablecoinIssued` is unaffected because it is the sum of all `poolStablecoinIssued` values and `totalUnbackedStablecoin`. The `confiscatePosition` function essentially transfers values from `poolStablecoinIssued` to `totalUnbackedStablecoin`, ensuring that the `totalStablecoinIssued` remains unchanged.

What the `confiscatePosition` function does is transition from equation A to equation B.

**Equation A**

$$
totalStablecoinIssued = ΣpoolStablecoinIssued + totalUnbackedStablecoin
$$

**Equation B**

$$
totalStablecoinIssued = \[ΣpoolStablecoinIssued - α] + \[totalUnbackedStablecoin + α]
$$

When *α* represents the amount of debt transferred from `poolStablecoinIssued` tot `unbackedStablecoin` by `confiscatePosition` function.

#### [fn accrueStabilityFee](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol#L482)

This function manipulates both `poolStablecoinIssued` and `totalStablecoinIssued` variables.

The `accrueStabilityFee` function increases the value of `poolStablecoinIssued[_collateralPoolId]`. This action of accruing stability fees involves recalculating the total amount of debt issued from a specific collateral type. Due to the increase in `poolStablecoinIssued[_collateralPoolId]`, the `totalStablecoinIssued` value also increases.

$$
totalStablecoinIssued + β = \[ΣpoolStablecoinIssued + β] + totalUnbackedStablecoin
$$

Where *β* represents the amount by which the `debtValue` increases as the inflated value of `_debtAccumulatedRate` is reflected in the `debtVault` when the `accrueStabilityFee` function is called.

### [totalStablecoinIssued](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol#L38)

`totalStablecoinIssued` is the variable stored in the ***`BookKeeper`*** contract. Four functions manipulate `totalStablecoinIssued`.

#### [fn adjustPosition](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol#L291)

The `adjustPosition` function adjusts the values of `totalStablecoinIssued` and `poolStablecoinIssued` based on the changes made to a position. For more details, please refer to the fn `adjustPosition` section under `poolStablecoinIssued`.

If a position's debt increases because a user borrows (more) FXD,

$$
totalStablecoinIssued ↑ = poolStablecoinIssued↑ + totalUnbackedStablecoin
$$

If a position's debt decreases as a user pays back FXD,

$$
totalStablecoinIssued ↓ = poolStablecoinIssued↓ + totalUnbackedStablecoin
$$

#### [fn settleSystemBadDebt](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol#L449)

The `settleSystemBadDebt` function utilizes the internal balance of stablecoin in the **`SystemDebtEngine`** within the `bookKeeper` to settle the bad debt. When the bad debt is settled, the value of `totalUnbackedStablecoin` decreases, and so does the value of `totalStablecoinIssued`.

$$
totalStablecoinIssued ↓ = ΣpoolStablecoinIssued↓ + totalUnbackedStablecoin
$$

#### [fn mintUnbackedStablecoin](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol#L464C22-L464C22)

The `mintUnbackedStablecoin` function increases the amount of `totalUnbackedStablecoin` and `totalStablecoinIssued`.

$$
totalStablecoinIssued ↑ = ΣpoolStablecoinIssued↑ + totalUnbackedStablecoin
$$

#### [fn accrueStabilityFee](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol#L482)

$$
totalStablecoinIssued + β = \[ΣpoolStablecoinIssued + β] + totalUnbackedStablecoin
$$

Where *β* represents the amount by which the `debtValue` increases as the inflated value of `_debtAccummulatedRate` is reflected in the `debtValue` when the *accrueStabilityFee* function is called.

For a more detailed explanation, please refer to the previous section on [accrueStabilityFee](#fn-accruestabilityfee).


# Collateral Accounting

This section provides a deep understanding of how the accounting of collateral is done in the BookKeeper contract.

### Where is a position's collateral recorded?

Each position's collateral amount and debt are recorded in the `BookKeeper` contract. In the `BookKeeper` contract, [positions](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol#L28) are the double mapping that keeps track of each position's `lockedCollateral` and `debtShare`.&#x20;

<pre class="language-solidity" data-overflow="wrap" data-full-width="false"><code class="lang-solidity"><strong>mapping(bytes32 => mapping(address => Position)) public positions;
</strong></code></pre>

[positions](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol#L28) mapping has the value as `Position` struct, and the struct's first member, `lockedCollateral` keeps track of the collateral.

{% code overflow="wrap" fullWidth="false" %}

```solidity
struct Position {
    uint256 lockedCollateral; // Locked collateral inside this position
    uint256 debtShare;
}
```

{% endcode %}

### How is a position's collateral recorded?

#### [position.lockedCollateral](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol#L24)

`position.lockedCollateral` represents the amount of collateral locked in a specific position. It serves as the primary reference to determine the amount of collateral a particular position holds. The value of `position.lockedCollateral` increases when a position is opened and decreases when it is closed. During the position opening flow, the value of [CollateralToken](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol#L29) variable [increase temporarily](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/adapters/CollateralTokenAdapter/CollateralTokenAdapter.sol#L196C9-L196C9), and later gets transferred to `position.lockedCollateral`*.*

{% code overflow="wrap" %}

```solidity
mapping(bytes32 => mapping(address => uint256)) public collateralToken;
```

{% endcode %}

Similarly, the position `value.lockedCollateral` is temporarily transferred to the `CollateralToken` variable during the position closing flow. Then, when the collateral gets withdrawn from `CollateralTokenAdapter`, the temporarily increased number on [CollateralToken](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol#L29) decreases as much as [withdrawn](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/adapters/CollateralTokenAdapter/CollateralTokenAdapter.sol#L214).

Three functions are directly involved in `lockedCollateral` accounting.

[fn adjustPosition](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol#L291) in `BookKeeper`.

[fn moveCollateral](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol#L246) in `BookKeeper`.

[fn withdraw](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/adapters/CollateralTokenAdapter/CollateralTokenAdapter.sol#L210) in `CollateralTokenAdapter`.

[fn deposit](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/adapters/CollateralTokenAdapter/CollateralTokenAdapter.sol#L187) in `CollateralTokenAdapter`.


# Liquidation

High level explanation of liquidation process

The liquidation process in the Fathom protocol involves several key components and steps outlined in detail in the `LiquidationEngine` and `FixedSpreadLiquidationStrategy` contracts. The liquidation mechanism maintains the system's stability by handling under-collateralized positions. Here is an overview of the process:

**Components Involved:**

1. **Liquidation Engine (`LiquidationEngine`):** Manages the overall liquidation process.
2. **Fixed Spread Liquidation Strategy (`FixedSpreadLiquidationStrategy`):** Implements a specific strategy for liquidation.
3. **Collateral Pool Config (`CollateralPoolConfig`):** Provides configuration for collateral pools, including parameters like liquidation ratio, close factor, and liquidator incentives.
4. **BookKeeper (`BookKeeper`):** Records positions, stablecoin balances and collateral.
5. **System Debt Engine (`SystemDebtEngine`):** Manages the system's overall debt and surpluses, including systemBadDebt and systemSurpluses.
6. **Price Oracle (`PriceOracle`):** Provides price feeds for collateral assets.

**Liquidation Process:**

1. **Triggering Liquidation:**

* A position becomes eligible for liquidation when its collateral value falls below a predefined threshold (defined by the liquidation ratio in `CollateralPoolConfig`). The liquidation Ratio is the same as ( *1 / Loan to Value Ratio*).&#x20;
* The `PriceOracle` plays a crucial role in determining the health of positions by providing the latest available prices for collateral assets.

2. **Liquidation Execution:**

* The liquidation process is initiated by a liquidator (which, at the moment, is a role only available to whitelisted addresses) who identifies an under-collateralized position and calls the liquidate function in `LiquidationEngine`.
* The liquidate function checks various conditions, such as the liquidator's whitelist status, the system's operational status (live), and the health of the price feed.
* If the conditions are met, `LiquidationEngine` interacts with the `FixedSpreadLiquidationStrategy` to execute the liquidation.

3. **Fixed Spread Liquidation Strategy:**

* This strategy determines the specifics of the liquidation, such as the amount of debt to be repaid and the amount of collateral to be seized.
* It calculates the required parameters based on current prices, debt accumulated rates, and other factors defined in `CollateralPoolConfig`.

4. **Financial Adjustments:**

* Upon successful liquidation, the `BookKeeper` updates the financial state of the system, including adjusting the debt and collateral amounts for the liquidated position.
* The `SystemDebtEngine` may also handle any resultant bad debt from the liquidation process.

5. **Distribution of Assets:**

* The liquidator typically receives a portion of the seized collateral as an incentive, with the rest used to repay the debt.
* Parameters like liquidator incentives and treasury fees govern the distribution of assets.

6. **Edge Cases and Safeguards:**

* The system includes various safeguards and checks to prevent unauthorized access and ensure the integrity of the liquidation process.
* For instance, roles and permissions are enforced using access control mechanisms.

The following subsection guides you through the liquidation process in detail.


# Fixed Spread Liquidation Strategy

The complete explanation of the Fixed Spread Liquidation Strategy can be found in <https://docs.fathom.fi/whitepaper/version-1.0#id-3.1.3-fxd-fixed-spread-liquidation-strategy>.


# Liquidation process walk through

This page provides a more detailed explanation of Fathom's FXD liquidation process

For a position to be considered safe, the below should hold true.

$$
lockedCollateralAmount \* PriceWithSafetyMargin > DebtShare \* debtAccumulateRate,
$$

where

$$
PriceWithSafetyMargin = RawPrice \* LTV.
$$

*RawPrice* is the price of collateral from `PriceFeed` and *LTV* is Loan to Ratio.

If a position's value of `lockedCollateral(lockedCollateralAmount * PriceWithSafetyMargin)` goes below the `debtValue(DebtShare * debtAccumulatedRate)`, the position is considered unsafe/underwater and will be subject to liquidation process. The liquidator bot monitors the health of each position in the Fathom protocol.

Once a position is underwater and spotted by the liquidator bot, the bot can call the `liquidate` function in the `LiquidationEngine` contract.

<pre class="language-solidity" data-overflow="wrap"><code class="lang-solidity">function liquidate(
    bytes32 _collateralPoolId, // the collateralPoolId of the position that is to be liquidated
    address _positionAddress, // the positionHandler's address of a position that is to be liquidated
    uint256 _debtShareToBeLiquidated, // a param to set how much of debtShare will be liquidated from a position
    uint256 _maxDebtShareToBeLiquidated, // the ceiling for the debtShare that can be liquidated
    address _collateralRecipient, // the recipient of the collateral once the liquidation process ends
<strong>    bytes calldata _data // is used when the liquidation process includes FlashLendingCallee
</strong>) external;
</code></pre>

Or the bot can call the `batchLiquidate` function if it spots multiple underwater positions.

{% code overflow="wrap" %}

```solidity
function batchLiquidate(
    bytes32[] calldata _collateralPoolIds,
    address[] calldata _positionAddresses,
    uint256[] calldata _debtShareToBeLiquidateds,
    uint256[] calldata _maxDebtShareToBeLiquidateds,
    address[] calldata _collateralRecipients,
    bytes[] calldata _datas
) external;
```

{% endcode %}

If a bot calls `liquidate` or `batchLiquidate` functions to `LiquidationEngine` without using the `_data` param, the liquidator bot needs to have enough balance of FXD token available and should have approved `FixedSpreadLiquidationStrategy` as a spender. This is because the process of depositing FXD to liquidate and receive collateral is done in the execute function in `FixedSpreadLiquidationStrategy`.

If a bot calls `liquidate` or `batchLiquidate` functions and has the `_data` param filled with encoded data that can be used for [flashLendingCalle's](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/liquidation-strategies/FixedSpreadLiquidationStrategy.sol#L214) address, the liquidator bot doesn't necessarily need to have an FXD token available.

Once liquidation functions are called, the liquidation process starts from the internal function [\_liquidate](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/LiquidationEngine.sol#L239).

{% code overflow="wrap" %}

```solidity
function _liquidate(
    bytes32 _collateralPoolId,
    address _positionAddress,
    uint256 _debtShareToBeLiquidated,
    uint256 _maxDebtShareToBeLiquidated,
    address _collateralRecipient,
    bytes calldata _data,
    address sender
) internal; 
```

{% endcode %}

`_liquidate` function first goes through some checks in the function args and checks whether the position targeted for liquidation is safe.

{% code overflow="wrap" %}

```solidity
require(
    _collateralPoolLocalVars.priceWithSafetyMargin > 0 &&
    _vars.positionLockedCollateral * _collateralPoolLocalVars.priceWithSafetyMargin <
    _vars.positionDebtShare * _collateralPoolLocalVars.debtAccumulatedRate,
    "LiquidationEngine/position-is-safe"
);
```

{% endcode %}

Once the position is underwater, the liquidation task is tossed to `FixedSpeadLiquidationStrategy` execute function.

<pre class="language-solidity" data-overflow="wrap"><code class="lang-solidity">_strategy.execute(
    _collateralPoolId,
    _vars.positionDebtShare,
<strong>    _vars.positionLockedCollateral,
</strong>    _positionAddress,
<strong>    _debtShareToBeLiquidated,
</strong>    _maxDebtShareToBeLiquidated,
    sender,
    _collateralRecipient,
    _data
);
</code></pre>

The [`execute`](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/liquidation-strategies/FixedSpreadLiquidationStrategy.sol#L148) function in  `FixedSpeadLiquidationStrategy` starts by verifying if the caller has the `LIQUIDATION_ENGINE_ROLE` from the `AccessControlConfig` associated with the `BookKeeper`. This ensures that only authorized entities can initiate the liquidation process.

{% code overflow="wrap" %}

```solidity
require(
    IAccessControlConfig(bookKeeper.accessControlConfig()).hasRole(
        IAccessControlConfig(bookKeeper.accessControlConfig()).LIQUIDATION_ENGINE_ROLE(),
        msg.sender
    ),
    "!liquidationEngingRole"
);
```

{% endcode %}

The function then validates the input parameters, such as the debt share, collateral amount, and position address. It checks for zero values and valid price feeds to ensure the integrity of the liquidation data.

{% code overflow="wrap" %}

```solidity
_validateValues(_collateralPoolId, _positionDebtShare, _positionCollateralAmount, _positionAddress);
```

{% endcode %}

Then, it calculates the liquidation information based on the current market price, debt share, and collateral amount. This step involves determining the actual debt value to be liquidated, the collateral amount that will be seized, and any applicable treasury fees.

<pre class="language-solidity" data-overflow="wrap"><code class="lang-solidity">LiquidationInfo memory info = _calculateLiquidationInfo(
<strong>    _collateralPoolId,
</strong>    _debtShareToBeLiquidated,
    getFeedPrice(_collateralPoolId),
    _positionCollateralAmount,
    _positionDebtShare
);
</code></pre>

The function then calls `confiscatePosition` on the `BookKeeper`, adjusting the collateral and debt share of the position in question.

```solidity
bookKeeper.confiscatePosition(
    _collateralPoolId,
    _positionAddress,
    address(this),
    address(systemDebtEngine),
    -int256(info.collateralAmountToBeLiquidated),
    -int256(info.actualDebtShareToBeLiquidated)
);
```

Treasury fees are moved from the liquidation contract to the `SystemDebtEngine` if any treasury fees are due.

{% code overflow="wrap" %}

```solidity
if (info.treasuryFees > 0) {
    bookKeeper.moveCollateral(_collateralPoolId, address(this), address(systemDebtEngine), info.treasuryFees);
}
```

{% endcode %}

If flash lending is enabled and valid, the contract facilitates flash lending calls. This step is optional and based on the encoded data provided.

{% code overflow="wrap" %}

```solidity
if (info.treasuryFees > 0) {
    bookKeeper.moveCollateral(_collateralPoolId, address(this), address(systemDebtEngine), info.treasuryFees);
}
```

{% endcode %}

Without flash lending, the contract withdraws the collateral to the liquidator and transfers the required FXD amount to cover the debt. The FXD is then deposited in the `BookKeeper` to clear the debt.

{% code overflow="wrap" %}

```solidity
IGenericTokenAdapter(ICollateralPoolConfig(bookKeeper.collateralPoolConfig()).getAdapter(_collateralPoolId)).withdraw(
    _collateralRecipient,
    info.collateralAmountToBeLiquidated - info.treasuryFees,
    abi.encode(0)
);
address _stablecoin = address(stablecoinAdapter.stablecoin());
_stablecoin.safeTransferFrom(_liquidatorAddress, address(this), ((info.actualDebtValueToBeLiquidated / RAY) + 1));
_stablecoin.safeApprove(address(stablecoinAdapter), ((info.actualDebtValueToBeLiquidated / RAY) + 1));
stablecoinAdapter.depositRAD(_liquidatorAddress, info.actualDebtValueToBeLiquidated, _collateralPoolId, abi.encode(0));
```

{% endcode %}

Finally, an event `LogFixedSpreadLiquidate` is emitted to record the details of the liquidation transaction.

{% code overflow="wrap" %}

```solidity
emit LogFixedSpreadLiquidate(
    _collateralPoolId,
    info.positionDebtShare,
    info.positionCollateralAmount,
    _positionAddress,
    info.debtShareToBeLiquidated,
    info.maxDebtShareToBeLiquidated,
    _liquidatorAddress,
    _collateralRecipient,
    info.actualDebtShareToBeLiquidated,
    info.actualDebtValueToBeLiquidated,
    info.collateralAmountToBeLiquidated,
    info.treasuryFees
);
```

{% endcode %}

\
After the `execute` function of the `FixedSpreadLiquidationStrategy` completes, the remaining liquidation process in the `LiquidationEngine` is verification of successful liquidation and recording of `systemBadDebt` if needed.&#x20;

First, updated position data is retrieved:

{% code overflow="wrap" %}

```solidity
(_vars.newPositionLockedCollateral, _vars.newPositionDebtShare) = bookKeeper.positions(_collateralPoolId, _positionAddress);
```

{% endcode %}

Then, the decrease of position debt Share is validated, ensuring effective liquidation:

{% code overflow="wrap" %}

```solidity
require(_vars.newPositionDebtShare < _vars.positionDebtShare, "LiquidationEngine/debt-not-liquidated");
```

{% endcode %}

Once the liquidation validation is good with `debtShare`, receipt of the expected stablecoin amount by the `SystemDebtEngine` is checked:

{% code overflow="wrap" %}

```solidity
_vars.wantStablecoinValueFromLiquidation = (_vars.positionDebtShare - _vars.newPositionDebtShare) * _collateralPoolLocalVars.debtAccumulatedRate; // [rad]
require(
    bookKeeper.stablecoin(address(systemDebtEngine)) - _vars.systemDebtEngineStablecoinBefore >= _vars.wantStablecoinValueFromLiquidation,
    "LiquidationEngine/payment-not-received"
);
```

{% endcode %}

In case the collateral is fully liquidated with remaining debt, the function records this as `systemBadDebt`:

{% code overflow="wrap" %}

```solidity
if (_vars.newPositionLockedCollateral == 0 && _vars.newPositionDebtShare > 0) {
    require(_vars.newPositionDebtShare < 2 ** 255, "LiquidationEngine/overflow");
    bookKeeper.confiscatePosition(
        _collateralPoolId,
        _positionAddress,
        _positionAddress,
        address(systemDebtEngine),
        0,
        -int256(_vars.newPositionDebtShare)
    );
}

```

{% endcode %}


# Emergency Shutdown

<figure><img src="/files/4qMl89WwoZw86e4xs5xu" alt=""><figcaption><p>Emergency Shutdown</p></figcaption></figure>

The emergency shutdown process for Fathom's FXD is a comprehensive mechanism designed to safeguard both the protocol and its users in a significant crisis. This process is crucial for maintaining stability in decentralized finance (DeFi) systems. The emergency shutdown facilitates the return of excess collateral from safe positions. It allows for the return of collateral to those who give back FXD to the protocol, using a specific FXD to Collateral conversion ratio determined during the emergency shutdown. Here's a detailed explanation of the Fathom protocol's emergency shutdown procedure:

#### 1. **Initiating Emergency Shutdown**

* **Caging the Protocol**: The shutdown process starts with the protocol owner calling the [`cage`](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/ShowStopper.sol#L113) function in the [**ShowStopper**](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/ShowStopper.sol) contract. This action halts most activities within the protocol and is irreversible. The `_cageCooldown` period is the time allotted for calling the accumulateBadDebt function before the `finalizeDebt` function is executed.

{% code overflow="wrap" %}

```solidity
function cage(uint256 _cageCoolDown) external;
```

{% endcode %}

* **Caging Specific Collateral Pools**: The [`cagePool`](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/ShowStopper.sol#L132) function is then called to initiate the shutdown for a particular collateral pool type, marking a point of no return for that pool.

{% code overflow="wrap" %}

```solidity
function cagePool(bytes32 _collateralPoolId) external;
```

{% endcode %}

* **Accumulating Bad Debt**: The [`accumulateBadDebt`](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/ShowStopper.sol#L151) function, is called for all positions, leaving each with a certain amount of excess collateral. All positions within the protocol must undergo this process. If any positions have not been processed by users using `accumulateBadDebt`, the protocol administrator must ensure that all remaining positions are appropriately managed.

{% code overflow="wrap" %}

```solidity
function accumulateBadDebt(bytes32 _collateralPoolId, address _positionAddress) external;
```

{% endcode %}

* **Redeeming Locked Collateral**: Position owners can then use the [`redeemLockedCollateral`](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/ShowStopper.sol#L247) function to transfer this excess collateral to a specified receiver. The receiver's collateral balance is recorded in the `BookKeeper`.

{% code overflow="wrap" %}

```solidity
function redeemLockedCollateral(
    bytes32 _collateralPoolId,
    address _positionAddress,
    address _collateralReceiver,
    bytes calldata /* _data */
) external;
```

{% endcode %}

#### 3. **Returning FXD and Retrieving Collateral**

* **Finalizing Debt and Price**: After dealing with bad debt by calling  [`accumulateBadDebt`](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/ShowStopper.sol#L151) function for all the positions, the [`finalizeDebt`](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/ShowStopper.sol#L180) function is called to fix the debt amount, followed by the [`finalizeCashPrice`](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/ShowStopper.sol#L195) function to set a conversion ratio from FXD to collateral. `finalizeDebt` function will revert if there will be remaining `systemSurplus`.

{% code overflow="wrap" %}

```solidity
function finalizeDebt() external;
```

{% endcode %}

* **Depositing FXD**:  FXD Owners deposit their FXD into the system using the [stablecoinAdapterDeposit](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/proxy-actions/FathomStablecoinProxyActions.sol#L184) function in the  [FathomStablecoinProxyActions](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/proxy-actions/FathomStablecoinProxyActions.sol) contract. Since the `FathomStablecoinProxyActions` contract serves as a library for the [ProxyWallet](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/proxy-wallet/ProxyWallet.sol)  contract, calls to the `stablecoinAdapterDeposit` function need to be well-encoded and executed using the [execute](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/proxy-wallet/ProxyWallet.sol#L19) function of the `ProxyWallet`, owned by the FXD owner. When encoding the function call, the `_positionAddress` argument must match the address of the FXD Owner depositing FXD into the protocol.

{% code overflow="wrap" %}

```solidity
function stablecoinAdapterDeposit(
    address _adapter,
    address _positionAddress,
    uint256 _stablecoinAmount, // [wad]
    bytes calldata _data
) public;
```

{% endcode %}

{% code overflow="wrap" %}

```solidity
function execute(bytes memory _data) public payable returns (bytes memory _response);
```

{% endcode %}

* **Whitelisting and Accumulating Stablecoin**: FXD owners must [whitelist](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol#L203) the ShowStopper contract in the [BookKeeper](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol) contract to allow FXD/Collateral manipulation. They then call [accumulateStablecoin](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/ShowStopper.sol#L214C5-L214C60) to move the FXD accounting from the `BookKeeper` to the `ShowStopper`’s `stablecoinAccumulator`.

{% code overflow="wrap" %}

```solidity
function accumulateStablecoin(uint256 _amount) external;
```

{% endcode %}

* **Redeeming Stablecoin for Collateral**: FXD owners use [redeemStablecoin](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/ShowStopper.sol#L228) to transfer collateral from the ShowStopper to their account (EOA) within the `BookKeeper`.

{% code overflow="wrap" %}

```solidity
function redeemStablecoin(bytes32 _collateralPoolId, uint256 _amount) external;
```

{% endcode %}

#### 4. **Final Withdrawal of Collateral**

* **Caging the** [**CollateralTokenAdapter**](https://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/adapters/CollateralTokenAdapter/CollateralTokenAdapter.sol): This action signifies the end of the process for depositing FXD and retrieving collateral. The owner of the protocol does the caging.
* **Emergency Withdrawal**: Finally, users can call the emergency withdrawal function to withdraw their collateral.

{% code overflow="wrap" %}

```solidity
function emergencyWithdraw(address _to) external;
```

{% endcode %}

#### 5. **Responsibility of Users**

* **Adhering to Process**: Users are advised to follow the steps specified to reduce confusion and ensure a smooth process.
* **Bearing Consequences of Deviation**: If a user deviates from the prescribed process and incurs a loss, they bear the responsibility for their actions.

#### **6. Responsibility of the protocol**

* **Providing instruction:** In times of emergency, the Fathom protocol team should provide user-friendly interfaces to ensure that users do not have to deal with overly technical tasks, such as encoding a function call and directly calling the smart contracts.
* **Skimming all the positions**: The protocol administrator must ensure that all positions are processed using the `accumulateBadDebt` function before the `coolDownPeriod` ends to ensure the correct execution of the emergency shutdown process.
* **Settling systemBadDebt and withdrawing systemSurplus**: The protocol administrator must ensure that the `systemBadDebt` is settled using the systemSurplus, and all the surplus (if any is left) is withdrawn before the `finalizeDebt` function is called.

#### Summary of the Fathom's FXD Emergency Shutdown

The emergency shutdown of Fathom's FXD is an intricate, irreversible, multi-step process crucial for preserving the stability and security of the decentralized finance (DeFi) system during significant crises. This procedure involves several key stages:

1. **Initiating Emergency Shutdown**: The process begins with halting most protocol activities through the cage function in the `ShowStopper` contract, marking a no-return point. The cooldown period following this action allows for the necessary processing of positions.
2. **Handling Excess Collateral from Positions**: The `accumulateBadDebt` function, essential for managing excess collateral, must be applied to all positions. This responsibility falls to the protocol administrator if not completed by users. Subsequently, position owners can transfer excess collateral using the `redeemLockedCollateral` function.
3. **Returning FXD and Retrieving Collateral**: After handling bad debt, the `finalizeDebt` function is called to solidify the debt amount, followed by the `finalizeCashPrice` function for setting the FXD to collateral conversion ratio. FXD owners must deposit their tokens using the `stablecoinAdapterDeposit` function, which requires precise encoding and execution. They also need to whitelist the `ShowStopper` contract for FXD/Collateral manipulation, followed by using `redeemStablecoin` to transfer collateral.
4. **Final Withdrawal of Collateral**: The process concludes with caging the `CollateralTokenAdapter` and the final step of `emergencyWithdraw` by users to reclaim their collateral.
5. **User and Protocol Responsibilities**: Users must adhere to the specified process sequence to minimize confusion and prevent losses. Any deviation leading to losses falls under the user's responsibility. On the protocol's end, providing user-friendly interfaces during emergencies and ensuring all positions are skimmed within the cooldown period is critical for smooth shutdown execution. The protocol administrator is also responsible for settling system bad debt and withdrawing any remaining system surplus before calling `finalizeDebt`.


# Maths for position safety

This section explains how the Fathom's FXD stablecoin position's safety is calculated.

For a position to be considered safe, below should hold true.

$$
lockedCollateralAmount \* PriceWithSafetyMargin > DebtShare \* debtAccumulateRate,
$$

where

$$
Price WithSafetyMargin = RawPrice \* LTV
$$

When *RawPrice* is the price of collateral from `PriceFeed` and *LTV* is Loan To Ratio.

In other words

$$
lockedCollateralVaule > debtVault
$$

$$
debtVault = debtShare \* debtAccumulateRate
$$

And `debtAccumulatedRate` is calculated as

$$
debtAccumulatedRate = (1 + interestRate)^{1 / 31,536,000}
$$

since `debtAccumulatedRate` is a second pounding *interestRate*.

#### Position safety calculation model

Please refer to below position safety calculation model.

{% embed url="<https://docs.google.com/spreadsheets/d/1--XSZWeKq2HudwH6Btlg8hSpUuEOFStGYXXUDoOW7Es/edit?usp=sharing>" %}
<https://docs.google.com/spreadsheets/d/1--XSZWeKq2HudwH6Btlg8hSpUuEOFStGYXXUDoOW7Es/edit?usp=sharing>
{% endembed %}


# Fee structure

Described in <https://docs.fathom.fi/whitepaper/version-1.0#id-5-fathom-sources-of-revenue>.


# Risk Management

### Liquidation Risks

#### **Risk:**

Your position is at risk of liquidation if the market value of your collateral falls, causing your Safety Buffer to deplete entirely (Debt Ratio equals the Collateral Factor).

#### **Mitigation:**

* Fathom utilizes improved Fixed Spread Liquidation, with batch liquidations and a gentle Close Factor. Governance decides on the Close Factor value, but even for very volatile assets, it is possible to set it to 25% of a position's Debt Value. For Gold and other less volatile assets, this value is lower. This reduces the costs for the liquidators and the risk for FXD borrowers to lose capital, at the same time preventing the risk of bad debt.
* The user can mitigate the risk by increasing the Safety Buffer to protect against potential collateral price movements. It is recommended that the market be monitored and the Safety Buffer adjusted accordingly. Fathom is building AI agents to help users to understand the market conditions.
* Fathom FXD is moving towards employing a dual-threshold liquidation process designed to reduce the frequency and impact of liquidations. This approach includes a 'soft' threshold where AI agents assess market conditions. If the price drop is deemed temporary with an expected quick recovery, actions like liquidation can be postponed to avoid unnecessary cascades. The 'hard' threshold represents a more critical point where liquidation occurs to preserve system stability.
* You can find more details about liquidation process in [Whitepaper](/whitepaper).

### Price Stability

#### **Risk:**

Though fully backed by assets, FXD’s market price can fluctuate above or below its $1 peg temporarily due to real-time supply and demand dynamics.

#### **Mitigation:**

* Stability Fees can be adjusted to influence market behavior, encouraging repayment of loans with FXD during high supply phases, thus bolstering demand.
* FXD includes mechanisms like a debt ceiling to regulate FXD supply in accordance with market demand.
* The Stability Swap Module in Fathom ecosystem facilitates efficient arbitrage opportunities, stabilizing the FXD price around its peg.
* You can find more details about stability of FXD price in [Whitepaper](/whitepaper).

### Undercollateralization

#### **Risk:**

There is a potential for FXD to become undercollateralized if the market value of the backing assets drops significantly.

#### **Mitigation:**

* Liquidations are supposed to occur before collateralization value drops to 100%
* A conservative approach to the collateral factor limits the maximum FXD issuance per collateral unit. This factor is continuously adjusted based on asset volatility and comparative data from other lending protocols, ensuring a sufficient buffer against market downturns.
* Interest accrued on loans contributes to a surplus reserve, fortifying our capacity to manage and cover bad debts effectively.
* FXD is using the diverse basket of various assets, lowering the risk of total collateral value drop.

### Smart Contract Vulnerabilities

#### **Risk:**

Despite thorough audits, our smart contracts and those of integrated platforms might contain vulnerabilities.

#### **Mitigation:**

We engage multiple reputable third-party auditing firms to scrutinize our contracts, significantly mitigating potential risks. Comprehensive audit reports are accessible for transparency.

The list of the audits:

* <https://audits.oxor.io/reports/-Ntzvo0Tum3zOymAJXQ7>
* <https://github.com/strongholdsec/audits/blob/main/Fathom/fathom-stablecoin/Fathom%20Stablecoin%20Audit%20Report.pdf>


# Interfaces


# ProxyWalletRegistry

https\://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/proxy-wallet/ProxyWalletRegistry.sol

The `ProxyWalletRegistry` manages the creation and administration of proxy wallets. This contract serves as a registry to associate owners with their respective proxy wallets and includes features to manage access and operational states.

#### Events

* **`LogAddToWhitelist`**:
  * Emitted when an address is added to the whitelist. Only in centralized mode.
  * Parameters:
    * `_user` (address indexed): The address added to the whitelist.
* **`LogRemoveFromWhitelist`**:
  * Emitted when an address is removed from the whitelist. Only in centralized mode.
  * Parameters:
    * `_user` (address indexed): The address removed from the whitelist.
* **`LogSetDecentralizedMode`**:
  * Emitted when the decentralized mode is toggled.
  * Parameters:
    * `newValue` (bool): The new state of the decentralized mode (true for enabled, false for disabled).
* **`LogProxyWalletCreation`**:
  * Emitted when a new proxy wallet is created and associated with an owner.
  * Parameters:
    * `owner` (address): The owner of the new proxy wallet.
    * `proxyWallet` (address): The address of the newly created proxy wallet.

#### State Variables

* **`proxies`** (mapping(address => ProxyWallet)):
  * Maps an owner's address to their corresponding proxy wallet.
* **`factory`** (ProxyWalletFactory):
  * The factory contract used for creating new proxy wallets.
* **`whitelisted`** (mapping(address => bool)):
  * Tracks whether addresses are whitelisted, which influences their ability to create proxy wallets. Only in centralized mode.
* **`bookKeeper`** (IBookKeeper):
  * Reference to the `BookKeeper` contract used for managing financial interactions within the system.
* **`isDecentralizedMode`** (bool):
  * A flag indicating whether the system is operating in a decentralized mode, affecting proxy wallet creation permissions.

#### Functions

**Public/External Functions**

* **`initialize`**:
  * Initializes the `ProxyWalletRegistry` with necessary contract references.
  * Parameters:
    * `_factory` (address): Address of the `ProxyWalletFactory` contract.
    * `_bookKeeper` (address): Address of the `BookKeeper` contract.
* **`addToWhitelist`**:
  * Adds an address to the whitelist. Only in centralized mode.
  * Parameters:
    * `_usr` (address): The address to add to the whitelist.
* **`removeFromWhitelist`**:
  * Removes an address from the whitelist. Only in centralized mode.
  * Parameters:
    * `_usr` (address): The address to remove from the whitelist.
* **`setDecentralizedMode`**:
  * Toggles the decentralized mode of the registry.
  * Parameters:
    * `isOn` (bool): Boolean to enable or disable decentralized mode.
* **`pause`** and **`unpause`**:
  * Controls the paused state of the contract, restricting or enabling function execution based on the contract's operational state.
* **`build0`**:
  * Convenience function that allows an owner to create a proxy wallet for themselves without specifying an owner explicitly.
* **`build`**:
  * Creates a new proxy wallet for a specified owner if they are whitelisted or if the contract is in decentralized mode.
  * Parameters:
    * `_owner` (address): The intended owner of the new proxy wallet.
* **`setOwner`**:
  * Changes the owner of a specific proxy wallet.
  * Parameters:
    * `_newOwner` (address): The new owner to set.


# ProxyWallet

https\://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/proxy-wallet/ProxyWallet.sol

#### Overview

The `ProxyWallet` serves as a flexible, owner-controlled wallet that can execute arbitrary transactions. It uses a `ProxyActionsStorage` to manage state and actions and leverages comprehensive access control via `FathomAuth`.

#### Events

* **`LogSetAuthority`** (from `FathomAuthEvents`):
  * Emitted when the authority for this contract is set.
  * Parameters:
    * `_authority` (address indexed): The address of the new authority.
* **`LogSetOwner`** (from `FathomAuthEvents`):
  * Emitted when the owner of the contract is changed.
  * Parameters:
    * `_owner` (address indexed): The address of the new owner.
* **`LogNote`** (from `FathomNote`):
  * Emitted for each transaction executed through the proxy wallet, providing details of the operation.
  * Parameters:
    * `sig` (bytes4 indexed): The signature of the function called.
    * `guy` (address indexed): The address initiating the call.
    * `foo` (bytes32 indexed): Part of the call data.
    * `bar` (bytes32 indexed): Part of the call data.
    * `wad` (uint256): The value involved in the transaction.
    * `fax` (bytes): Full call data.

#### State Variables

* **`proxyActionsStorage`** (`ProxyActionsStorage`):
  * The storage contract used for managing proxy actions and settings.
* **`authority`** (`IAuthority` from `FathomAuth`):
  * The authority contract that checks permissions for actions.
* **`owner`** (`address` from `FathomAuth`):
  * The owner of the contract, who has elevated privileges.

#### Functions

* **`execute`**:
  * Executes a transaction via the proxy, allowing the wallet to interact with other contracts.
  * Parameters:
    * `_data` (bytes memory): The calldata or transaction data to be executed.
  * Returns:
    * `_response` (bytes memory): The return data from the executed call.
* **`receive`**:
  * A fallback function to allow the contract to receive Ether directly.


# FathomStablecoinProxyActions

https\://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/proxy-actions/FathomStablecoinProxyActions.sol

The `FathomStablecoinProxyActions` contract enables complex operations such as opening, managing, and interacting with positions (vaults) that hold collateral and issue stablecoins. It handles tasks like depositing collateral, drawing stablecoins against it, paying back debt, and unlocking collateral.

The address for this interface should be the address of the particular `ProxyWallet`.

#### Functions:

**Admin Functions:**

* **`whitelist(address _bookKeeper, address _usr)`**:
  * **Arguments**:
    * `_bookKeeper`: The address of the bookkeeper contract.
    * `_usr`: The address to be whitelisted.
* **`blacklist(address _bookKeeper, address _usr)`**:
  * **Arguments**:
    * `_bookKeeper`: The address of the bookkeeper contract.
    * `_usr`: The address to be blacklisted.

**Position Management Functions:**

* **`allowManagePosition(address _manager, uint256 _positionId, address _user, uint256 _ok)`**:
  * **Arguments**:
    * `_manager`: Address of the position management contract.
    * `_positionId`: Numeric ID of the position.
    * `_user`: Address of the user to be allowed or disallowed.
    * `_ok`: Permission flag (typically 0 or 1).
* **`allowMigratePosition(address _manager, address _user, uint256 _ok)`**:
  * **Arguments**:
    * `_manager`: Address of the position management contract.
    * `_user`: Address of the user whose migration permissions are being set.
    * `_ok`: Permission flag (typically 0 or 1).
* **`exportPosition(address _manager, uint256 _positionId, address _destination)`**:
  * **Arguments**:
    * `_manager`: Address of the position management contract.
    * `_positionId`: Numeric ID of the position.
    * `_destination`: Address where the position should be exported.
* **`importPosition(address _manager, address _source, uint256 _positionId)`**:
  * **Arguments**:
    * `_manager`: Address of the position management contract.
    * `_source`: Address from which the position is imported.
    * `_positionId`: Numeric ID of the position.
* **`movePosition(address _manager, uint256 _source, uint256 _destination)`**:
  * **Arguments**:
    * `_manager`: Address of the position management contract.
    * `_source`: Numeric ID of the source position.
    * `_destination`: Numeric ID of the destination position.

**Collateral and Stablecoin Management Functions:**

* **`safeLockXDC(address _manager, address _xdcAdapter, uint256 _positionId, address _owner, bytes calldata _data)`**:
  * **Arguments**:
    * `_manager`: Address of the manager contract.
    * `_xdcAdapter`: Address of the XDC adapter contract.
    * `_positionId`: Numeric ID of the position.
    * `_owner`: Address of the owner of the position.
    * `_data`: Additional data passed in call.
* **`draw(address _manager, address _stabilityFeeCollector, address _stablecoinAdapter, uint256 _positionId, uint256 _amount, bytes calldata _data)`**:
  * **Arguments**:
    * `_manager`: Address of the manager contract.
    * `_stabilityFeeCollector`: Address of the stability fee collector.
    * `_stablecoinAdapter`: Address of the stablecoin adapter.
    * `_positionId`: Numeric ID of the position.
    * `_amount`: Amount of stablecoins to draw.
    * `_data`: Additional data passed in call.

#### Events:

* **`LogBorrowedAmount(address _positionAddress, uint256 _FXDBorrowAmount)`**:
  * **Arguments**:
    * `_positionAddress`: Address of the position from which stablecoins were borrowed.
    * `_FXDBorrowAmount`: Amount of stablecoins borrowed.
* **`LogPaidAmount(address _positionAddress, uint256 _FXDPaidAmount)`**:
  * **Arguments**:
    * `_positionAddress`: Address of the position to which stablecoins were repaid.
    * `_FXDPaidAmount`: Amount of stablecoins repaid.


# CollateralPoolConfig

https\://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/config/CollateralPoolConfig.sol

The `CollateralPoolConfig` contract manages the configuration of different collateral pools within the Fathom protocol. It includes settings such as debt ceilings, liquidation ratios, and other important parameters that define the behavior and constraints of collateral pools.

#### Structs

**CollateralPool**

Defines the parameters and state of a collateral pool.

* `totalDebtShare` (uint256): The total debt share of the stablecoin issued against this collateral pool, denominated in wei.
* `debtAccumulatedRate` (uint256, ray): The accumulated rate which calculates the compounding stability fee over time. Initialized to 1 RAY (10^27).
* `priceWithSafetyMargin` (uint256, ray): The price of the collateral with a safety margin applied. This price accounts for the liquidation ratio.
* `debtCeiling` (uint256, rad): The maximum debt that can be issued against this collateral pool.
* `debtFloor` (uint256, rad): The minimum amount of debt required to open a position in this collateral pool.
* `priceFeed` (address): Address of the price feed contract which provides price updates for the collateral.
* `liquidationRatio` (uint256, ray): The minimum collateralization ratio required to avoid liquidation, expressed as a Ray.
* `stabilityFeeRate` (uint256, ray): The per-second stability fee rate, compounding to calculate the debt over time.
* `lastAccumulationTime` (uint256): The timestamp of the last update to the `debtAccumulatedRate`.
* `adapter` (address): The adapter address that handles token-specific logic for deposits and withdrawals.
* `closeFactorBps` (uint256): The percentage (in basis points) of debt that can be liquidated in one transaction.
* `liquidatorIncentiveBps` (uint256): Additional collateral percentage given to the liquidator as an incentive.
* `treasuryFeesBps` (uint256): The fee taken by the treasury on liquidations, expressed in basis points.
* `strategy` (address): Address of the liquidation strategy contract for this collateral pool.
* `positionDebtCeiling` (uint256, rad): The maximum debt that any single position can hold in this collateral pool.

**CollateralPoolInfo**

A simplified struct for returning basic information about a collateral pool.

* `debtAccumulatedRate` (uint256, ray): Current accumulated rate for stability fees.
* `totalDebtShare` (uint256): Total debt issued against this pool.
* `debtCeiling` (uint256, rad): Maximum debt allowed in this pool.
* `priceWithSafetyMargin` (uint256, ray): Price of collateral with safety margin considered.
* `debtFloor` (uint256, rad): Minimum debt per position.
* `positionDebtCeiling` (uint256, rad): Maximum debt per individual position.

### Storage Variables

**`accessControlConfig`**

* **Type:** `IAccessControlConfig`
* **Description:** An instance of the `IAccessControlConfig` interface that provides functionalities for managing access control based on roles. This variable is crucial for enforcing role-based security within the contract, ensuring that only authorized roles can perform specific actions (e.g., updating pool configurations).

### Set Functions

* **setPriceWithSafetyMargin(bytes32 \_collateralPoolId, uint256 \_priceWithSafetyMargin)**: Sets the price with a safety margin for the specified pool. Only callable by the price oracle role.
* **setDebtCeiling(bytes32 \_collateralPoolId, uint256 \_debtCeiling)**: Sets the debt ceiling for a pool. Only callable by the contract owner.
* **setPositionDebtCeiling(bytes32 \_collateralPoolId, uint256 \_positionDebtCeiling)**: Sets the maximum debt that can be issued against a single position in the specified pool.
* **setPriceFeed(bytes32 \_poolId, address \_priceFeed)**: Assigns a new price feed contract to a collateral pool.
* **setLiquidationRatio(bytes32 \_poolId, uint256 \_liquidationRatio)**: Adjusts the liquidation ratio for a collateral pool.
* **setStabilityFeeRate(bytes32 \_collateralPoolId, uint256 \_stabilityFeeRate)**: Sets the stability fee rate for a collateral pool.
* **setDebtFloor(bytes32 \_collateralPoolId, uint256 \_debtFloor)**: Sets the minimum debt that can be created in a specific collateral pool, preventing under-collateralized positions.
* **setAdapter(bytes32 \_collateralPoolId, address \_adapter)**: Updates the adapter address for a collateral pool, which handles specific token interactions for depositing and withdrawing collateral.
* **setCloseFactorBps(bytes32 \_collateralPoolId, uint256 \_closeFactorBps)**: Sets the percentage (in basis points) of how much debt can be liquidated in a single transaction for a specific collateral pool.
* **setLiquidatorIncentiveBps(bytes32 \_collateralPoolId, uint256 \_liquidatorIncentiveBps)**: Defines the incentive, in basis points, given to liquidators for performing liquidations in a specific pool.
* **setTreasuryFeesBps(bytes32 \_collateralPoolId, uint256 \_treasuryFeesBps)**: Sets the treasury fees, in basis points, collected from liquidations in a specific collateral pool.
* **setTotalDebtShare(bytes32 \_collateralPoolId, uint256 \_totalDebtShare)**: Updates the total debt share of the stablecoin issued against a specific collateral pool. Restricted to the bookkeeper role.
* **setDebtAccumulatedRate(bytes32 \_collateralPoolId, uint256 \_debtAccumulatedRate)**: Updates the accumulated rate for calculating the compounding stability fee over time for a specific pool. Also restricted to the bookkeeper role.
* **setStrategy(bytes32 \_collateralPoolId, address \_strategy)**: Assigns a new liquidation strategy contract to a collateral pool, which defines how liquidations should be handled.
* **updateLastAccumulationTime(bytes32 \_collateralPoolId)**: Updates the timestamp of the last accumulation of stability fees for a collateral pool. Restricted to the stability fee collector role.

**View Functions**

* **collateralPools(bytes32 \_collateralPoolId)**: Returns detailed information about a specific collateral pool.
* **getTotalDebtShare(bytes32 \_collateralPoolId)**: Retrieves the total debt share issued against a collateral pool.
* **getDebtAccumulatedRate(bytes32 \_collateralPoolId)**: Retrieves the current debt accumulated rate for a collateral pool.
* **getPriceWithSafetyMargin(bytes32 \_collateralPoolId)**: Retrieves the current price of the collateral in the pool, adjusted for the safety margin.
* **getDebtCeiling(bytes32 \_collateralPoolId)**: Retrieves the debt ceiling for a specific collateral pool.
* **getPositionDebtCeiling(bytes32 \_collateralPoolId)**: Gets the maximum amount of debt that can be taken out in a single position for a specified collateral pool.
* **getDebtFloor(bytes32 \_collateralPoolId)**: Retrieves the minimum debt amount that must be maintained in a position within a specific collateral pool.
* **getPriceFeed(bytes32 \_collateralPoolId)**: Returns the address of the price feed contract associated with a collateral pool.
* **getLiquidationRatio(bytes32 \_collateralPoolId)**: Retrieves the liquidation ratio for a collateral pool, determining the minimum required collateralization.
* **getStabilityFeeRate(bytes32 \_collateralPoolId)**: Retrieves the stability fee rate for a specific collateral pool.
* **getLastAccumulationTime(bytes32 \_collateralPoolId)**: Retrieves the timestamp of the last stability fee accumulation for a collateral pool.
* **getAdapter(bytes32 \_collateralPoolId)**: Returns the address of the token adapter associated with a collateral pool.
* **getCloseFactorBps(bytes32 \_collateralPoolId)**: Retrieves the close factor, in basis points, for a specific collateral pool.
* **getLiquidatorIncentiveBps(bytes32 \_collateralPoolId)**: Retrieves the liquidator incentive, in basis points, for a specific collateral pool.
* **getTreasuryFeesBps(bytes32 \_collateralPoolId)**: Retrieves the percentage of fees collected for the treasury from liquidations in a specific collateral pool.
* **getStrategy(bytes32 \_collateralPoolId)**: Returns the address of the liquidation strategy contract for a collateral pool.
* **getCollateralPoolInfo(bytes32 \_collateralPoolId)**: Provides a snapshot of current settings and state for a specific collateral pool.

### Events

**LogSetPriceWithSafetyMargin**

* **Parameters:**
  * `_caller` (address): The address of the user who called the function.
  * `_collateralPoolId` (bytes32): The identifier of the collateral pool.
  * `_priceWithSafetyMargin` (uint256): The updated price of the collateral with the safety margin applied.
* **Description:** This event is emitted when the price with safety margin for a specific collateral pool is updated. The safety margin is a buffer that helps protect the protocol against rapid price fluctuations leading to under-collateralized loans.

**LogSetDebtCeiling**

* **Parameters:**
  * `_caller` (address): The address of the user who called the function.
  * `_collateralPoolId` (bytes32): The identifier of the collateral pool.
  * `_debtCeiling` (uint256): The updated debt ceiling of the pool.
* **Description:** This event is fired when the debt ceiling of a collateral pool is set. The debt ceiling is the maximum amount of debt that can be issued against the collateral in the pool.

**LogSetDebtFloor**

* **Parameters:**
  * `_caller` (address): The address of the user who called the function.
  * `_collateralPoolId` (bytes32): The identifier of the collateral pool.
  * `_debtFloor` (uint256): The updated debt floor of the pool.
* **Description:** Emitted when the debt floor of a collateral pool is updated. The debt floor is the minimum debt that must be maintained in any position within this pool, ensuring that very small positions do not disproportionately consume resources.

**LogSetPriceFeed**

* **Parameters:**
  * `_caller` (address): The address of the user who called the function.
  * `_poolId` (bytes32): The identifier of the collateral pool.
  * `_priceFeed` (address): The address of the new price feed contract.
* **Description:** This event is emitted when the price feed for a collateral pool is changed. The price feed is a critical component that supplies the market price of the collateral, which is used to manage all economic activities related to the pool.

**LogSetLiquidationRatio**

* **Parameters:**
  * `_caller` (address): The address of the user who called the function.
  * `_poolId` (bytes32): The identifier of the collateral pool.
  * `_data` (uint256): The updated liquidation ratio.
* **Description:** Emitted when the liquidation ratio of a collateral pool is updated. This ratio determines the threshold below which positions become subject to liquidation.

**LogSetStabilityFeeRate**

* **Parameters:**
  * `_caller` (address): The address of the user who called the function.
  * `_poolId` (bytes32): The identifier of the collateral pool.
  * `_data` (uint256): The updated stability fee rate.
* **Description:** Fired when the stability fee rate for a collateral pool is set. This fee rate affects how quickly debt accrues on borrowed amounts.

**LogSetAdapter**

* **Parameters:**
  * `_caller` (address): The address of the user who called the function.
  * `_collateralPoolId` (bytes32): The identifier of the collateral pool.
  * `_adapter` (address): The address of the adapter contract.
* **Description:** Emitted when the adapter for a collateral pool is changed. Adapters handle the specific mechanics of interacting with different types of collateral.

**LogSetCloseFactorBps**

* **Parameters:**
  * `_caller` (address): The address of the user who called the function.
  * `_collateralPoolId` (bytes32): The identifier of the collateral pool.
  * `_closeFactorBps` (uint256): The updated close factor in basis points.
* **Description:** This event is emitted when the close factor for a collateral pool is updated. The close factor determines the percentage of a position that can be liquidated in a single transaction.

**LogSetLiquidatorIncentiveBps**

* **Parameters:**
  * `_caller` (address): The address of the user who called the function.
  * `_collateralPoolId` (bytes32): The identifier of the collateral pool.
  * `_liquidatorIncentiveBps` (uint256): The updated liquidator incentive in basis points.
* **Description:** Emitted when the liquidator incentive for a collateral pool is updated. This incentive is given to liquidators as a reward for executing liquidations.

**LogSetTreasuryFeesBps**

* **Parameters:**
  * `_caller` (address): The address of the user who called the function.
  * `_collateralPoolId` (bytes32): The identifier of the collateral pool.
  * `_treasuryFeeBps` (uint256): The updated treasury fees in basis points.
* **Description:** Fired when the treasury fees for a collateral pool are set. These fees are transferred to the treasury upon liquidations and contribute to the overall economic stability of the protocol.

**LogSetTotalDebtShare**

* **Parameters:**
  * `_caller` (address): The address of the user who called the function.
  * `_collateralPoolId` (bytes32): The identifier of the collateral pool.
  * `_totalDebtShare` (uint256): The updated total debt share.
* **Description:** This event is emitted when the total debt share for a collateral pool is updated. This represents the total amount of debt issued against the collateral in the pool.

**LogSetDebtAccumulatedRate**

* **Parameters:**
  * `_caller` (address): The address of the user who called the function.
  * `_collateralPoolId` (bytes32): The identifier of the collateral pool.
  * `_debtAccumulatedRate` (uint256): The updated accumulated rate for debt.
* **Description:** Emitted when the debt accumulated rate for a collateral pool is updated. This rate determines how stability fees compound over time.

**LogSetStrategy**

* **Parameters:**
  * `_caller` (address): The address of the user who called the function.
  * `_collateralPoolId` (bytes32): The identifier of the collateral pool.
  * `_strategy` (address): The address of the liquidation strategy contract.
* **Description:** Fired when the liquidation strategy for a collateral pool is updated. This strategy defines how liquidations should be conducted for the specific type of collateral.

**LogPositionDebtCeiling**

* **Parameters:**
  * `_caller` (address): The address of the user who called the function.
  * `_collateralPoolId` (bytes32): The identifier of the collateral pool.
  * `_positionDebtCeiling` (uint256): The updated maximum debt that can be taken out in a single position for the specified collateral pool.
* **Description:** This event is emitted when the position debt ceiling of a collateral pool is updated. This ceiling limits the maximum debt that any single position can hold within the pool.


# BookKeeper

https\://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/BookKeeper.sol

The `BookKeeper` manages the state and operations related to collateral pools within Fathom FXD Protocol. It involves the management of stablecoin debt, collateral ratios, and various fees associated with positions held in these pools.

### **Structs**

#### **`CollateralPool`**: Contains detailed metrics and settings for each collateral pool, including debt shares, rates, ceilings, and specific fees.

* `totalDebtShare` (uint256, \[wad]): Total debt share of FXD stablecoin for this collateral pool.
* `debtAccumulatedRate` (uint256, \[ray]): Rate at which debt accumulates, essentially the price of the internal token.
* `priceWithSafetyMargin` (uint256, \[ray]): Adjusted price accounting for the collateralization safety margin.
* `debtCeiling` (uint256, \[rad]): Maximum allowable debt for this pool.
* `debtFloor` (uint256, \[rad]): Minimum debt amount for positions within this pool.
* `priceFeed` (address): Oracle address providing the price feed.
* `liquidationRatio` (uint256, \[ray]): Required collateral ratio to avoid liquidation.
* `stabilityFeeRate` (uint256, \[ray]): Fee rate applied to the debt for maintaining stability.
* `lastAccumulationTime` (uint256, \[unix epoch time]): Timestamp of the last debt rate accumulation.
* `adapter` (address): Interface for integrating external functionalities.
* `closeFactorBps` (uint256): Basis points describing the percentage of debt that can be liquidated in one action.
* `liquidatorIncentiveBps` (uint256): Additional collateral percentage awarded to liquidators.
* `treasuryFeesBps` (uint256): Collateral percentage allocated to the treasury from liquidations.
* `strategy` (address): Address of the strategy used for managing liquidations.
* `positionDebtCeiling` (uint256, \[rad]): Maximum debt that an individual position can hold.

#### **`CollateralPoolInfo`**: Simplified version focused on essential metrics like debt rate, total debt share, and debt ceilings.

* `debtAccumulatedRate` (uint256, \[ray]): Current debt accumulation rate for the pool.
* `totalDebtShare` (uint256, \[wad]): Total shared debt in the pool.
* `debtCeiling` (uint256, \[rad]): Debt ceiling of the pool.
* `priceWithSafetyMargin` (uint256, \[ray]): Price adjusted for safety margins.
* `debtFloor` (uint256, \[rad]): Minimum threshold of debt for the pool.
* `positionDebtCeiling` (uint256, \[rad]): Maximum debt allowed per position.

#### **`Position`**: Structure representing individual positions within the collateral pools, focused on collateral and debt metrics.

* **`lockedCollateral`** (uint256, \[wad]): Amount of collateral currently locked within this position.
* **`debtShare`** (uint256, \[wad]): Share of the FXD stablecoin debt attributed to this position.

### State Variables

#### `positions`

* **Description**: Retrieves the position details for a given collateral pool and position address.
* **Parameters**:
  * `_collateralPoolId` (bytes32): The identifier for the collateral pool.
  * `_positionAddress` (address): The address of the position.
* **Returns**: `Position` struct containing the locked collateral and debt share of the position.

#### `collateralToken`

* **Description**: Retrieves the amount of collateral token that has been deposited into the protocol for a given collateral pool and address.
* **Parameters**:
  * `_collateralPoolId` (bytes32): The identifier for the collateral pool.
  * `_address` (address): The address for which to retrieve the collateral token amount.
* **Returns**: `uint256` representing the amount of collateral token.

#### `stablecoin`

* **Description**: Retrieves the amount of stablecoin that has been deposited or has not been withdrawn from the protocol for a given address.
* **Parameters**:
  * `_address` (address): The address for which to retrieve the stablecoin amount.
* **Returns**: `uint256` representing the amount of stablecoin.

#### `systemBadDebt`

* **Description**: Retrieves the amount of system bad debt, which arises from late liquidations for a given address.
* **Parameters**:
  * `_address` (address): The address for which to retrieve the bad debt amount.
* **Returns**: `uint256` representing the amount of bad debt.

#### `poolStablecoinIssued`

* **Description**: Retrieves the amount of stablecoin issued per collateral pool.
* **Parameters**:
  * `_collateralPoolId` (bytes32): The identifier for the collateral pool.
* **Returns**: `uint256` representing the amount of stablecoin issued for the specified collateral pool.

#### `positionWhitelist`

* **Description**: Checks if a position address has been whitelisted to allow adjustments by another address.
* **Parameters**:
  * `_positionAddress` (address): The position address.
  * `_delegateAddress` (address): The address to check if it has allowance to adjust the position.
* **Returns**: `uint256` (1 for allowed, 0 for not allowed).

### **Set Functions**

These functions are used to set or update key parameters of the collateral pools:

#### **`setPriceWithSafetyMargin(bytes32 collateralPoolId, uint256 priceWithSafetyMargin)`**

* **`collateralPoolId`** (`bytes32`): The identifier for the collateral pool.
* **`priceWithSafetyMargin`** (`uint256`): The new price of the collateral, adjusted to include the safety margin.

#### **`setTotalDebtShare(bytes32 collateralPoolId, uint256 totalDebtShare)`**

* **`collateralPoolId`** (`bytes32`): The identifier for the collateral pool.
* **`totalDebtShare`** (`uint256`): The new total debt share for the collateral pool.

#### **`setDebtAccumulatedRate(bytes32 collateralPoolId, uint256 debtAccumulatedRate)`**

* **`collateralPoolId`** (`bytes32`): The identifier for the collateral pool.
* **`debtAccumulatedRate`** (`uint256`): The new accumulated rate of debt for the collateral pool.

#### **`setPositionDebtCeiling(bytes32 collateralPoolId, uint256 positionDebtCeiling)`**

* **`collateralPoolId`** (`bytes32`): The identifier for the collateral pool.
* **`positionDebtCeiling`** (`uint256`): The new debt ceiling for any individual position within the collateral pool.

**Update Function**

#### **`updateLastAccumulationTime(bytes32 collateralPoolId)`**

* **`collateralPoolId`** (`bytes32`): The identifier for the collateral pool for which the last accumulation time will be updated.

**Retrieval Functions**

These functions provide read-only access to various parameters and states within the collateral pools:

#### **`collateralPools(bytes32 collateralPoolId)`**

* **`collateralPoolId`** (`bytes32`): The identifier for the collateral pool. Returns the `CollateralPool` struct with detailed information.

#### **`getTotalDebtShare(bytes32 collateralPoolId)`**

* **`collateralPoolId`** (`bytes32`): The identifier for the collateral pool. Returns the total debt share as `uint256`.

#### **`getDebtAccumulatedRate(bytes32 collateralPoolId)`**

* **`collateralPoolId`** (`bytes32`): The identifier for the collateral pool. Returns the debt accumulated rate as `uint256`.

#### **`getPriceWithSafetyMargin(bytes32 collateralPoolId)`**

* **`collateralPoolId`** (`bytes32`): The identifier for the collateral pool. Returns the price adjusted for safety margin as `uint256`.

#### **`getDebtCeiling(bytes32 collateralPoolId)`**

* **`collateralPoolId`** (`bytes32`): The identifier for the collateral pool. Returns the debt ceiling as `uint256`.

#### **`getDebtFloor(bytes32 collateralPoolId)`**

* **`collateralPoolId`** (`bytes32`): The identifier for the collateral pool. Returns the debt floor as `uint256`.

#### **`getPositionDebtCeiling(bytes32 collateralPoolId)`**

* **`collateralPoolId`** (`bytes32`): The identifier for the collateral pool. Returns the position debt ceiling as `uint256`.

#### **`getPriceFeed(bytes32 collateralPoolId)`**

* **`collateralPoolId`** (`bytes32`): The identifier for the collateral pool. Returns the address of the price feed.

#### **`getLiquidationRatio(bytes32 collateralPoolId)`**

* **`collateralPoolId`** (`bytes32`): The identifier for the collateral pool. Returns the liquidation ratio as `uint256`.

#### **`getStabilityFeeRate(bytes32 collateralPoolId)`**

* **`collateralPoolId`** (`bytes32`): The identifier for the collateral pool. Returns the stability fee rate as `uint256`.

#### **`getLastAccumulationTime(bytes32 collateralPoolId)`**

* **`collateralPoolId`** (`bytes32`): The identifier for the collateral pool. Returns the last accumulation time as `uint256`.

#### **`getAdapter(bytes32 collateralPoolId)`**

* **`collateralPoolId`** (`bytes32`): The identifier for the collateral pool. Returns the address of the adapter.

#### **`getCloseFactorBps(bytes32 collateralPoolId)`**

* **`collateralPoolId`** (`bytes32`): The identifier for the collateral pool

### **Events**

#### `LogSetTotalDebtCeiling`

* **Emitted when**: The total debt ceiling of the system is updated.
* **Parameters**:
  * `_caller` (address indexed): The address of the user who initiated the update.
  * `_totalDebtCeiling` (uint256): The new total debt ceiling set for the system.

#### `LogSetAccessControlConfig`

* **Emitted when**: The access control configuration is updated.
* **Parameters**:
  * `_caller` (address indexed): The address of the user who initiated the update.
  * `_accessControlConfig` (address): The new address of the access control configuration.

#### `LogSetCollateralPoolConfig`

* **Emitted when**: The collateral pool configuration is updated.
* **Parameters**:
  * `_caller` (address indexed): The address of the user who initiated the update.
  * `_collateralPoolConfig` (address): The new address of the collateral pool configuration.

#### `LogAdjustPosition`

* **Emitted when**: A position is adjusted (collateral or debt share is changed).
* **Parameters**:
  * `_caller` (address indexed): The address of the user who made the adjustment.
  * `_collateralPoolId` (bytes32 indexed): The identifier of the collateral pool.
  * `_positionAddress` (address indexed): The address of the position being adjusted.
  * `_lockedCollateral` (uint256): The amount of collateral locked.
  * `_debtShare` (uint256): The debt share associated with the position.
  * `_positionDebtValue` (uint256): The total debt value of the position.
  * `_addCollateral` (int256): The amount of collateral added or removed.
  * `_addDebtShare` (int256): The amount of debt share added or removed.

#### `LogAddCollateral`

* **Emitted when**: Collateral is added to a position.
* **Parameters**:
  * `_caller` (address indexed): The address of the user who added the collateral.
  * `_usr` (address indexed): The address of the position where collateral is added.
  * `_amount` (int256): The amount of collateral added.

#### `LogMoveCollateral`

* **Emitted when**: Collateral is moved from one position to another.
* **Parameters**:
  * `_caller` (address indexed): The address of the user who initiated the move.
  * `_collateralPoolId` (bytes32 indexed): The identifier of the collateral pool involved.
  * `_src` (address): The source address from which collateral is moved.
  * `_dst` (address indexed): The destination address to which collateral is moved.
  * `_amount` (uint256): The amount of collateral moved.

#### `LogMoveStablecoin`

* **Emitted when**: Stablecoin is moved from one account to another.
* **Parameters**:
  * `_caller` (address indexed): The address of the user who initiated the move.
  * `_src` (address): The source address from which stablecoin is moved.
  * `_dst` (address indexed): The destination address to which stablecoin is moved.
  * `_amount` (uint256): The amount of stablecoin moved.

#### `StablecoinIssuedAmount`

* **Emitted when**: Stablecoin issuance data is recorded.
* **Parameters**:
  * `_totalStablecoinIssued` (uint256): Total stablecoin issued to date.
  * `_collateralPoolId` (bytes32 indexed): The identifier of the collateral pool.
  * `_poolStablecoinIssued` (uint256): Amount of stablecoin issued for the specified collateral pool.

### **Role Management**

These functions manage access control for different roles within the protocol, such as granting and revoking roles, and checking role assignments.

The `BookKeeper` serves as a comprehensive system for managing collateral pools, their configurations, and associated roles, ensuring robust control over the protocol's functionalities related to stablecoin issuance and collateral management.

Includes functions like `grantRole`, `revokeRole`, and `hasRole`, managing access and permissions within the protocol.

#### Events

#### **`RoleAdminChanged`**: Emitted when there is a change in the administration of a role within the system.

* `role` (`bytes32 indexed`): The role affected.
* `previousAdminRole` (`bytes32 indexed`): The previous administrator of the role.
* `newAdminRole` (`bytes32 indexed`): The new administrator of the role.

#### **`RoleGranted`**: Indicates that a role has been granted to an account.

* `role` (`bytes32 indexed`): The role that has been granted.
* `account` (`address indexed`): The account to which the role has been granted.
* `sender` (`address indexed`): The account that performed the role grant.

#### **`RoleRevoked`**: Signals that a role has been revoked from an account.

* `role` (`bytes32 indexed`): The role that has been revoked.
* `account` (`address indexed`): The account from which the role has been removed.
* `sender` (`address indexed`): The account that performed the role revocation.

#### Functions

#### **`hasRole(bytes32 role, address account)`**

* Checks if a specific account has been granted a specified role.
* **Arguments:**
  * **`role`** (`bytes32`): The identifier of the role to check.
  * **`account`** (`address`): The address of the account to check for the role.
* **Returns:** `bool` indicating whether the account has the specified role.

#### **`getRoleAdmin(bytes32 role)`**

* Retrieves the administrator role for a given role. The administrator role is capable of managing the permissions for the specified role, including granting and revoking it.
* **Arguments:**
  * **`role`** (`bytes32`): The role identifier for which the admin role is requested.
* **Returns:** `bytes32` representing the admin role that manages the specified role.

#### **`grantRole(bytes32 role, address account)`**

* Grants a role to an account. This function can only be called by an account that has the admin role for the role being granted.
* **Arguments:**
  * **`role`** (`bytes32`): The role to be granted.
  * **`account`** (`address`): The address of the account to which the role will be granted.
* **Emits:** A `RoleGranted` event indicating that the role has been granted.

#### **`revokeRole(bytes32 role, address account)`**

* Revokes a role from an account. This function can only be called by an account that has the admin role for the role being revoked.
* **Arguments:**
  * **`role`** (`bytes32`): The role to be revoked.
  * **`account`** (`address`): The address of the account from which the role will be revoked.
* **Emits:** A `RoleRevoked` event indicating that the role has been revoked.

#### **`renounceRole(bytes32 role, address account)`**

* Allows an account to renounce a role it currently holds. This function is designed to be used in cases where an account needs to voluntarily give up its privileges, such as when the security of the account is compromised.
* **Arguments:**
  * **`role`** (`bytes32`): The role to be renounced.
  * **`account`** (`address`): The address of the account that is renouncing the role.
* **Emits:** A `RoleRevoked` event indicating that the role has been renounced by the account.


# FXD

https\://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/FathomStablecoin.sol

### Overview

The FXD token adheres to the ERC-20 standard and includes additional functionalities tailored to the Fathom protocol's needs.

### ERC-20 Standard Functions

#### `name`

* **Description**: Returns the name of the token.
* **Returns**: `string` representing the token's name.

#### `symbol`

* **Description**: Returns the token symbol.
* **Returns**: `string` representing the token's symbol.

#### `decimals`

* **Description**: Returns the number of decimals the token uses.
* **Returns**: `uint8` representing the number of decimal places the token uses. This affects the granularity of the token.

#### `totalSupply`

* **Description**: Returns the total amount of FXD tokens currently in circulation.
* **Returns**: `uint256` representing the total supply of tokens.

#### `balanceOf`

* **Parameters**:
  * `account` (address): The address of the token holder.
* **Description**: Provides the balance of FXD tokens held by a specific account.
* **Returns**: `uint256` representing the number of tokens held by the specified account.

#### `transfer`

* **Parameters**:
  * `to` (address): The address of the recipient.
  * `amount` (uint256): The amount of FXD tokens to transfer.
* **Description**: Transfers a specified amount of FXD tokens from the caller's account to another address.
* **Returns**: `bool` indicating whether the transfer was successful.
* **Emits**: `Transfer` event.

#### `allowance`

* **Parameters**:
  * `owner` (address): The address of the token owner.
  * `spender` (address): The address of the spender.
* **Description**: Returns the remaining number of tokens that the spender is allowed to spend on behalf of the owner.
* **Returns**: `uint256` representing the remaining amount of tokens allowed to be spent.

#### `approve`

* **Parameters**:
  * `spender` (address): The address of the spender.
  * `amount` (uint256): The amount of FXD tokens the spender is allowed to use.
* **Description**: Approves a spender to withdraw tokens from the owner's account multiple times, up to the specified amount.
* **Returns**: `bool` indicating whether the approval was successful.
* **Emits**: `Approval` event.

#### `transferFrom`

* **Parameters**:
  * `from` (address): The address of the sender.
  * `to` (address): The address of the recipient.
  * `amount` (uint256): The amount of tokens to transfer.
* **Description**: Transfers tokens from one account to another, using an allowance mechanism.
* **Returns**: `bool` indicating whether the transfer was successful.
* **Emits**: `Transfer` event.

### Additional Functions

#### `mint`

* **Parameters**:
  * `to` (address): The address that will receive the created tokens.
  * `amount` (uint256): The amount of tokens to create.
* **Description**: Mints new FXD tokens and assigns them to the specified address, increasing the total supply. Can be called only by the `StablecoinAdapter` in the process of taking the loan.

#### `burn`

* **Parameters**:
  * `from` (address): The address from which tokens will be burned.
  * `amount` (uint256): The amount of tokens to burn.
* **Description**: Burns a specified amount of FXD tokens from a given account, reducing the total supply. Can be called only by the `StablecoinAdapter` in the process of repaying the loan.

#### `increaseAllowance`

* **Parameters**:
  * `spender` (address): The address of the spender.
  * `addedValue` (uint256): The additional amount of tokens that the spender is allowed to spend.
* **Description**: Increases the allowance that a spender has to use the caller’s tokens.
* **Returns**: `bool` indicating whether the operation was successful.

#### `decreaseAllowance`

* **Parameters**:
  * `spender` (address): The address of the spender.
  * `subtractedValue` (uint256): The amount by which to decrease the spender's allowance.
* **Description**: Decreases the allowance that a spender has to use the caller’s tokens.
* **Returns**: `bool` indicating whether the operation was successful.

### Events

#### `Transfer`

* **Emitted when**: Tokens are moved from one account to another.
* **Parameters**:
  * `from` (address indexed): The address of the sender.
  * `to` (address indexed): The address of the receiver.
  * `value` (uint256): The amount of tokens transferred.

#### `Approval`

* **Emitted when**: A spender is approved to use tokens from another account.
* **Parameters**:
  * `owner` (address indexed): The address of the token owner.
  * `spender` (address indexed): The address of the spender who is granted permission.
  * `value` (uint256): The amount of tokens the spender is allowed to use.


# LiquidationEngine

https\://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/LiquidationEngine.sol

The `LiquidationEngine` contract manages all liquidations within the protocol, providing interfaces for liquidators to initiate the liquidation process for positions that are under-collateralized.

**Functions**

* **`liquidate(bytes32 _collateralPoolId, address _positionAddress, uint256 _debtShareToBeLiquidated, uint256 _maxDebtShareToBeLiquidated, address _collateralRecipient, bytes calldata _data)`**: Allows a whitelisted liquidator to initiate the liquidation of a position. It requires the ID of the collateral pool, the address of the position, the amount of debt to be liquidated, a maximum allowable debt amount for liquidation to manage slippage, the recipient of the collateral, and additional data for the liquidation process.
* **`batchLiquidate(bytes32[] calldata _collateralPoolIds, address[] calldata _positionAddresses, uint256[] calldata _debtShareToBeLiquidateds, uint256[] calldata _maxDebtShareToBeLiquidateds, address[] calldata _collateralRecipients, bytes[] calldata datas)`**: Facilitates the batch liquidation of multiple positions in a single transaction. This method enhances efficiency in handling liquidations at scale.

**Events**

* **`LiquidationFail(bytes32 _collateralPoolId, address _positionAddress, address _liquidator, string reason)`**: Emitted when a liquidation attempt fails. It provides details about the failed operation, including the collateral pool ID, position address, liquidator, and reason for failure.


# FlashMintModule

https\://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/flash-mint/FlashMintModule.sol

The `FlashMintModule` contract facilitates the issuance of flash loans within the protocol. This contract allows borrowing a specified amount of stablecoins, executing arbitrary operations, and repaying the loan within a single transaction. It adheres to the ERC-3156 standard for flash loans.

### Storage Variables

* **`bookKeeper`** (`IBookKeeper`):
  * This variable stores the address of the `BookKeeper` contract, which is used for managing accounting and collateral within the system. It interacts with the bookkeeping functionalities to record transactions related to flash loans.
* **`stablecoinAdapter`** (`IStablecoinAdapter`):
  * This variable holds the address of the `StablecoinAdapter` contract. The adapter is used to interact with the stablecoin in a manner consistent with the internal accounting system, such as depositing or withdrawing stablecoin for flash loans.
* **`stablecoin`** (`IStablecoin`):
  * This variable represents the ERC20 stablecoin used for flash loans. It facilitates operations such as minting, transferring, and burning the stablecoin.
* **`systemDebtEngine`** (`address`):
  * A crucial contract address for managing the system’s overall debt and fee accrual. It is used primarily to settle fees or bad debt that accrues through flash loan operations.
* **`max`** (`uint256`):
  * This variable sets the maximum amount of stablecoin that can be borrowed through a single flash loan. It is important for managing liquidity and risk.
* **`feeRate`** (`uint256`):
  * The fee rate charged for taking out a flash loan. It is expressed as a percentage and calculated over the amount of the loan to generate revenue from flash loan operations.
* **`locked`** (`uint256`):
  * A reentrancy guard used to prevent reentry into critical functions such as flash loan issuance. This helps protect against certain types of exploits where recursive calls can lead to unintended consequences.
* **`flashMintWhitelist`** (`mapping(address => bool)`):
  * A whitelist of addresses that are permitted to initiate flash loans. This control mechanism ensures that only approved contracts or addresses can utilize flash loan functionality, which can be essential for maintaining system security.
* **`isDecentralizedState`** (`bool`):
  * Indicates whether the contract is operating in a decentralized mode. In a decentralized state, the contract might allow a broader set of interactions than when it is in a more controlled state.

**Flash Loan Functions**

* **`flashLoan(IERC3156FlashBorrower _receiver, address _token, uint256 _amount, bytes calldata _data)`**: Executes a flash loan. The `_receiver` must implement the `IERC3156FlashBorrower` interface. This function checks the token type, enforces the maximum loan amount, calculates the fee, mints the required stablecoin, sends it to the receiver, and expects repayment within the same transaction.
* **`bookKeeperFlashLoan(IBookKeeperFlashBorrower _receiver, uint256 _amount, bytes calldata _data)`**: Similar to `flashLoan` but interacts with receivers that handle bookkeeping entries directly. It is meant for more integrated system operations, managing loans in terms of the bookkeeping system's RAD units.

**Administrative Functions**

* **`setMax(uint256 _data)`** and **`setFeeRate(uint256 _data)`**: Set the maximum loanable amount and the fee rate for loans. The maximum is set in stablecoin units, and the fee rate is a percentage that applies to the borrowed amount.
* **`setDecentralizedStatesStatus(bool _status)`**: Toggle the operational mode between a more decentralized setting (where whitelist control might be relaxed) and a more controlled setting.
* **`addToWhitelist(address _toBeWhitelisted)`** and **`removeFromWhitelist(address _usr)`**: Manage addresses that are allowed to initiate flash loans. This is particularly relevant in a more centralized operational mode to ensure only vetted contracts or addresses can initiate loans.
* **`pause()`** and **`unpause()`**: Enable or disable the flash loan operations. This can be critical in situations where the protocol needs to be paused for upgrades or security issues.

**Utility Functions**

* **`convert()`** and **`accrue()`**: Handle internal conversions and accounting adjustments. `convert()` can be used to convert balance discrepancies into the bookkeeping system, while `accrue()` moves accrued fees to the system debt engine.
* **`refreshApproval()`**: Refresh the approval of the stablecoin to the maximum value for the stablecoin adapter, ensuring that the contract can always interact with the stablecoin as expected.

**Events**

* **`LogSetMax(uint256 _data)`**, **`LogSetFeeRate(uint256 _data)`**, and **`LogFlashLoan(address indexed _receiver, address indexed _token, uint256 _amount, uint256 _fee)`**: Log significant actions and state changes within the contract, providing transparency over flash loan parameters and administrative adjustments.
* **`LogDecentralizedStateStatus(bool _oldDecentralizedStateStatus, bool _newDecentralizedStateStatus)`**: Tracks changes in the operational mode of the contract, signaling shifts between centralized and decentralized control.
* **`LogAddToWhitelist(address indexed _user)`** and **`LogRemoveFromWhitelist(address indexed _user)`**: Document changes to the list of addresses authorized to initiate flash loans.


# PriceFeed

https\://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/price-feeders/CentralizedOraclePriceFeed.sol

The `CentralizedOraclePriceFeed` contract utilizes a centralized oracle source to fetch the latest prices of assets. It introduces a delay in price updates to mitigate the risks associated with price manipulation and flash loan attacks. The delayed price update ensures that fetched prices do not immediately affect the system, providing a buffer to detect and react to potential price anomalies.

`CentralizedOraclePriceFeed` is named centralized because it utilizes Oracle data that can be fetched from off-chain centralized sources (like Chainlink, Supra, and other oracles), not from pure onchain (DEX) data. Oracles themselves can be decentralized, and `CentralizedOraclePriceFeed` isn't responsible for the quality of the data.

#### Storage Variables

* `oracle`: Address of the centralized oracle contract (`address`). This oracle provides the latest price data.
* `accessControlConfig`: Address of the access control contract (`IAccessControlConfig`). It is used to manage roles and permissions within the contract.
* `latestPrice`: Latest fetched price information stored as `PriceInfo`, which includes the price and the timestamp of the last update.
* `delayedPrice`: The price that is currently being used by the system, delayed by a certain period defined by `timeDelay`.
* `timeDelay`: The delay period (in seconds) that determines how long fetched price data must wait before being considered valid within the system.
* `priceLife`: The duration (in seconds) for which a price is considered valid after being updated.
* `poolId`: Identifier for the specific pool or asset that this price feed pertains to.

#### Functions

* `setOracle(address _oracle)`: Updates the oracle address. This function can only be called by the owner or governance role.
* `setTimeDelay(uint256 _seconds)`: Sets the time delay for the price update. This can only be adjusted by the owner or governance role.
* `setPriceLife(uint256 _seconds)`: Sets the duration for which a price is considered valid.
* `retrivePrice()`: Fetches the latest price from the oracle and updates the price information in the contract.

#### Events

* `LogSetTimeDelay(address indexed _caller, uint256 _seconds)`: Emitted when the time delay is updated.
* `LogSetPriceLife(address indexed _caller, uint256 _second)`: Emitted when the price life duration is updated.
* `LogPeekPriceFailed(address indexed _caller, string _reason)`: Emitted if fetching the latest price fails.


# ShowStopper

https\://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/ShowStopper.sol

The `ShowStopper` contract manages the emergency shutdown of a system. It allows authorized users to trigger a shutdown to stop all essential financial operations, calculate and settle debts, and enable the redemption of collateral by users. The shutdown process ensures that the system can be gracefully wound down while protecting user assets.

#### Storage Variables

* `bookKeeper`: Reference to the `IBookKeeper` contract which handles all accounting-related operations.
* `liquidationEngine`: Reference to the `ILiquidationEngine` contract, responsible for handling the liquidation process during normal operations.
* `systemDebtEngine`: Reference to the `ISystemDebtEngine`, which manages the system's debts and surpluses.
* `priceOracle`: Reference to the `IPriceOracle` contract, providing updated asset prices.
* `live`: Boolean flag indicating if the system is active (1) or in shutdown mode (0).
* `cagedTimestamp`: Timestamp when the emergency shutdown was triggered.
* `cageCoolDown`: Cool-down period post-shutdown during which operations remain paused.
* `debt`: Total system debt recorded post-shutdown.
* `cagePrice`: Mapping of collateral types to their fixed prices set at the time of shutdown.
* `badDebtAccumulator`: Mapping tracking accumulated bad debts per collateral type.
* `totalDebtShare`: Mapping of total debt per collateral type.
* `finalCashPrice`: Final settled cash price per collateral type for redeeming stablecoins.
* `stablecoinAccumulator`: Tracks the total stablecoins deposited by users post-shutdown for later collateral redemption.
* `redeemedStablecoinAmount`: Mapping of redeemed stablecoin amounts per user per collateral type.

#### Functions

* `cage(uint256 _cageCoolDown)`: Triggers the emergency shutdown and sets the cool-down period.
* `cagePool(bytes32 _collateralPoolId)`: Locks the price of a specific collateral type at the time of shutdown.
* `accumulateBadDebt(bytes32 _collateralPoolId, address _positionAddress)`: Calculates and accumulates bad debt for a given collateral type and position.
* `finalizeDebt()`: Finalizes the total system debt after processing all positions.
* `finalizeCashPrice(bytes32 _collateralPoolId)`: Finalizes the cash price for a collateral type, determining the redemption value for stablecoins.
* `accumulateStablecoin(uint256 _amount)`: Accumulates stablecoins deposited by a user for later redemption.
* `redeemStablecoin(bytes32 _collateralPoolId, uint256 _amount)`: Allows users to redeem stablecoins for collateral based on the final cash price.
* `redeemLockedCollateral(bytes32 _collateralPoolId, address _positionAddress, address _collateralReceiver)`: Redeems the locked collateral for a position, transferring it to the specified receiver.

#### Events

* `LogCage(uint256 _cageCoolDown)`: Emitted when the emergency shutdown is triggered.
* `LogCageCollateralPool(bytes32 indexed collateralPoolId)`: Emitted when a collateral pool is locked at its cage price.
* `LogAccumulateBadDebt(bytes32 indexed collateralPoolId, address indexed positionAddress, uint256 amount, uint256 debtShare)`: Emitted when bad debt is accumulated for a position.
* `LogRedeemLockedCollateral(bytes32 indexed collateralPoolId, address indexed positionAddress, uint256 lockedCollateral)`: Emitted when locked collateral is redeemed post-shutdown.
* `LogFinalizeDebt()`: Emitted when the final system debt is calculated.
* `LogFinalizeCashPrice(bytes32 indexed collateralPoolId)`: Emitted when the final cash price for a collateral type is set.
* `LogAccumulateStablecoin(address indexed ownerAddress, uint256 amount)`: Emitted when a user's stablecoins are accumulated for redemption.
* `LogRedeemStablecoin(bytes32 indexed collateralPoolId, address indexed ownerAddress, uint256 amount)`: Emitted when stablecoins are redeemed for collateral.


# StabilityFeeCollector

https\://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/StabilityFeeCollector.sol

The `StabilityFeeCollector` is a contract responsible for collecting stability fees from various collateral pools within a FXD system. These fees are used to manage the stability of FXD by compensating for volatility in the collateral's value and ensuring the system's solvency. The contract provides functionality to calculate and accrue stability fees over time, ensuring they are consistently applied and collected.

#### Storage Variables

* `bookKeeper`: Reference to the `IBookKeeper` contract, managing the accounting of collateral and debts within the system.
* `systemDebtEngine`: Address of the contract responsible for handling system debts and stability fees accumulation.

#### Functions

* `pause()`: Pauses fee collection, preventing new fees from being accumulated.
* `unpause()`: Resumes fee collection, allowing fees to be accumulated again.
* `setSystemDebtEngine(address _systemDebtEngine)`: Updates the address of the system debt engine used for fee collection.
* `collect(bytes32 _collateralPool)`: Public function that anyone can call to trigger the collection of stability fees for a specific collateral pool. It updates the accumulated rate of fees for the pool.
* `_collect(bytes32 _collateralPoolId)`: Internal function that performs the actual calculation and collection of fees, updating the necessary state in the `bookKeeper` and collateral pool configuration.

#### Events

* `LogSetSystemDebtEngine(address indexed _caller, address _data)`: Emitted when the system debt engine address is updated.


# SystemDebtEngine

https\://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/SystemDebtEngine.sol

The `SystemDebtEngine` contract is responsible for managing the system's surplus and bad debt. It acts as the central financial manager within a FXD system, specifically designed to handle scenarios where debts become unmanageable or when excess funds are accumulated beyond what is required for the system's stability.

#### Storage Variables

* `bookKeeper`: Reference to the `IBookKeeper` contract, which handles the ledger of all financial operations within the system.
* `surplusBuffer`: The minimum amount of surplus (in RAD, 10^45) that should always be maintained in the system to cover unexpected liabilities.
* `live`: A flag indicating whether the system is active (1) or has been shut down (0).

#### Functions

* `withdrawCollateralSurplus(bytes32 _collateralPoolId, address _to, uint256 _amount)`: Allows the owner to withdraw surplus collateral from a specific collateral pool.
* `withdrawStablecoinSurplus(address _to, uint256 _value)`: Allows the owner to withdraw surplus stablecoins from the system, provided there is no outstanding bad debt and the withdrawal does not drop the balance below the surplus buffer.
* `setSurplusBuffer(uint256 _data)`: Sets the minimum surplus buffer required in the system.
* `settleSystemBadDebt(uint256 _value)`: Allows anyone to settle bad debt using the surplus funds available in the system.
* `cage()`: Can be called by the owner or a designated emergency role to shut down the system in case of a significant issue. It settles as much bad debt as possible with available funds during the shutdown.
* `pause()`: Pauses all critical functionalities of the contract, preventing state-changing operations.
* `unpause()`: Resumes all operations after a pause.

#### Events

* `LogSetSurplusBuffer(address indexed _caller, uint256 _data)`: Emitted when the surplus buffer is updated.
* `LogCage()`: Emitted when the system is shut down.


# AdminControls

https\://github.com/Into-the-Fathom/fathom-stablecoin-smart-contracts/blob/master/contracts/main/stablecoin-core/AdminControls.sol

The `AdminControls` contract provides  management capabilities for the Fathom FXD Protocol. It is designed to configure and control core components of the system, allowing administrative actions such as pausing and unpausing protocol operations, setting key contract addresses, and managing permissions.

Administrative role can be assigned to the Governance or Multisig account.

#### State Variables:

1. **bookKeeper (`address public`)**: Stores the address of the `BookKeeper` contract which manages the core accounting logic for the protocol.
2. **liquidationEngine (`address public`)**: Holds the address of the `LiquidationEngine` contract responsible for handling the liquidation processes.
3. **priceOracle (`address public`)**: References the `PriceOracle` contract which provides price feeds for the assets.
4. **positionManager (`address public`)**: Points to the `PositionManager` contract that manages user positions.
5. **systemDebtEngine (`address public`)**: Contains the address of the `SystemDebtEngine` contract managing the system’s debt situations.
6. **flashMintModule (`address public`)**: Holds the address of the `FlashMintModule` for flash loan functionalities.
7. **stablecoinAdapter (`address public`)**: References the `StablecoinAdapter` which handles interactions related to the FXD stablecoin.

#### Functions:

* **pauseProtocol (`external`)**: Pauses all core components of the protocol to halt operations.
* **unpauseProtocol (`external`)**: Resumes operations of all core components after being paused.
* **setBookKeeper (`external, address _bookKeeper`)**: Updates the address of the `BookKeeper` contract.
* **setPositionManager (`external, address _positionManager`)**: Updates the address of the `PositionManager` contract.
* **setLiquidationEngine (`external, address _liquidationEngine`)**: Updates the address of the `LiquidationEngine` contract.
* **setSystemDebtEngine (`external, address _systemDebtEngine`)**: Updates the address of the `SystemDebtEngine` contract.
* **setFlashMintModule (`external, address _flashMintModule`)**: Updates the address of the `FlashMintModule` contract.
* **setPriceOracle (`external, address _priceOracle`)**: Updates the address of the `PriceOracle` contract.
* **setStablecoinAdapter (`external, address _stablecoinAdapter`)**: Updates the address of the `StablecoinAdapter` contract.

#### Events:

* **LogPauseProtocol (`event`)**: Emitted when the protocol is paused.
* **LogUnpauseProtocol (`event`)**: Emitted when the protocol is unpaused.
* **LogSetBookKeeper (`event, address indexed newAddress`)**: Emitted when the `BookKeeper` address is updated.
* **LogSetPositionManager (`event, address indexed newAddress`)**: Emitted when the `PositionManager` address is updated.
* **LogSetLiquidationEngine (`event, address indexed newAddress`)**: Emitted when the `LiquidationEngine` address is updated.
* **LogSetSystemDebtEngine (`event, address indexed newAddress`)**: Emitted when the `SystemDebtEngine` address is updated.
* **LogSetFlashMintModule (`event, address indexed newAddress`)**: Emitted when the `FlashMintModule` address is updated.
* **LogSetPriceOracle (`event, address indexed newAddress`)**: Emitted when the `PriceOracle` address is updated.
* **LogSetStablecoinAdapter (`event, address indexed newAddress`)**: Emitted when the `StablecoinAdapter` address is updated.


# Deployments


# XDC Network

Addresses of deployed contract on XDC mainnet and Apothem testnet

## Addresses on XDC mainnet

### CollateralPoolIds

* XDC -  `0x5844430000000000000000000000000000000000000000000000000000000000`
* CGO - `0x43474f0000000000000000000000000000000000000000000000000000000000`

### Proxy Addresses

* ProxyActionsStorage: `0x4B327FD5aA9da5515Dbfd47eD51663eF774aF6cA`
* FathomStablecoin: `0x49d3f7543335cf38Fa10889CCFF10207e22110B5`
* BookKeeper: `0x6FD3f049DF9e1886e1DFc1A034D379efaB0603CE`
* PositionManager: `0x2fE84707e907eaB4C4E6a91CCe458E648be390Ae`
* ProxyWalletRegistry: `0x3b92595cbe2fC6063e696460990e69Ae4172c707`
* ProxyWalletFactory: `0xA43529Ce149924051e9A56b2BE740AEDbA4A581a`
* StablecoinAdapter: `0xE3b248A97E9eb778c9B08f20a74c9165E22ef40E`
* CollateralPoolConfig: `0x4F5Ea639600A01931B1370CDe99a7B1e7b6b8f6C`
* CollateralTokenAdapter XDC: `0x2fc7e65023aFF27FA61A573B5C8E3fDe3CE9ef79`
* XDC Vault: `0x9B4aCeFE2dB986Ca080Dc01d137e6566dBE0aA3a`
* CollateralTokenAdapter CGO: `0x30c64659AADD8C92328859A1CEE99721083A8E0f`
* CGO Vault: `0x14F2d15cdB7255A7c96973Ce54a269Ac1988cfcf`
* LiquidationEngine: `0x6Af7c469CD476aa7b5Cf5e486CfC8260814c244C`&#x20;
* StabilityFeeCollector: `0x00f093e0E188dA1711a18fd5BF7468aea706888C`
* SystemDebtEngine: `0xe8ede47d96757FB872fe5Fea1ba3C5AF39eC2246`
* PriceOracle: `0xF557fBf34B785b157344167fE0D9bAb95da06843`
* DelayFathomOraclePriceFeed: `0x5dE248bbD0ae9E846B8dBa12960fc3524Fb37a88`
* CentralizedOraclePriceFeed XDC `0xB7Bcc2A1B1bD61469b3c4dA32a76CA7E39fE8ac2`
* FathomPriceOracle XDC `0xFd129c0cb51F4e245eA4A326847489E06822D1A2`
* CentralizedOraclePriceFeed CGO `0xf00EB5361eabF8d9e77B5A83682B681590B0B96c`
* FathomPriceOracle CGO `0x2429cD19Df47cF550D0b45884B83688A172B5b49`
* AccessControlConfig: `0x2cD89769a2D9d992790e76c6A9f55c39fdf2FDc2`
* FlashMintModule: `0xAa72C35f09E0bABBAF78DD8ccEeEA3F5a54E7664`
* FlashMintArbitrager: `0x25464a1Cf25D1b180a36417fAB9FFd9960627860`
* BookKeeperFlashMintArbitrager `0xf3D403DA1C8368Ce164dDA5bd316d582aC457a35`
* StableSwapModule: `0x42c06188B8C03769A1F73B3f31b259271ee3B981`
* ShowStopper: `0x574651A152C5a14FaA88D556E09A48DF2713C1e8`
* AdminControls: `0x32A5f5D0BdB48E0A3A79ec21364e2F9f3f6a23c5`

### `Addresses W/O proxy pattern`

* FixedSpreadLiquidationStrategy: `0xfe5037504E0EF5eC2DfBEEA03f9d9cB43580EF23`
* ProxyAdminAddress: `0xb82AD475fc113671840D510B60Cbae5630a07f3B`
* ProxyFactory: `0x0acf88Ba60561372Ef93a67E04e1A55d9fC1D910`
* FathomStablecoinProxyActions: `0xD55eE8eC9FE218E2e4a981D2273db5d6d83c3141`


# User Guides


# Open FXD position

To open an FXD position, follow the steps below:

* Go to Fathom [DApp](https://dapp.fathom.fi/).
* Connect your Web3 wallet (such as [MetaMask](https://metamask.io/)) and make sure your network is set to the intended chain (i.e., [XDC](https://chainlist.org/chain/50)).

<div data-full-width="true"><figure><img src="/files/PNZ3hkodmgXBp1mfanF7" alt=""><figcaption></figcaption></figure></div>

* Select your desired collateral pool in "**Available Pools"**.
* Click "**Open Position**"

<div data-full-width="true"><figure><img src="/files/OFO8oYQ0vxo1dW3eYFaM" alt=""><figcaption></figcaption></figure></div>

* Enter the amount you would like to provide as collateral.
* Enter the amount of FXD you would like to borrow.
  * You can also click "**Safe Max**" to borrow the maximum amount of FXD that can be considered relatively safe at the current moment.
  * Note that when you take out an FXD loan, during market volatility for your collateral assets, you should monitor the Safety Buffer because if it drops to 0 and lower, your position may be liquidated.
* Click "**Open this Position**"
  * If this is your first time opening an FXD position:
    * The first transaction will be the creation of proxy wallet. Only the second transaction will be the position opening itself.
    * You may be required to approve the collateral transfer before the actual transfer (depending on the collateral type).
  * Sign and send the transaction in your Wallet.
  * Wait for the transaction to be processed.
  * Once the transaction has gone through, you'll see your FXD position in "**Your Positions"** on the same page below "**Available Pools"**.

<div data-full-width="true"><figure><img src="/files/GQWaxBuDGtpcd7tJc4oz" alt=""><figcaption></figcaption></figure></div>


# Top Up FXD Position

You can use the **Manage Position** functionality to **Top Up Position.** This may be done to **manage the position risk**, or to **borrow more FXD**.

* Go to Fathom [DApp](https://dapp.fathom.fi/).
* Connect your Web3 wallet (such as [MetaMask](https://metamask.io/)) and make sure your network is set to the intended chain (i.e., [XDC](https://chainlist.org/chain/50)).
* Opened positions are shown in "**Your Positions"**. Click "**Manage Position"** on the position you want to top up.

<div data-full-width="true"><figure><img src="/files/Oe18mUBdVXTjrJLIFTNf" alt=""><figcaption></figcaption></figure></div>

* Enter the amount of collateral you would like to add to position.
* If you want to borrow more FXD - enter the amount of it.
  * You can also click "**Safe Max**" to borrow the maximum amount of FXD that can be considered relatively safe at the current moment.
  * Note that when you take out an FXD loan, during market volatility for your collateral assets, you should monitor the Safety Buffer because if it drops to 0 and lower, your position may be liquidated.

<div data-full-width="true"><figure><img src="/files/IPkBouVT6DoewHRZUvNa" alt=""><figcaption></figcaption></figure></div>

* Click "**Open this Position**"
  * You may be required to approve the collateral transfer before the actual transfer (depending on the collateral type and previously approved value).
  * Sign and send the transaction in your Wallet.
  * Wait for the transaction to be processed.
  * Once the transaction has gone through, you'll see your adjusted FXD position in "**Your Positions"** on the same page below "**Available Pools"**.

<figure><img src="/files/RBgDYoqRG5RiWBM4THk8" alt=""><figcaption></figcaption></figure>


# Repay and close FXD position

You can use the **Manage Position** functionality to **Repay** and **Close Position.** This may be done to **manage the position risk**.

* Go to Fathom [DApp](https://dapp.fathom.fi/).
* Connect your Web3 wallet (such as [MetaMask](https://metamask.io/)) and make sure your network is set to the intended chain (i.e., [XDC](https://chainlist.org/chain/50)).
* Opened positions are shown in "**Your Positions"**. Click "**Manage Position"** on the position you want to close.

<div data-full-width="true"><figure><img src="/files/Oe18mUBdVXTjrJLIFTNf" alt=""><figcaption></figcaption></figure></div>

* Enter the amount of FXD you would like to repay.
* The amount of collateral that you receive is calculated automatically. If you want to keep some collateral - enter the amount of it.

<figure><img src="/files/U1TtNIOcvqyMyHjgYvX1" alt=""><figcaption></figcaption></figure>

* Click "**Repay this Position**"
  * You may be required to approve the FXD transfer before the actual transfer (depending on the previously approved value).
  * Sign and send the transaction in your Wallet.
  * Wait for the transaction to be processed.
  * Once the transaction has gone through, you'll see your adjusted FXD position in "**Your Positions"** on the same page below "**Available Pools"**. If you take back all collateral, your position will disappear from the list.

<figure><img src="/files/RBgDYoqRG5RiWBM4THk8" alt=""><figcaption></figcaption></figure>


# Vaults

Fathom Vaults is a cutting-edge financial platform that leverages blockchain technology to offer optimized asset management solutions. Built on a robust and secure framework, Fathom Vaults allows users to participate in a variety of investment strategies that not only include traditional DeFi protocols but also extend into Real-World Assets (RWA) and Trade Finance. Central to the ecosystem is the [FXD stablecoin](/fxd-stablecoin), a stable digital currency that provides a stable medium of exchange and a store of value across various investment strategies.


# Key Features

* **Dynamic Investment Strategies:** Engage in multiple investment strategies spanning decentralized finance, real-world assets, and trade finance. These strategies are designed to cater to different risk appetites and investment goals.
* **Stablecoin Integration:** Utilize the FXD stablecoin within the platform, the stable asset, to gain yields in on-chain native way.
* **Decentralized Governance:** Fathom Vaults operates under a community-driven Fathom governance model, allowing FXD holders to vote on key decisions, including strategy approvals and fee adjustments.
* **Security and Transparency:** Smart contracts are publicly auditable and have undergone rigorous security audits. Transparency in fee structure and strategy performance metrics is maintained to ensure trust and accountability.
* **Accessibility and Integration:** Designed with a focus on user experience, Fathom Vaults offers easy integration options for third-party services and developers, providing detailed documentation and access to on-chain data.


# Definitions

### Vault

Specialized smart contract on the blockchain that manages pooled user funds. Each vault can be connected to various investment strategies, automated by the corresponding strategy contracts. Vaults are compliant to [ERC-4626](https://ethereum.org/en/developers/docs/standards/tokens/erc-4626/).

### Strategy

A strategy within Fathom Vaults is a self-contained smart contract designed to maximize returns from assets held within a vault. Strategy allows seamlessly manage the vault's assets by deploying them into optimized yield-generating opportunities.

### Tokenized Strategy

In the Fathom Vaults ecosystem, a Tokenized Strategy is a specialized form of a strategy that doubles as an independent vault. Compliant with the ERC-4626 standard, this setup not only facilitates yield generation but also allows users to directly invest in the strategy. Upon investment, individuals receive shares that represent their stake, enabling a straightforward way to participate in specific investment strategies without intermediaries.

### Factory

The Vaults Factory is a core component deployed to streamline the creation of Allocator Vaults under Fathom Governance. This factory ensures that new vaults are deployed in a standardized, efficient, and secure manner, adhering to the latest protocols and specifications set forth by the governance. This setup promotes trust and consistency across all deployments, significantly simplifying the process of launching new investment vehicles on the platform.

### **Debt**

Funds sent from a vault to a strategy intended to generate returns.

### **Report**

A function where a vault accounts for the performance of its strategies, applying any relevant fees, and managing profit distribution.


# Architecture

At the core of Fathom Vaults' architecture are the smart contracts that handle vault operations, strategy implementation, and interactions with the FXD stablecoin. Here is a simplified view of the system:

1. **User Interface (UI):** Web3 compatible interfaces that allow users to interact with vaults, deposit and withdraw funds, and participate in governance.
2. **Smart Contracts:**
   * **Vault Contracts:** Manage the deposits, withdrawals, and allocation of funds to various strategies.
   * **Strategy Contracts:** Execute specific investment protocols, manage performance, and handle rewards distribution.
   * **Governance Contracts:** Facilitate voting and administrative functions driven by community governance.
3. **Off-Chain Data Storage:** Utilizes Graph Node and Subgraphs for indexing and querying blockchain data efficiently, enhancing the responsiveness and scalability of the platform.
4. **Off-Chain Services:** The Reports Processor automates the report processing for vault strategies. Monitoring & Risk Management AI Agents and Monitoring Systems bring more reliability and capital efficiency to the vaults and strategies.
5. **API Gateway:** Offers a seamless connection between the frontend and smart contracts, facilitating data flow and transaction execution across the platform.
6. **FXD Stablecoin:** FXD is the backbone of the Fathom Vaults ecosystem, designed to mitigate price volatility and provide a reliable medium of exchange. Vaults allow FXD holders to invest in various on-chain and off-chain products leveraging their portfolio.
7. **AI Agents:** They work for users and vault managers. On the user side, they allow users to structure the vaults' portfolio. For vault managers, they offer help structuring the strategies' allocations.

<figure><img src="/files/RjnYJm2ofKyV9rXuGt69" alt=""><figcaption><p>Architecture</p></figcaption></figure>


# Fees

Fathom Vaults have *Protocol Fees*, and *Performance Fees*. These fees are taken each time a vault or strategy reports gains, effectively ensuring that the ecosystem is sustainable and that the developers, as well as the infrastructure maintainers, are compensated for their contributions.

**Control and Customization**

The Fathom governance model empowers vault and strategy managers with autonomy over the fee mechanisms. They can determine the extent of fees charged, which provides an incentive structure aligned with the success of their strategies. At the same time, it offers rewards to the Fathom platform for providing the foundational infrastructure utilized by these financial instruments.

**Governance and Fee Settings**

The protocol fees are governed and adjustable through Fathom Governance, with the possible range set from 0% to 50%. This wide range allows for significant flexibility in adjusting to market conditions and strategy performance. Additionally, Fathom Governance possesses the capability to specify custom fee settings for individual vaults and strategies, enabling a tailored approach to fee imposition based on specific needs and circumstances.

**Fee Distribution Example**

To illustrate, consider a scenario where a strategy yields a profit of 100 FXD:

* **Performance Fee**: 20%
* **Protocol Fee**: 10% of the Performance Fee

Calculations:

* **Total Fees**: 100 FXD \* 20% = 20 FXD
* **Protocol Fees**: 20 FXD \* 10% = 2 FXD
* **Performance Fees**: 20 FXD - 2 FXD = 18 FXD

In this example, 18 FXD is allocated to the strategy managers or the specified recipients of the performance fees, while 2 FXD is directed to the Fathom Treasury to support ongoing development and maintenance.


# Workflows

Fathom Vaults are designed to streamline and enhance the experience for both users (investors), vault and strategy managers. Here's an overview of the typical workflows for each type of participant:

**User (Investor) Workflow**

1. **Account Setup**: Users begin by connecting their wallet to the Fathom interface. This setup involves ensuring that they hold FXD, the native stablecoin of the Fathom ecosystem, which is used for transactions within the vaults.
2. **Vault Selection**: Users navigate through the available vaults, each tailored to different risk preferences and investment strategies. The vaults are transparently described regarding their strategies, historical performance, and risk levels.
3. **Deposit**: Once a suitable vault is selected, users can deposit their FXD into the vault. This transaction involves transferring FXD from their personal wallets into the vault’s contract, where the FXD is then utilized according to the vault’s specific strategy.
4. **Yield Generation**: After the deposit, the vault automatically employs the user's FXD in various DeFi, RWA, or TradeFinance strategies based on the predefined rules of the vault. These strategies are designed to optimize returns while considering risk management.
5. **Earnings and Reports**: Users can track the performance of their investments through the dashboard that provides real-time data on earnings and the overall health of the vault. Periodic reports and alerts can also be configured for active monitoring.
6. **Withdrawal**: At any point, users can choose to withdraw their principal along with any returns generated, subject to the terms of the vault such as lock-up periods and withdrawal fees. The withdrawal process is straightforward, crediting the FXD back into the user’s wallet.

**Vault and Strategy Manager Workflow**

1. **Strategy Deployment**: Vault manager can be develops and deployers of the strategies within the Fathom ecosystem. These strategies might involve a mix of yield farming, lending protocols, or investment in real-world assets.
2. **Vault Configuration**: Once a strategy is ready, it is integrated into a vault. Managers configure the vault settings, including fees, risk management rules, and performance targets.
3. **Capital Management**: The primary role of the vault manager is to manage the capital pooled in the vault effectively. This involves deciding how much capital to allocate to different investments and managing the liquidity to meet withdrawal demands.
4. **Performance Monitoring and Adjustment**: Managers continuously monitor the performance of the vault and make necessary adjustments to the strategy to maximize returns and minimize risks. This might include rebalancing the portfolio, harvesting yields, and pivoting strategies based on market conditions.
5. **Reporting and Communication**: It is crucial for managers to maintain transparency with the investors. This involves regular updates on vault performance, upcoming changes or proposals, and any significant market movements that may affect the vault.
6. **Fee Collection and Reinvestment**: Managers collect performance-based fees as compensation for managing the vault. These fees are a percentage of the profits generated and are automatically deducted from the returns. Managers may also reinvest a portion of their earnings back into the vault to align their interests with those of the investors.

<figure><img src="/files/dbYgJ0aY5CY2CJsunJX2" alt=""><figcaption><p>Workflows</p></figcaption></figure>


# Vault Management

Fathom Vaults are designed to be straightforward and accessible to anyone with a vision for creating effective investment strategies. Unlike traditional systems that may centralize management, Fathom democratizes the ability to deploy, manage, and derive earnings from personalized vault configurations.

**Deployment**

Each vault version comes with its own Factory deployed for easy and secure vault deployment. To deploy a vault, interact with the factory using the `deployVault` method, which clones a pre-existing vault setup, ensuring consistency and reliability.

**Setup**

Post-deployment, you can customize your vault's settings:

* **Roles**: Define roles for different operational aspects of your vault. You can assign roles like strategy addition, debt management, and profit reporting.
* **Deposit Limits**: Initially set to zero, you'll need to configure this to start accepting deposits.

**Strategy Management**

Vaults manage debt among various strategies that generate yields.

* **Add Strategy**: Integrate new strategies to allocate funds.
* **Update Strategy**: Adjust strategy settings, including maximum debt limits.
* **Revoke Strategy**: Safely remove strategies that no longer align with the vault’s objectives.

**Running the Vault**

Operate your vault with simplicity:

* **Debt Allocation**: Manage how funds are distributed among strategies.
* **Reporting**: Regularly update the vault on strategy performance, capturing gains or losses and handling fee applications.
* **Profit Distribution**: Manage how and when profits are distributed to shareholders.

**Customization**

Enhance your vault’s functionality with additional features:

* **Accountant**: Attach custom fee logic.
* **Deposit/Withdraw Modules**: Customize rules for fund flows.
* **Queue Management**: Optimize strategy execution order.


# Strategy Creation

Creating and managing a tokenized strategy in the Fathom ecosystem involves a few critical functions. Below, we detail the essential functions your strategy must implement, focusing on asset deployment, yield optimization, and operational functions for comprehensive management.

### Inheriting from `BaseStrategy`

`BaseStrategy` implements all of the required functionality to seamlessly integrate with the `TokenizedStrategy` implementation contract allowing anyone to easily build a fully permissionless ERC-4626 compliant Strategy by inheriting this contract and overriding three simple functions.

### Storage Variables

In the context of the `BaseStrategy`, there are a couple of built-in global variables that you will frequently access:

* `asset`: This variable represents the ERC-20 token that your strategy will use as the primary asset for operations like deposits, withdrawals, and yield generation.
* `TokenizedStrategy`: This variable refers to the interface or instance of the strategy that includes core functions and state variables necessary for the strategy's operation.

If your strategy requires additional data or needs to check on operational states, you can access these through the `TokenizedStrategy` variable. It provides access to various states like `totalAssets` managed by the strategy.

### Must Override Functions

#### 1. **`_deployFunds(uint256 _amount)`**

**Purpose**

This function manages the deployment of the underlying asset into a yield-generating protocol each time a deposit is made into the strategy. It's responsible for ensuring that new deposits, as well as any funds previously not deployed, are effectively put to work to generate yield.

**Parameters**

* **`_amount`**: Represents the total quantity of the underlying assets that are available to be deployed. This includes both the new deposits and any funds that were previously idle within the strategy.

**Behavior and Considerations**

* **Permissionless**: This function can be called without specific permissions, which means the operations (like swaps or LP staking) can be initiated by any entity. This open access requires careful management to prevent manipulation.
* **Partial Deployment**: The strategy can choose not to deploy all available funds depending on its needs or conditions in the underlying protocols.

#### 2. **`_freeFunds(uint256 _amount)`**

**Purpose**

This function is invoked when there is a need to withdraw funds from the yield source, typically triggered by a user's withdrawal request from the strategy.

**Parameters**

* **`_amount`**: The amount of the underlying asset required to be liquidated from the yield source to meet withdrawal requests.

#### 3. **`_harvestAndReport()`**

**Purpose**

This function is central to the strategy's operational cycle, called periodically to manage the harvesting of rewards, reinvestment, and the reporting of the strategy's performance.

**Returns**

* **`_totalAssets`**: Provides a verified total of the strategy’s assets, including those deployed and idle, ensuring accurate performance tracking and fee calculation.

**Behavior and Considerations**

* **Permissioned**: Unlike other functions, this one is permissioned to ensure only authorized addresses can execute it, safeguarding against unauthorized or harmful actions.
* **Comprehensive Asset Accounting**: It is crucial for this function to accurately account for all assets to ensure correct profit, loss, and fee calculations.

### Optional Override Functions <a href="#optional-functions" id="optional-functions"></a>

While overriding the primary functions in a strategy ensures basic compliance and operational capability, incorporating additional optional functions allows for more detailed control and customization of the strategy's behavior. These functions are instrumental for strategies seeking greater flexibility and complexity in managing asset interactions and operational constraints.

#### **1. `availableDepositLimit (address _owner)`**

* **Purpose**: Restricts the amount that can be deposited based on strategic constraints or protocol requirements.
* **Parameter**: `_owner` is the depositor's address.
* **Returns**: The maximum allowable deposit amount.
* **Usage**: Enforce deposit limits or maintain a whitelist. Defaults to `uint256 max`, meaning no limit unless specified.
* **Best Practice**: Implement logic to check protocol limits or system status to automatically adjust deposit capabilities.

#### **2. `availableWithdrawLimit (address _owner)`**

* **Purpose**: Limits the amount that can be withdrawn, useful for managing liquidity or protocol constraints.
* **Parameter**: `_owner` refers to the shareholder.
* **Returns**: The permissible withdrawal amount.
* **Usage**: This function is crucial for strategies that may have illiquid positions or need to manage large withdrawals carefully. It defaults to `uint256 max`, allowing for maximum flexibility unless specifically limited.
* **Best Practice**: Override to set limits based on current strategy liquidity or operational requirements.

#### **3. `_tend (uint256 _totalIdle)`**

* **Purpose**: Allows for periodic maintenance or adjustments of the strategy's assets without a full report.
* **Parameter**: `_totalIdle` represents the amount of idle assets available.
* **Returns**: None.
* **Usage**: Ideal for strategies that require regular adjustments to maintain optimal investment positions or leverage levels.
* **Best Practice**: Use this function to adjust positions based on market conditions or internal strategy targets.

#### **4. `_tendTrigger ()`**

* **Purpose**: Indicates whether it's appropriate to perform a tend operation.
* **Returns**: A boolean indicating whether a tend operation should be initiated.
* **Usage**: Acts as a check to ensure that tend operations are called when necessary, based on specific strategy conditions or thresholds.
* **Best Practice**: Implement logic that assesses current market conditions, strategy performance, or asset allocations to decide the necessity of a tend operation.

#### **5. `_emergencyWithdraw (uint256 _amount)`**

* **Purpose**: Facilitates the withdrawal of funds in emergency situations, particularly after a strategy shutdown.
* **Parameter**: `_amount` specifies how much of the underlying asset to withdraw.
* **Returns**: None.
* **Usage**: Critical for withdrawing funds when a strategy has been halted due to significant issues or for decommissioning.
* **Best Practice**: Ensure that the logic is straightforward and failsafe to prevent complications during emergency operations.

These optional functions provide strategists with the tools to fine-tune their strategy's interaction with underlying assets, offering flexibility to adapt to a variety of operational scenarios and market conditions.

### Reporting

A critical operational process for strategists is the regular reporting of strategy performance. Reporting must be initiated by authorized addresses, specifically those designated as 'management' or 'keeper'. The `report` function is instrumental in aggregating accrued rewards, documenting any profits or losses, and managing the assessment and distribution of fees. This function underpins the yield generation for vault depositors and the fee accrual for strategists.

Strategies should be designed with the expectation that reporting occurs at intervals defined by the strategy’s specific `profitMaxUnlockTime`. This setup ensures that the strategy remains aligned with its yield targets and operational metrics.

`_harvestAndReport` is the primary function called during a report; it is pivotal for collecting rewards and recalibrating strategy assets and positions. Strategies that require more frequent operational checks or adjustments should implement and utilize `_tend` and `tendTrigger` functions to handle necessary actions between reports.

### Setters

Strategies come equipped with several modifiable parameters that management can adjust as needed:

* **Changing Management**: To change the strategy's management, initiate a two-step process. First, the existing management should invoke `setPendingManagement(address)` with the new management address. Subsequently, the new address must call `acceptManagement()` to finalize the transfer.
* **Keeper**: The strategy manager has the ability to designate a new keeper by calling `setKeeper(address)`.
* **Emergency Admin**: Initially set to `address(0)`, the emergency admin can be updated by management using `setEmergencyAdmin(address)`.
* **Performance Fee**: The management can modify the performance fee rate, which is applied to gains during reporting, using `setPerformanceFee(uint16)`. This setting adheres to defined minimum and maximum limits.
* **Performance Fee Recipient**: Assign the recipient of the performance fees by calling `setPerformanceFeeRecipient(address)`.
* **Profit Unlocking Period**: Profits are gradually released to depositors over a period defined by `profitMaxUnlockTime`, which defaults to 10 days but can be adjusted by the strategist with `setProfitMaxUnlockTime(uint256)`.

### Emergencies

Strategies incorporate two primary emergency functions:

* **Shutdown Strategy**: Executable only by the management or emergency admin, this irreversible function halts new deposits and mints. However, it allows other operations such as withdrawals, redemptions, reports, and tending to continue, enabling ongoing profit and loss documentation and allowing users to access their funds post-shutdown. This function can be utilized in critical situations or to decommission a vault.
* **Emergency Withdraw**: Upon strategy shutdown, management or the emergency admin may activate `emergencyWithdraw(uint256 _amount)` to extract a specified amount from the yield source and retain it within the vault in an idle state.

These emergency measures, along with any additional custom functions, are crucial tools for strategists to manage urgent scenarios effectively.


# Interfaces


# Factory

https\://github.com/Into-the-Fathom/fathom-vaults-smart-contracts/blob/master/contracts/factory/packages/FactoryPackage.sol

[`Factory`](https://github.com/Into-the-Fathom/fathom-vaults-smart-contracts/blob/master/contracts/factory/Factory.sol) is proxy, and its implementation is [`FactoryPackage`](https://github.com/Into-the-Fathom/fathom-vaults-smart-contracts/blob/master/contracts/factory/packages/FactoryPackage.sol).

The `FactoryPackage` contract is responsible for managing and deploying vaults with specific configurations. It maintains control over the vault's deployment template, fee structure, and also tracks all deployed vaults.

### **State Variables:**

* `vaultPackage`: Address of the vault package used as the template for deploying new vaults.
* `feeRecipient`: Address where collected fees are sent.
* `feeBPS`: Basis points for calculating fees on transactions.
* `vaults`: Dynamic array storing addresses of all vaults deployed by this factory.
* `vaultCreators`: Mapping from vault address to the creator's address.

### Set Functions

#### **`updateVaultPackage`**

* **Arguments**:
  * `_vaultPackage`: New address for the vault package to update the template for future vault deployments.

#### **`updateFeeConfig`**

* **Arguments**:
  * `_feeRecipient`: New address for receiving the fees collected from the operations.
  * `_feeBPS`: New basis points for the fee, updating how the fee percentage is calculated.

#### **`deployVault`**

* **Arguments**:
  * `_profitMaxUnlockTime`: The maximum time over which profits are unlocked in the deployed vault.
  * `_assetType`: Type identifier of the asset, useful for handling different asset behaviors or requirements.
  * `_asset`: Address of the asset (usually a token) that the vault will manage.
  * `_name`: Human-readable name of the vault for identification.
  * `_symbol`: Symbol of the vault's token.
  * `_accountant`: Address of the accountant contract that manages fee assessments and other accounting tasks for the vault.
  * `_admin`: Address that will have administrative privileges over the newly created vault.

### Read Functions

#### **`getVaults`**

* **Returns**: An array of addresses representing all vaults that have been deployed by this factory.

#### **`getVaultCreator`**

* **Arguments**:
  * `_vault`: The address of the vault for which the creator's address is queried.
* **Returns**: The address of the creator who initially deployed the specified vault.

#### **`protocolFeeConfig`**

* **Returns**: A tuple containing the current fee basis points (`uint16`) and the address of the fee recipient. This provides a quick overview of how fees are being handled by the factory.

### **Events:**

#### **`VaultPackageUpdated`**

* **Parameters**:
  * `vaultPackage` (`address indexed`): Emitted when the vault package address is updated.

#### **`FeeConfigUpdated`**

* **Parameters**:
  * `feeRecipient` (`address indexed`): Emitted when the fee recipient address is updated.
  * `feeBPS` (`uint16 indexed`): Emitted when the fee percentage basis points are updated.

#### **`VaultDeployed`**

* **Parameters**:
  * `vault` (`address indexed`): Address of the newly deployed vault.
  * `profitMaxUnlockTime` (`uint32 indexed`): Profit unlock time for the vault.
  * `asset` (`address indexed`): Asset managed by the vault.
  * `name` (`string`): Name of the vault.
  * `symbol` (`string`): Symbol of the vault’s token.
  * `accountant` (`address`): Accountant contract address.
  * `admin` (`address`): Admin address with privileges over the vault.


# Vault

https\://github.com/Into-the-Fathom/fathom-vaults-smart-contracts/blob/master/contracts/vault/packages/VaultPackage.sol

[`FathomVault`](https://github.com/Into-the-Fathom/fathom-vaults-smart-contracts/blob/master/contracts/vault/FathomVault.sol) is proxy, and its implementation is [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-vaults-smart-contracts/blob/master/contracts/vault/packages/VaultPackage.sol).

The `VaultPackage` serves as the template for creating and managing vaults within the Fathom ecosystem. It supports a variety of operations including asset management, strategy implementation, and fee assessment in an efficient and secure manner.

### **State Variables**

* **profitMaxUnlockTime** (`uint256`): Maximum time over which profits from the vault are unlocked.
* **assetContract** (`ERC20`): ERC20 token contract address of the vault's primary asset.
* **decimalsValue** (`uint8`): Decimal precision of the vault's primary asset.
* **sharesName** (`string`): Name of the token shares issued by the vault.
* **sharesSymbol** (`string`): Symbol of the token shares issued by the vault.
* **factory** (`address`): Address of the factory contract that deployed the vault.
* **accountant** (`address`): Address of the accountant contract responsible for managing the vault's fee assessments.
* **assetType** (`uint256`): Type identifier for the asset, addressing specific behaviors or requirements.
* **defaultQueue** (`address[]`): The default strategy queue used for managing assets.
* **useDefaultQueue** (`bool`): Flag determining if the default strategy queue is always used.
* **depositLimit** (`uint256`): Maximum amount of assets that can be deposited into the vault.
* **depositLimitModule** (`address`): Address of the contract handling dynamic deposit limits.
* **withdrawLimitModule** (`address`): Address of the contract handling dynamic withdrawal limits.
* **minimumTotalIdle** (`uint256`): Minimum amount of total idle assets required in the vault.
* **strategies** (`mapping(address => StrategyParams)`): Mapping of strategy addresses to their operational parameters.

### Set Functions

#### **`setAccountant`**

* **Arguments**:
  * `newAccountant` (`address`): Address of the new accountant contract.

#### **`setDefaultQueue`**

* **Arguments**:
  * `newDefaultQueue` (`address[] calldata`): Array of strategy addresses to update the default queue.

#### **`setUseDefaultQueue`**

* **Arguments**:
  * `_useDefaultQueue` (`bool`): New boolean value to set the use of the default queue.

#### **`setDepositLimit`**

* **Arguments**:
  * `_depositLimit` (`uint256`): New deposit limit for the vault.

#### **`setDepositLimitModule`**

* **Arguments**:
  * `_depositLimitModule` (`address`): Address of the new deposit limit module.

#### **`setWithdrawLimitModule`**

* **Arguments**:
  * `_withdrawLimitModule` (`address`): Address of the new withdrawal limit module.

#### **`setMinimumTotalIdle`**

* **Arguments**:
  * `_minimumTotalIdle` (`uint256`): New minimum total idle assets for the vault.

#### **`setProfitMaxUnlockTime`**

* **Arguments**:
  * `_newProfitMaxUnlockTime` (`uint256`): New maximum time for profit unlocking.

#### **`addStrategy`**

* **Arguments**:
  * `newStrategy` (`address`): Address of the new strategy to add to the vault.

#### **`revokeStrategy`**

* **Arguments**:
  * `strategy` (`address`): Strategy address to revoke.
  * `force` (`bool`): Flag to force revocation, potentially incurring losses.

#### **`updateMaxDebtForStrategy`**

* **Arguments**:
  * `strategy` (`address`): Strategy address to update.
  * `newMaxDebt` (`uint256`): New maximum debt for the strategy.

#### **`shutdownVault`**

Shuts down the vault, preventing new deposits and initiating asset liquidation processes.

### Read Functions

#### **`getDebt`**

* **Arguments**:
  * `strategy` (`address`): Strategy address to query the current debt.
* **Returns**: Current debt amount for the specified strategy.

#### **`totalSupply`**

Returns the total supply of shares issued by the vault.

#### **`totalAssets`**

Returns the total assets managed by the vault, including both idle assets and those engaged in strategies.

#### **`unlockedShares`**

Returns the number of shares that have been unlocked based on the vault's profit unlocking schedule.

#### **`pricePerShare`**

Returns the current price per share of the vault, based on the underlying asset value.

### Events

#### **`UpdatedAccountant`**

* **Parameters**:
  * `newAccountant` (`address`): Address of the updated accountant.

#### **`UpdatedDefaultQueue`**

* **Parameters**:
  * `newDefaultQueue` (`address[]`): Updated array of strategy addresses for the default queue.

#### **`UpdatedUseDefaultQueue`**

* **Parameters**:
  * `_useDefaultQueue` (`bool`): Updated flag state for using the default queue.

#### **`UpdatedDepositLimit`**

* **Parameters**:
  * `_depositLimit` (`uint256`): New deposit limit set for the vault.

#### **`UpdatedDepositLimitModule`**

* **Parameters**:
  * `_depositLimitModule` (`address`): Address of the newly set deposit limit module.

#### **`UpdatedWithdrawLimitModule`**

* **Parameters**:
  * `_withdrawLimitModule` (`address`): Address of the newly set withdrawal limit module.

#### **`UpdatedMinimumTotalIdle`**

* **Parameters**:
  * `_minimumTotalIdle` (`uint256`): New minimum total idle assets set for the vault.

#### **`UpdatedProfitMaxUnlockTime`**

* **Parameters**:
  * `_newProfitMaxUnlockTime` (`uint256`): New maximum time for unlocking vault profits.


# BaseStrategy

https\://github.com/Into-the-Fathom/fathom-vaults-smart-contracts/blob/master/contracts/strategy/BaseStrategy.sol

The `BaseStrategy` provides a foundation for creating ERC-4626 compliant vaults, which integrate seamlessly with a `TokenizedStrategy` implementation contract. This structure allows for ease in developing customizable strategies while maintaining a consistent interface and functionality through delegation.

### **Modifiers**

* **onlySelf**: Ensures that the function is called internally by the strategy itself, typically to confirm actions are a result of delegate calls from the strategy to the `TokenizedStrategy`.
* **onlyManagement**: Verifies that the caller is authorized under the strategy’s management role, controlling strategy operational parameters.
* **onlyKeepers**: Restricts function access to authorized keepers or management, facilitating routine maintenance and operational tasks.
* **onlyEmergencyAuthorized**: Limits access to emergency functions to addresses with emergency authorization, enhancing security and control in crisis situations.

### **Immutable Variables**

* **tokenizedStrategyAddress**: Address of the `TokenizedStrategy` implementation used across all strategies for handling logic and storage.
* **TokenizedStrategy**: A reference to the `TokenizedStrategy` instance, treating the strategy as if it’s a library for internal function calls.
* **asset**: The ERC20 token that the strategy operates on, used for yield-generating activities.

### **Functions to Override**

* **\_deployFunds(uint256 \_amount)**: Handles the deployment of specified amounts of the asset into yield-generating positions.
* **\_freeFunds(uint256 \_amount)**: Designed to release funds from investment positions, adjusting the strategy’s asset allocation.
* **\_harvestAndReport()**: Gathers yield and rebalances the strategy’s assets to reflect the actual holdings accurately.

### **Optional Functions to Override**

* **\_tend(uint256 \_totalIdle)**: Manages the strategy’s assets between reporting periods, optimizing yield generation and position management.
* **\_tendTrigger()**: Indicates whether the `_tend` function should be invoked, based on specific strategy conditions or thresholds.

### **TokenizedStrategy Integration**

* **deployFunds(uint256 \_amount)**: Delegates fund deployment to the `TokenizedStrategy`, allowing it to handle the specifics of asset investment.
* **freeFunds(uint256 \_amount)**: Delegates the release of funds to the `TokenizedStrategy`, ensuring that withdrawal requests are honored efficiently.
* **harvestAndReport()**: Provides an accurate and updated accounting of the strategy’s total assets, delegating reporting to the `TokenizedStrategy`.

### **Strategy Management and Maintenance**

* **tendThis(uint256 \_totalIdle)**: Facilitates the active management of the strategy’s resources, optimizing asset allocation and performance.
* **shutdownWithdraw(uint256 \_amount)**: Allows for the strategic withdrawal of funds in emergency scenarios, managed through the `TokenizedStrategy` to ensure consistency and reliability.

### **Security and Delegation Features**

* **\_delegateCall(bytes memory \_calldata)**: Facilitates direct interactions with the `TokenizedStrategy` by forwarding calls and handling returned data or errors.
* **fallback()**: Ensures all unspecified calls or data sent to the strategy are forwarded to the `TokenizedStrategy`, leveraging its logic and storage capabilities.


# TokenizedStrategy

https\://github.com/Into-the-Fathom/fathom-vaults-smart-contracts/blob/master/contracts/strategy/TokenizedStrategy.sol

The `TokenizedStrategy` contract serves as a proxy-style implementation that centralizes logic, storage, and management for strategies inheriting from `BaseStrategy`. It facilitates the creation of ERC4626 compliant vaults by handling interactions and state transitions through delegated calls to this contract.

### **Contract Storage**

* **`StrategyData`**: This struct consolidates all storage variables needed for a strategy, optimizing for gas efficiency by reducing the frequency of storage slot loading during function execution. Key elements include:
  * **`initialDomainSeparator` and `initialChainId`**: Utilized for EIP-712 compliance across different chains.
  * **`totalSupply`, `totalIdle`, and `totalDebt`**: Track the total shares issued, the idle assets, and the assets actively deployed, respectively.
  * **`profitUnlockingRate` and `fullProfitUnlockDate`**: Manage the unlocking of profit over time.
  * **`management`, `keeper`, `emergencyAdmin`**: Addresses responsible for strategy management, routine maintenance, and emergency interventions.

### **Core Functionalities**

* **Initialization and Strategy Setup**: On the deployment of a new strategy, essential parameters like asset type, strategy name, and roles are established.
* **Asset Management**: Functions to deploy funds (`deployFunds`), free funds (`freeFunds`), and report the strategy's performance (`report`) encapsulate core investment strategy operations.
* **Fee Management**: The contract facilitates setting and adjusting performance fees, which are calculated on the profits generated by the strategy.

### **Access Control Modifiers**

* **`onlyManagement`**: Ensures that only the designated management address can perform certain administrative tasks.
* **`onlyKeepers`**: Restricts sensitive operations such as reporting to either the designated keeper or management addresses.
* **`onlyEmergencyAuthorized`**: Allows for emergency actions, such as strategy shutdown, to be executed by authorized emergency administrators.

### **Events**

* **Management Events**: Such as `UpdateManagement`, signal changes in management roles or parameters.
* **Operational Events**: Including `Deposit` and `Withdraw`, provide transactional transparency for assets moving in and out of the strategy.
* **Performance Reporting**: The `Reported` event logs the outcomes of performance reports, detailing profits, losses, and fees.

### **Strategy Interaction Functions**

* **`deposit`/`mint`**: For adding assets to the strategy in exchange for shares.
* **`withdraw`/`redeem`**: For removing assets from the strategy, optionally handling losses within specified bounds.
* **`shutdownStrategy`/`emergencyWithdraw`**: For halting new investments and managing assets in response to adverse conditions.

### **Configuration and Maintenance**

* **`setPerformanceFee`**, **`setKeeper`**, **`setEmergencyAdmin`**: Functions to adjust operational parameters and roles to respond to evolving strategy needs or external conditions.
* **`shutdownStrategy`**: A critical function used to cease all investment activities, allowing the strategy to only handle withdrawals and necessary maintenance.

### **Utility and Helper Functions**

* **`convertToShares`/`convertToAssets`**: Convert between the underlying asset and shares based on the current state of the strategy, aiding in calculations for deposits and withdrawals.
* **`_updateBalances`**: Ensures internal accounting reflects the actual state of assets within the strategy, crucial after any interaction that alters the balance of deployed or idle assets.


# Deployments


# XDC Network

## Addresses on XDC mainnet

* VaultPackage: `0xdC988aBC044e764C7b507F89A1755f7427a1CCb2`
* FactoryPackage: `0xF8E56b3578a274e4a1dF0FF9664f668F5728dCD8`
* Factory: `0x0c6e3fd64D5f33eac0DCCDd887A8c7512bCDB7D6`
* TokenizedStrategy: `0x21B5a34F8ae0387f247E9b01bA1B5c5B8A48971F`
* Accountant: `0x427Fd46B341C5a3E1eA19BE11D36E5c526A885d4`

### Fathom Vaults

* Educational: `0x3C8e9896933B374E638f9a5C309535409129aaA2`. Strategies:
  * Educational: `0xE2DEa7e0c272dE04e8708674dAE73ebd6E5c1455`
* DeFi: `0x4dd9C4Cd9A8f24a8e4D51E07ae36d6Af4c4CB71B`.

  &#x20;Strategies:

  * Liquidation: `0xc0AC2E5181F90fDa9E9264b5b1634B2c8bD88CDd`


# User Guides


# Deposit and Withdraw in Vault

To deposit and then withdraw your FXD in the Vault, follow the steps below:

* Go to Fathom [DApp](https://dapp.fathom.fi/#/vaults).
* Connect your Web3 wallet (such as [MetaMask](https://metamask.io/)) and make sure your network is set to the intended chain (i.e., [XDC](https://chainlist.org/chain/50)).

<div data-full-width="true"><figure><img src="/files/QD3FR14Hw1ZKtnbcHpqD" alt=""><figcaption></figcaption></figure></div>

* Check your desired Vault by clicking the arrow icon at the right.

<figure><img src="/files/sjSN9rwTL0G0SpOupnGD" alt=""><figcaption></figcaption></figure>

* It is also better to check the Strategies this Vault is utilizing.

<div data-full-width="true"><figure><img src="/files/wqLRN8xR8HZ3uvXJvrUd" alt=""><figcaption></figcaption></figure></div>

* Click "**Deposit**".

<div data-full-width="true"><figure><img src="/files/NJRYRG02D4vrNdV20bYg" alt=""><figcaption></figcaption></figure></div>

* Enter the amount you would like to deposit. The shares token you will receive represents your part of the Vault pool. It does not equal your deposit by one-to-one.
* Click "**Deposit**"
  * You may be required to approve the FXD transfer before the actual transfer (depending on your previous deposits).
  * Sign and send the transaction in your Wallet.
  * Wait for the transaction to be processed.
  * Once the transaction has gone through, you'll see your deposit in "**Your Position"** on the same page, and the Vault will be marked as "**Earning"**.

<div data-full-width="true"><figure><img src="/files/YxBMkiJ5t9Os7kA02vyW" alt=""><figcaption></figcaption></figure></div>

* To withdraw your deposit and earnings, click the "**Manage**" button. Please be aware that, based on the Vault and its Strategies, you may face losses and withdraw less than you deposited.

<div data-full-width="true"><figure><img src="/files/JexiC2EhYInvwQ2W3MlX" alt=""><figcaption></figcaption></figure></div>

* Enter the amount you would like to withdraw. The shares token you will burn represents your part of the Vault pool. It does not equal your deposit by one-to-one.
* Click "**Withdraw**"
  * You may be required to approve the shares token transfer before the actual transfer (depending on your previous withdrawals).
  * Sign and send the transaction in your Wallet.
  * Wait for the transaction to be processed.
  * Once the transaction has gone through, you'll see your "**Your Position"** on the same page to have fewer assets or disappear if you return all the money.


# Lending

Fathom Lending is an advanced decentralized lending protocol that allows users to lend and borrow assets seamlessly. Designed to be robust, secure, and user-friendly, Fathom Lending offers a comprehensive suite of features to facilitate decentralized finance (DeFi) operations.

**Key Features**

* **Decentralized and Trustless**: Operates without a central authority, ensuring that all transactions are transparent and trustless.
* **Variety of Supported Assets**: Supports a wide range of assets, allowing users to diversify their portfolios and manage risk effectively.
* **Dynamic Interest Rates**: Utilizes advanced algorithms to provide competitive and dynamic interest rates for both lenders and borrowers.
* **Secure Collateral Management**: Implements rigorous security protocols for collateral management, ensuring the safety of user funds.
* **Efficient Liquidation Mechanisms**: Employs efficient liquidation processes to manage under-collateralized positions and protect the protocol's integrity.
* **Interoperability**: Designed to integrate with other Fathom products and 3-rd party DeFi platforms and services, enhancing its utility and user experience.


# Core Concepts

**Understanding Fathom Lending**

Fathom Lending allows users to lend and borrow cryptocurrencies. By providing liquidity to the protocol, lenders earn interest on their deposits, while borrowers can access these funds by providing collateral. The platform operates without intermediaries, leveraging smart contracts to automate and secure transactions.

### **Key Terminologies**

* **Lender**: A user who deposits assets into the Fathom Lending platform to earn interest.
* **Borrower**: A user who borrows assets from the Fathom Lending platform by providing collateral.
* **Collateral**: Assets pledged by borrowers to secure their loans and minimize the risk of default.
* **Interest Rate**: The percentage of interest paid by borrowers on their loans or earned by lenders on their deposits. Rates are determined dynamically based on supply and demand.
* **Liquidity Pool**: A collection of assets provided by lenders, available for borrowers to draw from.
* **Liquidation**: The process of selling a borrower's collateral when their loan falls below the required collateral ratio to protect the protocol from losses.

### **How Fathom Lending Works**

1. **Lending**: Users deposit their assets into the Fathom Lending protocol, adding liquidity to the platform. In return, they receive interest-bearing tokens representing their share of the liquidity pool.
2. **Borrowing**: Users can borrow assets from the liquidity pool by providing collateral. The amount they can borrow is determined by the collateral's value and the protocol's collateralization requirements.
3. **Interest Rates**: Interest rates for both lenders and borrowers are dynamically adjusted based on the utilization rate of the liquidity pool. Higher utilization leads to higher interest rates, incentivizing more deposits and balancing supply and demand.
4. **Collateral Management**: Borrowers must maintain a collateral ratio above a certain threshold to avoid liquidation. If the value of their collateral falls below this threshold, the protocol will automatically liquidate a portion of the collateral to repay the loan and maintain system stability.
5. **Liquidation**: When a borrower's collateral ratio drops below the required level, the protocol triggers a liquidation process. Liquidators can purchase the under-collateralized loans at a discount, incentivizing them to repay the loan and sell the collateral.


# Protocol Mechanics

### **Interest Rate Models**

Fathom Lending employs a dynamic interest rate model that adjusts based on the utilization rate of each asset pool. This model ensures that interest rates are fair and responsive to market conditions, balancing supply and demand for each asset. The key components of the interest rate model are:

* **Base Rate**: The minimum interest rate applied when utilization is low.
* **Slope 1**: The rate of increase in interest rates as utilization rises from 0% to the optimal utilization point.
* **Optimal Utilization Rate**: The target utilization level where the interest rate curve changes its slope.
* **Slope 2**: The rate of increase in interest rates as utilization rises above the optimal utilization point.

This tiered model incentivizes both lending and borrowing, ensuring sufficient liquidity and stable interest rates.

### **Collateral Management**

Collateral management is a crucial aspect of the Fathom Lending protocol, ensuring that loans are secure and the system remains stable. Key components of collateral management include:

* **Collateralization Ratio**: The required ratio of collateral value to borrowed amount. This ratio ensures that loans are over-collateralized to protect against market volatility.
* **Health Factor**: A measure of the safety of a borrower's loan, calculated as the ratio of the value of the collateral to the value of the borrowed assets. A higher health factor indicates a safer loan.
* **Collateral Types**: Fathom Lending supports various types of collateral, each with its own collateralization ratio based on its risk profile.

Borrowers must maintain their collateral above the required ratio to avoid liquidation. The protocol continuously monitors the value of the collateral and the borrowed amount to ensure compliance.

### **Liquidation Process**

The liquidation process in Fathom Lending ensures that the protocol remains solvent and that lenders' funds are protected. The key steps in the liquidation process are:

1. **Triggering Liquidation**: When a borrower's health factor falls below 1 (i.e., the value of their collateral is insufficient to cover their debt), the liquidation process is triggered.
2. **Liquidation**: Liquidators can liquidate the under-collateralized loans at a discount. The system incentivizes liquidators to repay the loan and sell the collateral, restoring the protocol's balance.
3. **Repayment and Collateral Sale**: The liquidator repays the borrower's loan and receives the collateral at a discount. This process ensures that the protocol remains solvent and that the liquidator is incentivized to participate.

Liquidations help maintain the stability and solvency of the Fathom Lending protocol, ensuring that lenders' funds are always protected.

### **Risk Parameters**

Fathom Lending employs several risk parameters to ensure the stability and security of the protocol. These parameters are designed to manage risk and protect users from market volatility. Key risk parameters include:

* **Loan-to-Value (LTV) Ratio**: The maximum amount a user can borrow relative to the value of their collateral. A lower LTV ratio indicates a more conservative borrowing limit, reducing the risk of liquidation.
* **Liquidation Threshold**: The collateral value at which a loan becomes eligible for liquidation. This threshold is set to ensure that loans are adequately collateralized and to protect against sudden market downturns.
* **Liquidation Bonus**: An additional incentive for liquidators, provided as a percentage of the collateral value. This bonus ensures that liquidators are adequately rewarded for their efforts in maintaining the protocol's stability.
* **Reserve Factor**: A percentage of the interest paid by borrowers that is reserved for the protocol. This reserve acts as a safety buffer to cover potential losses and ensure the long-term sustainability of the protocol.


# Architecture

Fathom Lending's contract architecture is facilitating seamless interactions between various components of the protocol. The architecture consists of several core smart contracts that handle different aspects of the lending and borrowing process. This modular approach ensures that each contract has a well-defined role, enhancing maintainability and scalability.

These smart contracts are the [AAVE V3 direct fork](https://docs.aave.com/developers). They are battle-tested on various networks and are considered safe.

**Key Contracts and Their Roles**

1. **LendingPool**: The central contract that manages deposits, withdrawals, borrowing, and repayments. It interacts with other contracts to execute these operations and maintain the protocol's state.
2. **LendingPoolCore**: Stores the protocol's internal data, such as user balances, reserve configurations, and interest rate models. It serves as the data layer for the LendingPool contract.
3. **LendingPoolConfigurator**: Allows authorized entities to configure the protocol's parameters, such as interest rate models, collateral factors, and reserve assets. It ensures that the protocol can be updated and optimized as needed.
4. **InterestRateStrategy**: Determines the interest rates for borrowing and lending based on the utilization rates of the asset pools. Multiple strategies can be implemented to accommodate different assets and market conditions.
5. **CollateralManager**: Manages collateral for borrowers, ensuring that loans are properly collateralized and initiating the liquidation process when necessary.
6. **PriceOracle**: Provides real-time price data for assets, enabling accurate calculation of collateral values and ensuring that loans remain adequately collateralized.

**Contract Interactions and Data Flow**

The interaction between contracts in Fathom Lending follows a well-defined flow to ensure efficiency and security. Here’s how these interactions typically occur:

1. **User Interaction**: Users interact with the LendingPool contract to deposit assets, borrow funds, repay loans, and withdraw assets.
2. **Data Access**: The LendingPool contract interacts with the LendingPoolCore contract to access and update user balances, reserve configurations, and other protocol data.
3. **Interest Calculation**: When users deposit or borrow assets, the LendingPool contract calls the InterestRateStrategy contract to determine the applicable interest rates based on current utilization rates.
4. **Collateral Management**: When a user borrows assets, the LendingPool contract interacts with the CollateralManager contract to verify collateral requirements and manage collateral deposits.
5. **Price Updates**: The PriceOracle contract continuously updates asset prices, which are used by the LendingPool and CollateralManager contracts to assess collateral values and determine liquidation thresholds.
6. **Liquidation**: If a borrower's collateral falls below the required threshold, the CollateralManager contract initiates the liquidation process, interacting with the LendingPool contract to repay the loan and sell the collateral.


# Interfaces


# FmToken

https\://github.com/Into-the-Fathom/fathom-lending-platform-smart-contracts/blob/master/contracts/protocol/tokenization/FmToken.sol

The FmToken is an interest-bearing token used within the Fathom protocol. It represents the user's stake in the underlying assets supplied to the protocol. This document provides details on the storage, functions, and events related to the FmToken contract.

### Functions

#### ERC20 Functions

* `name() external view returns (string memory)`: Returns the name of the token.
* `symbol() external view returns (string memory)`: Returns the symbol of the token.
* `decimals() external view returns (uint8)`: Returns the decimals of the token.
* `totalSupply() public view returns (uint256)`: Returns the total supply of the token.
* `balanceOf(address account) public view returns (uint256)`: Returns the balance of the specified account.
* `transfer(address recipient, uint256 amount) external returns (bool)`: Transfers tokens from the caller to the specified recipient.
* `allowance(address owner, address spender) external view returns (uint256)`: Returns the allowance of the spender for the owner's tokens.
* `approve(address spender, uint256 amount) external returns (bool)`: Approves the spender to use the specified amount of the caller's tokens.
* `transferFrom(address sender, address recipient, uint256 amount) external returns (bool)`: Transfers tokens from the sender to the recipient using the allowance mechanism.

#### Incentive Functions

* `getIncentivesController() external view returns (IFathomIncentivesController)`: Returns the address of the incentives controller.
* `setIncentivesController(IFathomIncentivesController controller) external`: Sets a new incentives controller.

#### Minting and Burning

* `mint(address caller, address onBehalfOf, uint256 amount, uint256 index) external returns (bool)`: Mints tokens to the specified user.
* `burn(address from, address receiverOfUnderlying, uint256 amount, uint256 index) external`: Burns tokens from the specified user and transfers the underlying asset to the specified receiver.
* `mintToTreasury(uint256 amount, uint256 index) external`: Mints tokens to the treasury.

#### Other Functions

* `transferOnLiquidation(address from, address to, uint256 value) external`: Transfers tokens during liquidation.
* `transferUnderlyingTo(address target, uint256 amount) external`: Transfers the underlying asset to the specified target.
* `handleRepayment(address user, address onBehalfOf, uint256 amount) external`: Handles repayment of the underlying asset.
* `permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external`: Approves spending of tokens using a signed message.

### Events

* `BalanceTransfer(address indexed from, address indexed to, uint256 value, uint256 index)`: Emitted during the transfer of tokens.
* `Mint(address indexed caller, address indexed onBehalfOf, uint256 value, uint256 balanceIncrease, uint256 index)`: Emitted during the minting of tokens.
* `Burn(address indexed from, address indexed target, uint256 value, uint256 balanceIncrease, uint256 index)`: Emitted during the burning of tokens.
* `Transfer(address indexed from, address indexed to, uint256 value)`: Emitted during the transfer of tokens.
* `Approval(address indexed owner, address indexed spender, uint256 value)`: Emitted when approval for spending is granted.


# VariableDebtToken

https\://github.com/Into-the-Fathom/fathom-lending-platform-smart-contracts/blob/master/contracts/protocol/tokenization/VariableDebtToken.sol

The `VariableDebtToken` contract is part of the Fathom lending protocol. It tracks users' borrowing positions at variable interest rates. This token is non-transferable and can only be minted or burned by the lending pool.

### Storage Variables

* `DEBT_TOKEN_REVISION`: Version of the debt token.
* `_underlyingAsset`: The address of the underlying asset.
* `POOL`: Reference to the main Pool contract.
* `_incentivesController`: Incentives controller for the token.

### **Set Functions:**

* `approveDelegation`: Delegates borrowing power to a user.
* `delegationWithSig`: Delegates borrowing power via signature.
* `setIncentivesController`: Sets the incentives controller.

### **Get Functions:**

* `balanceOf`: Returns the debt balance of a user.
* `totalSupply`: Returns the total supply of the debt token.
* `borrowAllowance`: Returns the borrow allowance for a user.
* `name`: Returns the name of the token.
* `symbol`: Returns the symbol of the token.
* `decimals`: Returns the number of decimals.
* `getIncentivesController`: Returns the incentives controller address.
* `UNDERLYING_ASSET_ADDRESS`: Returns the underlying asset address.

**Mint/Burn Functions:**

* `mint`: Mints debt tokens to a user.
* `burn`: Burns debt tokens from a user.

### Disabled ERC20 Functions

The following standard ERC20 functions are disabled as this is a non-transferable token:

* `transfer`
* `allowance`
* `approve`
* `transferFrom`
* `increaseAllowance`
* `decreaseAllowance`

These functions revert with an `OPERATION_NOT_SUPPORTED` error if called.

### Events

* `Mint`: Emitted when tokens are minted.
* `Burn`: Emitted when tokens are burned.
* `BorrowAllowanceDelegated`: Emitted when borrow allowance is delegated.
* `Transfer`: Emitted when tokens are transferred (disabled in this contract).
* `Approval`: Emitted when approval is given (disabled in this contract).
* `Initialized`: Emitted when the contract is initialized.


# StableDebtToken

https\://github.com/Into-the-Fathom/fathom-lending-platform-smart-contracts/blob/master/contracts/protocol/tokenization/StableDebtToken.sol

The `StableDebtToken` is a specialized token in the Fathom protocol used to track borrowing positions at a stable interest rate. This token does not inherit from `IERC20` to save on code size and avoids standard ERC20 functionalities such as transfers and approvals, given its non-transferable nature.

#### Events

* **Initialized**: Emitted when the token is initialized.
  * `underlyingAsset`: Address of the underlying asset.
  * `pool`: Address of the associated pool.
  * `incentivesController`: Address of the incentives controller.
  * `debtTokenDecimals`: Decimals of the debt token.
  * `debtTokenName`: Name of the debt token.
  * `debtTokenSymbol`: Symbol of the debt token.
  * `params`: Encoded parameters for additional initialization.
* **Mint**: Emitted when new stable debt is minted.
  * `user`: Address of the user who triggered the minting.
  * `onBehalfOf`: Address receiving the stable debt tokens.
  * `amount`: Amount minted (user-entered amount + balance increase from interest).
  * `currentBalance`: Balance of the user based on the previous balance and balance increase from interest.
  * `balanceIncrease`: Increase in balance since the last action of the user `onBehalfOf`.
  * `newRate`: Rate of the debt after the minting.
  * `avgStableRate`: Next average stable rate after the minting.
  * `newTotalSupply`: Next total supply of the stable debt token after the action.
* **Burn**: Emitted when stable debt is burned.
  * `from`: Address from which the debt will be burned.
  * `amount`: Amount being burned (user-entered amount - balance increase from interest).
  * `currentBalance`: Balance of the user based on the previous balance and balance increase from interest.
  * `balanceIncrease`: Increase in balance since the last action of `from`.
  * `avgStableRate`: Next average stable rate after the burning.
  * `newTotalSupply`: Next total supply of the stable debt token after the action.

#### Functions

**`initialize`**

Initializes the debt token.

* **Parameters**:
  * `pool`: The pool contract that is initializing this contract.
  * `underlyingAsset`: The address of the underlying asset of this debt token.
  * `incentivesController`: The smart contract managing potential incentives distribution.
  * `debtTokenDecimals`: The decimals of the debt token, same as the underlying asset's.
  * `debtTokenName`: The name of the token.
  * `debtTokenSymbol`: The symbol of the token.
  * `params`: Encoded parameters for additional initialization.

**`getAverageStableRate`**

Returns the average rate of all the stable rate loans.

* **Returns**:
  * The average stable rate.

**`getUserLastUpdated`**

Returns the timestamp of the last update of the user.

* **Parameters**:
  * `user`: The address of the user.
* **Returns**:
  * The timestamp.

**`getUserStableRate`**

Returns the stable rate of the user's debt.

* **Parameters**:
  * `user`: The address of the user.
* **Returns**:
  * The stable rate of the user.

**`balanceOf`**

Returns the balance of a user.

* **Parameters**:
  * `account`: The address of the user.
* **Returns**:
  * The balance of the user.

**`mint`**

Mints debt tokens to the `onBehalfOf` address.

* **Parameters**:
  * `user`: The address receiving the borrowed underlying.
  * `onBehalfOf`: The address receiving the debt tokens.
  * `amount`: The amount of debt tokens to mint.
  * `rate`: The rate of the debt being minted.
* **Returns**:
  * `bool`: True if it is the first borrow, false otherwise.
  * `uint256`: The total stable debt.
  * `uint256`: The average stable borrow rate.

**`burn`**

Burns debt of `user`.

* **Parameters**:
  * `from`: The address from which the debt will be burned.
  * `amount`: The amount of debt tokens getting burned.
* **Returns**:
  * `uint256`: The total stable debt.
  * `uint256`: The average stable borrow rate.

**`getSupplyData`**

Returns the principal, the total supply, the average stable rate, and the timestamp for the last update.

* **Returns**:
  * `uint256`: The principal.
  * `uint256`: The total supply.
  * `uint256`: The average stable rate.
  * `uint40`: The timestamp of the last update.

**`getTotalSupplyAndAvgRate`**

Returns the total supply and the average stable rate.

* **Returns**:
  * `uint256`: The total supply.
  * `uint256`: The average rate.

**`totalSupply`**

Returns the total supply of the stable debt tokens.

* **Returns**:
  * The total supply.

**`getTotalSupplyLastUpdated`**

Returns the timestamp of the last update of the total supply.

* **Returns**:
  * The timestamp.

**`principalBalanceOf`**

Returns the principal debt balance of the user.

* **Parameters**:
  * `user`: The address of the user.
* **Returns**:
  * The debt balance of the user since the last burn/mint action.

**`UNDERLYING_ASSET_ADDRESS`**

Returns the address of the underlying asset of this stable debt token.

* **Returns**:
  * The address of the underlying asset.

#### Non-Implemented ERC20 Functions

The following ERC20 functions are not implemented because `StableDebtToken` is non-transferable:

* `transfer`
* `allowance`
* `approve`
* `transferFrom`
* `increaseAllowance`
* `decreaseAllowance`


# L2Pool

https\://github.com/Into-the-Fathom/fathom-lending-platform-smart-contracts/blob/master/contracts/protocol/pool/L2Pool.sol

The `L2Pool` contract is a calldata-optimized extension of the Pool contract in the Fathom lending protocol. It allows users to interact with the protocol using a compact calldata representation, reducing transaction costs on rollups. Users can supply, withdraw, borrow, repay, and perform other standard lending operations with optimized calldata.

### Storage Variables

* `POOL_REVISION`: Version of the pool contract.
* `ADDRESSES_PROVIDER`: Reference to the PoolAddressesProvider contract.

### Functions

#### **Initialization:**

* `initialize`: Initializes the pool with the PoolAddressesProvider.

#### **Set Functions:**

* `setReserveInterestRateStrategyAddress`: Sets the interest rate strategy address for a reserve.
* `setConfiguration`: Sets the configuration for a reserve.
* `updateBridgeProtocolFee`: Updates the bridge protocol fee.
* `updateFlashloanPremiums`: Updates the flash loan premiums.
* `configureEModeCategory`: Configures an e-mode category.
* `setUserEMode`: Sets the user's e-mode category.
* `resetIsolationModeTotalDebt`: Resets the isolation mode total debt for a reserve.
* `rescueTokens`: Rescues tokens sent to the contract.

#### **Get Functions:**

* `getReserveData`: Returns the reserve data for an asset.
* `getUserAccountData`: Returns the user's account data.
* `getConfiguration`: Returns the configuration of a reserve.
* `getUserConfiguration`: Returns the user's configuration.
* `getReserveNormalizedIncome`: Returns the normalized income for a reserve.
* `getReserveNormalizedVariableDebt`: Returns the normalized variable debt for a reserve.
* `getReservesList`: Returns the list of reserves.
* `getReserveAddressById`: Returns the address of a reserve by its ID.
* `MAX_STABLE_RATE_BORROW_SIZE_PERCENT`: Returns the maximum stable rate borrow size percentage.
* `BRIDGE_PROTOCOL_FEE`: Returns the bridge protocol fee.
* `FLASHLOAN_PREMIUM_TOTAL`: Returns the total flash loan premium.
* `FLASHLOAN_PREMIUM_TO_PROTOCOL`: Returns the protocol's share of the flash loan premium.
* `MAX_NUMBER_RESERVES`: Returns the maximum number of reserves.
* `getEModeCategoryData`: Returns the data of an e-mode category.
* `getUserEMode`: Returns the e-mode category of a user.

#### **Supply Functions:**

* `supply`: Supplies assets to the pool.
* `supplyWithPermit`: Supplies assets to the pool with a permit.

#### **Withdraw Functions:**

* `withdraw`: Withdraws assets from the pool.

#### **Borrow Functions:**

* `borrow`: Borrows assets from the pool.
* `repay`: Repays borrowed assets.
* `repayWithPermit`: Repays borrowed assets with a permit.
* `repayWithFmTokens`: Repays borrowed assets using FM tokens.
* `swapBorrowRateMode`: Swaps the borrow rate mode.
* `rebalanceStableBorrowRate`: Rebalances the stable borrow rate.
* `setUserUseReserveAsCollateral`: Sets a user's reserve as collateral.
* `liquidationCall`: Executes a liquidation call.

#### **Flash Loan Functions:**

* `flashLoan`: Executes a flash loan.
* `flashLoanSimple`: Executes a simple flash loan.

#### **Finalization Functions:**

* `finalizeTransfer`: Finalizes a transfer of assets.

#### **Reserve Management Functions:**

* `initReserve`: Initializes a reserve.
* `dropReserve`: Drops a reserve.

#### **Emergency Functions:**

* `rescueTokens`: Rescues tokens from the contract

### Events

#### **Pool Events** (Inherited from `Pool` contract):

* **Supply**: Emitted when assets are supplied to the pool.
* **Withdraw**: Emitted when assets are withdrawn from the pool.
* **Borrow**: Emitted when assets are borrowed from the pool.
* **Repay**: Emitted when borrowed assets are repaid.
* **FlashLoan**: Emitted when a flash loan is executed.
* **SwapBorrowRateMode**: Emitted when the borrow rate mode is swapped.
* **RebalanceStableBorrowRate**: Emitted when the stable borrow rate is rebalanced.
* **SetUserUseReserveAsCollateral**: Emitted when a user sets a reserve as collateral.
* **LiquidationCall**: Emitted when a liquidation call is executed.
* **ReserveDataUpdated**: Emitted when reserve data is updated.
* **MintUnbacked**: Emitted when unbacked assets are minted.
* **BackUnbacked**: Emitted when unbacked assets are backed.
* **MintToTreasury**: Emitted when assets are minted to the treasury.
* **InitializeReserve**: Emitted when a reserve is initialized.
* **DropReserve**: Emitted when a reserve is dropped.
* **SetReserveInterestRateStrategyAddress**: Emitted when the interest rate strategy address for a reserve is set.
* **SetConfiguration**: Emitted when the configuration of a reserve is set.
* **UpdateBridgeProtocolFee**: Emitted when the bridge protocol fee is updated.
* **UpdateFlashloanPremiums**: Emitted when flash loan premiums are updated.
* **ConfigureEModeCategory**: Emitted when an e-mode category is configured.
* **SetUserEMode**: Emitted when a user's e-mode category is set.
* **ResetIsolationModeTotalDebt**: Emitted when the isolation mode total debt is reset.
* **RescueTokens**: Emitted when tokens are rescued.

#### **L2Pool Specific Events**:

* There are no additional events defined specifically in the `L2Pool` contract. It leverages the compact calldata representation to optimize the inherited functionalities from the `Pool` contract without adding new events.


# PoolAddressesProvider

https\://github.com/Into-the-Fathom/fathom-lending-platform-smart-contracts/blob/master/contracts/protocol/configuration/PoolAddressesProvider.sol

The `PoolAddressesProvider` contract is the main registry of addresses that are part of or connected to the Fathom protocol, including permissioned roles. It acts as a factory of proxies and an admin of those proxies, with the right to change their implementations. The contract is owned by the Fathom Governance.

### **Storage Variables**

* **\_marketId**: The identifier of the Fathom Market.
* **\_addresses**: A mapping of registered addresses (`bytes32 identifier` => `address registeredAddress`).

### **Constants**

* **POOL**: The identifier for the pool address.
* **POOL\_CONFIGURATOR**: The identifier for the pool configurator address.
* **PRICE\_ORACLE**: The identifier for the price oracle address.
* **ACL\_MANAGER**: The identifier for the ACL manager address.
* **ACL\_ADMIN**: The identifier for the ACL admin address.
* **PRICE\_ORACLE\_SENTINEL**: The identifier for the price oracle sentinel address.
* **DATA\_PROVIDER**: The identifier for the data provider address.

### Functions

### **Getters**

* **getMarketId()**: Returns the identifier of the Fathom Market.
* **getAddress(bytes32 id)**: Returns the registered address associated with the given identifier.
* **getPool()**: Returns the address of the pool.
* **getPoolConfigurator()**: Returns the address of the pool configurator.
* **getPriceOracle()**: Returns the address of the price oracle.
* **getACLManager()**: Returns the address of the ACL manager.
* **getACLAdmin()**: Returns the address of the ACL admin.
* **getPriceOracleSentinel()**: Returns the address of the price oracle sentinel.
* **getPoolDataProvider()**: Returns the address of the pool data provider.

### **Setters**

* **setMarketId(string memory newMarketId)**: Sets a new market identifier. Callable only by the owner.
* **setAddress(bytes32 id, address newAddress)**: Registers a new address with the given identifier. Callable only by the owner.
* **setAddressAsProxy(bytes32 id, address newImplementationAddress)**: Updates the implementation address of a proxy. Callable only by the owner.
* **setPoolImpl(address newPoolImpl)**: Sets a new pool implementation. Callable only by the owner.
* **setPoolConfiguratorImpl(address newPoolConfiguratorImpl)**: Sets a new pool configurator implementation. Callable only by the owner.
* **setPriceOracle(address newPriceOracle)**: Sets a new price oracle address. Callable only by the owner.
* **setACLManager(address newAclManager)**: Sets a new ACL manager address. Callable only by the owner.
* **setACLAdmin(address newAclAdmin)**: Sets a new ACL admin address. Callable only by the owner.
* **setPriceOracleSentinel(address newPriceOracleSentinel)**: Sets a new price oracle sentinel address. Callable only by the owner.
* **setPoolDataProvider(address newDataProvider)**: Sets a new pool data provider address. Callable only by the owner.

### **Events**

* **MarketIdSet(string indexed oldMarketId, string indexed newMarketId)**: Emitted when the market identifier is updated.
* **AddressSet(bytes32 indexed id, address indexed oldAddress, address indexed newAddress)**: Emitted when an address is registered or updated.
* **AddressSetAsProxy(bytes32 indexed id, address indexed proxyAddress, address indexed oldImplementationAddress, address newImplementationAddress)**: Emitted when a proxy address is set or updated.
* **PoolUpdated(address indexed oldPoolImpl, address indexed newPoolImpl)**: Emitted when the pool implementation is updated.
* **PoolConfiguratorUpdated(address indexed oldPoolConfiguratorImpl, address indexed newPoolConfiguratorImpl)**: Emitted when the pool configurator implementation is updated.
* **PriceOracleUpdated(address indexed oldPriceOracle, address indexed newPriceOracle)**: Emitted when the price oracle address is updated.
* **ACLManagerUpdated(address indexed oldAclManager, address indexed newAclManager)**: Emitted when the ACL manager address is updated.
* **ACLAdminUpdated(address indexed oldAclAdmin, address indexed newAclAdmin)**: Emitted when the ACL admin address is updated.
* **PriceOracleSentinelUpdated(address indexed oldPriceOracleSentinel, address indexed newPriceOracleSentinel)**: Emitted when the price oracle sentinel address is updated.
* **PoolDataProviderUpdated(address indexed oldDataProvider, address indexed newDataProvider)**: Emitted when the pool data provider address is updated.
* **ProxyCreated(bytes32 indexed id, address indexed proxyAddress, address indexed implementationAddress)**: Emitted when a new proxy is created.


# User Guides


# Supply, Borrow, Repay and Withdraw Asset

To cover the most important flows: supply, borrow, repay and withdraw an asset, follow the steps below.

### Supply Asset

* Go to Fathom [DApp](https://dapp.fathom.fi/#/lending).
* Connect your Web3 wallet (such as [MetaMask](https://metamask.io/)) and make sure your network is set to the intended chain (i.e., [XDC](https://chainlist.org/chain/50)).

<div data-full-width="true"><figure><img src="/files/ijj31VB7A2TCBcqeVTJc" alt=""><figcaption></figcaption></figure></div>

* Choose the asset to Supply.
  * You can investigate the [Market](https://dapp.fathom.fi/#/lending/reserve-overview/?underlyingAsset=0x49d3f7543335cf38fa10889ccff10207e22110b5\&marketName=proto_mainnet_v3) for this asset to make the decision. Clock "Details" button.

<figure><img src="/files/W9VeYrPnDfteByAb7YzV" alt=""><figcaption></figcaption></figure>

* Click "**Supply**" button.
* Enter the amount of the asset you would like to supply.

<div data-full-width="true"><figure><img src="/files/eNsXN6sU3V6lMRyllkZE" alt=""><figcaption></figcaption></figure></div>

* Click "**Supply Asset**"
  * If this is your first time supplying this asset you may be required to approve the asset transfer before the actual transfer (depending on the asset type).
  * Sign and send the transaction in your Wallet.
  * Wait for the transaction to be processed.
  * Once the transaction has gone through, you'll see your asset supply in "**Your supplies"**.

<div data-full-width="true"><figure><img src="/files/f6ZofmsxcoAGAJxIptil" alt=""><figcaption></figcaption></figure></div>

### Borrow Asset

Now, you can borrow assets against your collateral. Be careful only to borrow a little; otherwise, your position may be liquidated. The simplest metric for the position risk is the health factor.

* Choose an asset to borrow and click "Borrow" button.
* Enter the amount of the asset you would like to borrow. Pay attention to the Health Factor.

<figure><img src="/files/rqygZZlycJTf2OCtt10b" alt=""><figcaption></figcaption></figure>

* Click "Borrow Asset"
  * Sign and send the transaction in your Wallet.
  * Wait for the transaction to be processed.
  * Once the transaction has gone through, you'll see your asset borrowed in "**Your borrows"**.

<figure><img src="/files/MThhkq7FbaDcpx58teQr" alt=""><figcaption></figcaption></figure>

### Repay Asset

If you have significant borrowing positions, your ability to withdraw your supply may be restricted. You need to repay all your borrowed assets with interest to withdraw all your supplies.

* Choose the asset to repay and click "**Repay**" button.
* Enter the amount of the asset you would like to repay.

<div data-full-width="true"><figure><img src="/files/a0J2OOmyEJV8bcSyqGvQ" alt=""><figcaption></figcaption></figure></div>

Click "**Repay Asset**"

* If this is your first time repaying this asset you may be required to approve the asset transfer before the actual transfer (depending on the collateral type).
* Sign and send the transaction in your Wallet.
* Wait for the transaction to be processed.
* Once the transaction has gone through, you'll see changes in "**Your borrows"**.

### Withdraw Asset

* Choose the asset to withdraw and click "**Withdraw**" button.
* Enter the amount of the asset you would like to withdraw.

<div data-full-width="true"><figure><img src="/files/2S3aDxznUT9vuDak4cMR" alt=""><figcaption></figcaption></figure></div>

Click "**Withdraw Asset**"

* Sign and send the transaction in your Wallet.
* Wait for the transaction to be processed.
* Once the transaction has gone through, you'll see changes in "**Your supplies"**.

### Risk Management

Pay attention to your Health Factor. If it becomes too small, your supplied assets may be liquidated to restore it. In that case, you will lose your supply.

There are 2 ways how to manage your Health Factors:

* Supply more assets
* Repay your borrowed assets


# Deployments


# XDC Network

## Addresses on XDC mainnet

#### Admin / ownership

ACL Admin / Pool Admin / Emergency Admin / Owner of PoolAddressesProvider / Registry / EmissionManager / FmToken treasuries: `0x4ccF956B8e601C5958401B4178e3dEA844C0a984`

#### Core protocol

PoolAddressesProviderRegistry: `0xDAb3B99eb3569466750c436d6F4c99d57850Cc89`

PoolAddressesProvider: `0x37ab83e6a9B99DA3eAF00D1afdC45f50ee7625E5`

Pool (Proxy): `0x70d8005E3c8C7e383FE35Fa40156042F3393449F`

Pool Implementation: `0x5c756ACD4Cb26a9cA6De7abF9765cE84B5Be9322`

PoolConfigurator (Proxy): `0x56f3A75C71C207a77c3b8c77a34FC89cF1a6DB66`

PoolConfigurator Implementation: `0xE6525d46ADc3Cd5AF2CfA322504A7C17F8445c8D`

ACLManager: `0xf73e7d6309A2DaDE5B698eD33dA929d2F2281526`

PoolDataProvider: `0x7fa488a5C88E9E35B0B86127Ec76B0c1F0933191`

FathomOracle (PriceOracle): `0x54348d953Abc4f167cbdeDe648095c1aF7DE355A`

FallbackOracle: `0x32A2FdC2A5206320cE697C952c7f4cCDdA2a0294`

EmissionManager: `0x049F146A33a16e454f3BE28bb0bc18c12C96a894`

IncentivesController (Proxy): `0xf5e0C80114C0b0E3c4b55c217643E9a02699bB9b`

IncentivesV2 Implementation: `0x32f42b439C63Bc4F27F701CFD5939a5889eA2a00`

WrappedTokenGatewayV3 (WXDC gateway): `0x57Ba8bAA7c3Ff6606751859f1CED9f68819C2f41`

WalletBalanceProvider: `0x7C724DEaD5012Eb4C9e2d1529cF0353e767C82Cd`

UiPoolDataProviderV3: `0x5f7001B6Dc957dC5B2F78f0BC3aFbFc1fE628A18`

UiIncentiveDataProviderV3: `0xA69c5468Aa4ab263a250fD9dA4322e58370F2bB2`

ReservesSetupHelper: `0x5b8483Ab120537A307Df6bB3dD2Bb149091F2AF7`

FlashLiquidator: `0x5cF8e2326F5c013d568F48E878e9D7ae9557F902`

FmTokenV2 Implementation (active for all fmTokens): `0x95f2f5fd81815Da3517E1EdfC149EE47c116F904`

StableDebtToken Implementation: `0x80e2eA68DB630660eFCa18780F24587967F3071B`

VariableDebtToken Implementation: `0xfaA128B457FC7cBF9763A7Be66bF89662d9777FF`

#### Logic libraries (linked into Pool / PoolConfigurator)

SupplyLogic: `0xA8f477530036cF1391E5A76A723635be7b28Eff3`

BorrowLogic: `0x602d170366C4c14c855BAa051A35Ee318564343A`

LiquidationLogic: `0xdf816BB3a1415B4b88365D6Ecb5Fcc52A7ee7729`

EModeLogic: `0x1240f345449Ee3293FEAE9E3e3FbcCe1589e9160`

BridgeLogic: `0x00C1B7ce7703beD7e115833a6c2DbcFeD887a4f1`

ConfiguratorLogic: `0x373E40f30e7a2CcFfe22fA1926bD71284332a2B9`

FlashLoanLogic: `0x57023484830D90027E33e37Abc301A89e1318B30`

PoolLogic: `0x8c2cf73fB553d9a8a8Dc34A6B5e6078FC023c34F`

#### Interest rate strategies

rateStrategyVolatileOne (used by WXDC, CGO, FTHM): `0x99E7d2d9B8349B70aae31e5213c54fd022fd5DCF`

rateStrategyStableOne (used by xUSDT, USDC): `0xB34A51D8443219bdA8BFBA5826B7907Bc4032e11`

rateStrategyStableTwo (used by FXD): `0x12936376CCb51877ed2135b985aEe1d011e173CA`

#### Active markets

**WXDC**

WXDC Underlying: `0x951857744785E80e2De051c32EE7b25f9c458C42`

WXDC fmToken (fmWXDC): `0xDAEf7d4000fb0e511C9f2dEEAE602d9c8fcb28f7`

WXDC VariableDebtToken: `0x10eB945e14131Fb55B2F432d826F4e09d718276D`

WXDC StableDebtToken: `0xcbf718E6802E646D6d016912453E1ECb1BdB0DcA`

WXDC Oracle source: `0x8d470BDE66eE52981D7D29Bc2e6FCa3b4DC17879`

WXDC InterestRateStrategy: `0x99E7d2d9B8349B70aae31e5213c54fd022fd5DCF`

**USDC**

USDC Underlying: `0xfA2958CB79b0491CC627c1557F441eF849Ca8eb1`

USDC fmToken (fmUSDC): `0xfc751eef339555950A8cb443bb1e3FdD6a3A77eC`

USDC VariableDebtToken: `0x2c58F972225598dd945fdb2D11a998D63e189509`

USDC StableDebtToken: `0xa2c3C5b95413F486A07897D288B2a7aA10Db1Cc6`

USDC Oracle source: `0x321F084B78756C5550e6Ab200d88BB2602BCE1A2`

USDC InterestRateStrategy: `0xB34A51D8443219bdA8BFBA5826B7907Bc4032e11`

#### Deprecated markets

**FXD**

FXD Underlying: `0x49d3f7543335cf38Fa10889CCFF10207e22110B5`

FXD fmToken (fmFXD): `0xEC826980367dABBAA28F614B8D0e14548dCca37b`

FXD VariableDebtToken: `0xcF5b5C4DfeA09a0Ad129717BfbbCA750c362E795`

FXD StableDebtToken: `0xe82b0F5CDf092Bf01Ae56898bB35b1E77fc60aC2`

FXD Oracle source: `0x03396fE4E58A0778679E2731564f064FA5256C6E`

FXD InterestRateStrategy: `0x12936376CCb51877ed2135b985aEe1d011e173CA`

**xUSDT**

xUSDT Underlying (USDT\@xinfin): `0xD4B5f10D61916Bd6E0860144a91Ac658dE8a1437`

xUSDT fmToken (fmxUSDT): `0x1C3bBc4FA17128711c238Bc50Bd0AE85D35C2515`

xUSDT VariableDebtToken: `0x98dC1115ADdcdD2eF67c87D35fAF0b835b3F746D`

xUSDT StableDebtToken: `0x2F6C3d501cfD528D78c7C1Da3B8Ea37Ba85BDB93`

xUSDT Oracle source: `0x321F084B78756C5550e6Ab200d88BB2602BCE1A2`

xUSDT InterestRateStrategy: `0xB34A51D8443219bdA8BFBA5826B7907Bc4032e11`

**CGO**

CGO Underlying (Comtech Gold): `0x8f9920283470F52128bF11B0c14E798bE704fD15`

CGO fmToken (fmCGO): `0x0947617c830307957FAc8d51b1a9488e756Cf2Cf`

CGO VariableDebtToken: `0xa8aFc7a05E54F3027Eb77727d77cc5D3Fe7Bf4Af`

CGO StableDebtToken: `0x474C64774703f8e5132cc8400d77FA854cA6e219`

CGO Oracle source: `0x90473A2Fa1d9eB8fe6C45072D933218f828AF834`

CGO InterestRateStrategy: `0x99E7d2d9B8349B70aae31e5213c54fd022fd5DCF`

**FTHM**

FTHM Underlying (Fathom Protocol Token): `0x3279dBEfABF3C6ac29d7ff24A6c46645f3F4403c`

FTHM fmToken (fmFTHM): `0x103Df67779bf7F1C5cfa2374049E5666D9686b98`

FTHM VariableDebtToken: `0x31D83E0cae604F6Ce0a06800DAFe0959449b1947`

FTHM StableDebtToken: `0x2b0B493CB20C9efAb5b316618D86fe8a790D81dE`

FTHM Oracle source: `0xFc2fd5b24B2baEEa13b42809F582aa083cd29409`

FTHM InterestRateStrategy: `0x99E7d2d9B8349B70aae31e5213c54fd022fd5DCF`


# DEX

Fathom DEX is a decentralized exchange that provides a seamless and efficient platform for swapping digital assets. Designed to operate in a permissionless and trustless environment, Fathom DEX empowers users by offering decentralized liquidity pools and automated market-making functionalities. Here are some key features and benefits of Fathom DEX:

### **Key Features**

1. **Decentralized Liquidity Pools**
   * Users can provide liquidity by depositing pairs of tokens into liquidity pools, earning fees from trades that occur within those pools.
2. **Automated Market Making**
   * Fathom DEX uses an automated market maker (AMM) model, where the pricing of tokens is determined by a constant product formula. This ensures continuous liquidity and facilitates efficient trading.
3. **Token Swaps**
   * Users can easily swap between different tokens directly from their wallets without the need for intermediaries. The swap process is quick, secure, and cost-effective.
4. **Transparent and Trustless**
   * All transactions and operations on Fathom DEX are executed via smart contracts, ensuring transparency, security, and trustlessness. Users retain full control of their assets at all times.


# Core Concepts

### **Liquidity Pools**

Liquidity pools are at the heart of Fathom DEX, enabling users to provide liquidity and facilitate token swaps. A liquidity pool is a smart contract that holds pairs of tokens. Users can contribute to these pools by depositing equal values of two tokens, earning a share of the trading fees generated by the pool.

#### **Key Points:**

* **Liquidity Providers:** Users who add tokens to a liquidity pool are known as liquidity providers (LPs). In return for their contribution, they receive LP tokens, which represent their share of the pool.
* **Earning Fees:** LPs earn fees from trades that occur in their pool. These fees are proportional to their share of the total pool liquidity.
* **Impermanent Loss:** LPs should be aware of impermanent loss, a temporary loss in value that can occur when the price of deposited tokens changes relative to each other.

### **Token Swaps**

Token swaps are the primary function of Fathom DEX, allowing users to exchange one token for another directly from their wallets. The platform uses an Automated Market Maker (AMM) model to facilitate these swaps without the need for an order book.

#### **Key Points:**

* **Automated Market Maker:** The AMM algorithm uses a constant product formula (x \* y = k) to determine the price of tokens in a pool. This ensures continuous liquidity and efficient price discovery.
* **Slippage:** Swaps may incur slippage, which is the difference between the expected price of a trade and the actual price. Slippage occurs due to changes in the pool’s token ratio during the swap.
* **Transaction Fees:** Each swap incurs a small transaction fee, which is distributed to the liquidity providers of the respective pool.

### **Fees and Rewards**

Fathom DEX operates on a fee structure designed to incentivize liquidity provision and ensure a sustainable ecosystem.

#### **Key Points:**

* **Trading Fees:** A percentage of each trade executed on the platform is collected as a fee. This fee is distributed among the liquidity providers of the pool where the trade occurred.
* **LP Rewards:** In addition to trading fees, liquidity providers may earn rewards in the form of native tokens or other incentives, depending on the platform’s reward programs.
* **Staking and Farming Rewards:** Users can participate in staking and yield farming programs to earn additional rewards. These programs encourage long-term participation and enhance overall liquidity.


# Architecture

Fathom DEX relies on a robust and secure smart contract architecture to facilitate its decentralized exchange functionalities.

These smart contracts are the [Uniswap V2 direct fork](https://docs.uniswap.org/contracts/v2/concepts/protocol-overview/smart-contracts). They are battle-tested on various networks and are considered safe.

### **Overview of Smart Contract Architecture**

#### **Factory Contract**

* **Role:** The factory contract is responsible for deploying new liquidity pool contracts. It maintains a registry of all active liquidity pools on the platform.
* **Functions:**
  * CreatePair: Deploys a new pair contract for a given token pair.
  * GetPair: Retrieves the address of an existing pair contract.

#### **Pair Contract**

* **Role:** Each pair contract represents a liquidity pool for a specific token pair. It manages the addition and removal of liquidity, as well as the execution of token swaps.
* **Functions:**
  * AddLiquidity: Allows users to add tokens to the liquidity pool.
  * RemoveLiquidity: Allows users to withdraw their tokens from the liquidity pool.
  * Swap: Facilitates token swaps between the two tokens in the pair.

#### **Router Contract**

* **Role:** The router contract provides the main interface for users to interact with the DEX. It routes transactions to the appropriate pair contracts.
* **Functions:**
  * AddLiquidity: Simplifies the process of adding liquidity by automatically calculating the optimal token amounts.
  * RemoveLiquidity: Manages the removal of liquidity, ensuring users receive the correct token amounts.
  * SwapExactTokensForTokens: Executes a token swap with a specified input amount.
  * SwapTokensForExactTokens: Executes a token swap with a specified output amount.


# Interfaces


# Factory

https\://github.com/Into-the-Fathom/fathom-swap-smart-contracts/blob/master/contracts/core/UniswapV2Factory.sol

The `UniswapV2Factory` contract is a core component of the Fathom DEX. It is responsible for creating and managing pairs (liquidity pools) for token exchanges.

### State Variables

#### feeTo

* **Type:** `address`
* **Description:** Address to which protocol fees are sent.

#### feeToSetter

* **Type:** `address`
* **Description:** Address with the permission to update the `feeTo` address.

#### getPair

* **Type:** `mapping(address => mapping(address => address))`
* **Description:** Mapping from two token addresses to the address of their liquidity pool.

#### allPairs

* **Type:** `address[]`
* **Description:** Array of all created pair addresses.

### Set Functions

#### createPair

* **Parameters:**
  * `address tokenA`: The first token of the pair.
  * `address tokenB`: The second token of the pair.
* **Returns:**
  * `address pair`: The address of the created pair.
* **Description:** Creates a new liquidity pair for `tokenA` and `tokenB`. Emits the `PairCreated` event.

#### setFeeTo

* **Parameters:**
  * `address _feeTo`: The address to set as the fee recipient.
* **Description:** Sets the address to which protocol fees are sent. Can only be called by the `feeToSetter`.

#### setFeeToSetter

* **Parameters:**
  * `address _feeToSetter`: The address to set as the new `feeToSetter`.
* **Description:** Sets the address that can update the fee recipient. Can only be called by the current `feeToSetter`.

### Read Functions

#### allPairsLength

* **Parameters:** None
* **Returns:**
  * `uint`: The length of the `allPairs` array.
* **Description:** Returns the number of all pairs created.

#### getInitHash

* **Parameters:** None
* **Returns:**
  * `bytes32`: The keccak256 hash of the UniswapV2Pair creation code.
* **Description:** Returns the initialization hash of the UniswapV2Pair contract.

### Events

#### PairCreated

* **Parameters:**
  * `address indexed token0`: The first token of the pair.
  * `address indexed token1`: The second token of the pair.
  * `address pair`: The address of the created pair.
  * `uint`: The total number of pairs.
* **Description:** Emitted when a new pair is created.


# Pair

https\://github.com/Into-the-Fathom/fathom-swap-smart-contracts/blob/master/contracts/core/UniswapV2Pair.sol

The `UniswapV2Pair` contract is a core component of the Uniswap decentralized exchange. It facilitates liquidity pools between two ERC-20 tokens, enabling token swaps and liquidity management. The contract allows users to add and remove liquidity, swap tokens, and ensure reserves are synchronized with balances. It also supports permits for approvals via signatures and enforces the constant product formula for swaps. The contract emits events to track key actions such as minting, burning, and swapping of tokens.

### State Variables

#### factory

* **Type:** `address`
* **Description:** The address of the factory contract that created this pair.

#### token0

* **Type:** `address`
* **Description:** The address of the first token in the pair.

#### token1

* **Type:** `address`
* **Description:** The address of the second token in the pair.

#### reserve0

* **Type:** `uint112`
* **Description:** The reserve of token0.

#### reserve1

* **Type:** `uint112`
* **Description:** The reserve of token1.

#### blockTimestampLast

* **Type:** `uint32`
* **Description:** The timestamp of the last block when the reserves were updated.

#### price0CumulativeLast

* **Type:** `uint`
* **Description:** Cumulative price of token0.

#### price1CumulativeLast

* **Type:** `uint`
* **Description:** Cumulative price of token1.

#### kLast

* **Type:** `uint`
* **Description:** The product of the reserves, as of the last liquidity event.

#### unlocked

* **Type:** `uint`
* **Description:** Mutex variable to prevent reentrancy.

### Set Functions

#### mint

* **Parameters:**
  * `address to`
* **Returns:**
  * `uint liquidity`: The amount of liquidity minted.
* **Description:** Mints new liquidity tokens and sends them to the specified address. Updates reserves and handles fees.

#### burn

* **Parameters:**
  * `address to`
* **Returns:**
  * `uint amount0`: The amount of token0 burned.
  * `uint amount1`: The amount of token1 burned.
* **Description:** Burns liquidity tokens and sends the underlying assets to the specified address. Updates reserves and handles fees.

#### swap

* **Parameters:**
  * `uint amount0Out`
  * `uint amount1Out`
  * `address to`
  * `bytes calldata data`
* **Returns:** None
* **Description:** Swaps tokens and sends the output to the specified address. Allows for callbacks to execute additional logic.

#### skim

* **Parameters:**
  * `address to`
* **Returns:** None
* **Description:** Transfers any token balances to the specified address, bringing the token balances in line with the reserves.

#### sync

* **Parameters:** None
* **Returns:** None
* **Description:** Forces reserves to match the token balances in the contract.

### Read Functions

#### name

* **Parameters:** None
* **Returns:**
  * `string`: The name of the token.
* **Description:** Returns the name of the token.

#### symbol

* **Parameters:** None
* **Returns:**
  * `string`: The symbol of the token.
* **Description:** Returns the symbol of the token.

#### decimals

* **Parameters:** None
* **Returns:**
  * `uint8`: The number of decimals the token uses.
* **Description:** Returns the number of decimals the token uses.

#### totalSupply

* **Parameters:** None
* **Returns:**
  * `uint`: The total supply of the token.
* **Description:** Returns the total supply of the token.

#### balanceOf

* **Parameters:**
  * `address owner`
* **Returns:**
  * `uint`: The balance of the specified address.
* **Description:** Returns the token balance of the specified address.

#### allowance

* **Parameters:**
  * `address owner`
  * `address spender`
* **Returns:**
  * `uint`: The remaining number of tokens that the spender is allowed to spend.
* **Description:** Returns the remaining number of tokens that the spender is allowed to spend on behalf of the owner.

#### DOMAIN\_SEPARATOR

* **Parameters:** None
* **Returns:**
  * `bytes32`: The EIP-712 domain separator.
* **Description:** Returns the EIP-712 domain separator.

#### PERMIT\_TYPEHASH

* **Parameters:** None
* **Returns:**
  * `bytes32`: The permit typehash.
* **Description:** Returns the permit typehash.

#### nonces

* **Parameters:**
  * `address owner`
* **Returns:**
  * `uint`: The current nonce for the specified address.
* **Description:** Returns the current nonce for the specified address.

#### MINIMUM\_LIQUIDITY

* **Parameters:** None
* **Returns:**
  * `uint`: The minimum liquidity amount.
* **Description:** Returns the minimum liquidity amount.

#### getReserves

* **Parameters:** None
* **Returns:**
  * `uint112 reserve0`
  * `uint112 reserve1`
  * `uint32 blockTimestampLast`
* **Description:** Returns the current reserves of the pair and the timestamp of the last block.

#### price0CumulativeLast

* **Parameters:** None
* **Returns:**
  * `uint`: The last cumulative price of token0.
* **Description:** Returns the last cumulative price of token0.

#### price1CumulativeLast

* **Parameters:** None
* **Returns:**
  * `uint`: The last cumulative price of token1.
* **Description:** Returns the last cumulative price of token1.

### Events

#### Approval

* **Parameters:**
  * `address indexed owner`: The address of the token owner.
  * `address indexed spender`: The address of the spender.
  * `uint value`: The amount of tokens approved for spending.
* **Description:** Emitted when the allowance of a `spender` for an `owner` is set by a call to `approve`. `value` is the new allowance.

#### Transfer

* **Parameters:**
  * `address indexed from`: The address from which the tokens are transferred.
  * `address indexed to`: The address to which the tokens are transferred.
  * `uint value`: The amount of tokens transferred.
* **Description:** Emitted when `value` tokens are moved from one account (`from`) to another (`to`).

#### Mint

* **Parameters:**
  * `address indexed sender`: The address initiating the minting.
  * `uint amount0`: The amount of token0 added.
  * `uint amount1`: The amount of token1 added.
* **Description:** Emitted when liquidity is minted for the pair.

#### Burn

* **Parameters:**
  * `address indexed sender`: The address initiating the burning.
  * `uint amount0`: The amount of token0 removed.
  * `uint amount1`: The amount of token1 removed.
  * `address indexed to`: The address to which the burned tokens are sent.
* **Description:** Emitted when liquidity is burned for the pair.

#### Swap

* **Parameters:**
  * `address indexed sender`: The address initiating the swap.
  * `uint amount0In`: The amount of token0 input.
  * `uint amount1In`: The amount of token1 input.
  * `uint amount0Out`: The amount of token0 output.
  * `uint amount1Out`: The amount of token1 output.
  * `address indexed to`: The address to which the output tokens are sent.
* **Description:** Emitted when a swap is executed.

#### Sync

* **Parameters:**
  * `uint112 reserve0`: The new reserve of token0.
  * `uint112 reserve1`: The new reserve of token1.
* **Description:** Emitted when the reserves of the pair are synchronized.


# Router

https\://github.com/Into-the-Fathom/fathom-swap-smart-contracts/blob/master/contracts/periphery/UniswapV2Router02.sol

The `UniswapV2Router02` contract facilitates interactions with the Uniswap decentralized exchange, including adding and removing liquidity, swapping tokens, and retrieving price quotes. It supports the following operations:

* **Add Liquidity:** Allows users to contribute tokens to liquidity pools.
* **Remove Liquidity:** Enables users to withdraw their tokens from liquidity pools.
* **Token Swaps:** Facilitates swapping of tokens through Uniswap pairs.
* **Supporting Fee-On-Transfer Tokens:** Handles tokens with transfer fees during liquidity removal and swaps.
* **Price Quotes and Amounts:** Provides functions to compute price quotes and required token amounts for swaps.

### State Variables

* `factory`: Address of the Uniswap V2 factory contract.
* `WETH`: Address of the wrapped ETH (WETH) token contract.

### Set Functions in UniswapV2Router02

#### `addLiquidity`

Adds liquidity to a pair of tokens.

Parameters:

* `address tokenA`: Address of token A.
* `address tokenB`: Address of token B.
* `uint amountADesired`: Desired amount of token A.
* `uint amountBDesired`: Desired amount of token B.
* `uint amountAMin`: Minimum amount of token A.
* `uint amountBMin`: Minimum amount of token B.
* `address to`: Address to receive liquidity tokens.
* `uint deadline`: Timestamp after which the transaction will revert.

#### `addLiquidityETH`

Adds liquidity to a token-ETH pair.

Parameters:

* `address token`: Address of the token.
* `uint amountTokenDesired`: Desired amount of the token.
* `uint amountTokenMin`: Minimum amount of the token.
* `uint amountETHMin`: Minimum amount of ETH.
* `address to`: Address to receive liquidity tokens.
* `uint deadline`: Timestamp after which the transaction will revert.

#### `removeLiquidity`

Removes liquidity from a pair of tokens.

Parameters:

* `address tokenA`: Address of token A.
* `address tokenB`: Address of token B.
* `uint liquidity`: Amount of liquidity tokens to remove.
* `uint amountAMin`: Minimum amount of token A.
* `uint amountBMin`: Minimum amount of token B.
* `address to`: Address to receive tokens.
* `uint deadline`: Timestamp after which the transaction will revert.

#### `removeLiquidityETH`

Removes liquidity from a token-ETH pair.

Parameters:

* `address token`: Address of the token.
* `uint liquidity`: Amount of liquidity tokens to remove.
* `uint amountTokenMin`: Minimum amount of the token.
* `uint amountETHMin`: Minimum amount of ETH.
* `address to`: Address to receive tokens.
* `uint deadline`: Timestamp after which the transaction will revert.

#### `removeLiquidityWithPermit`

Removes liquidity from a pair of tokens using a permit.

Parameters:

* `address tokenA`: Address of token A.
* `address tokenB`: Address of token B.
* `uint liquidity`: Amount of liquidity tokens to remove.
* `uint amountAMin`: Minimum amount of token A.
* `uint amountBMin`: Minimum amount of token B.
* `address to`: Address to receive tokens.
* `uint deadline`: Timestamp after which the transaction will revert.
* `bool approveMax`: Whether to approve the maximum amount.
* `uint8 v`: V value of the permit signature.
* `bytes32 r`: R value of the permit signature.
* `bytes32 s`: S value of the permit signature.

#### `removeLiquidityETHWithPermit`

Removes liquidity from a token-ETH pair using a permit.

Parameters:

* `address token`: Address of the token.
* `uint liquidity`: Amount of liquidity tokens to remove.
* `uint amountTokenMin`: Minimum amount of the token.
* `uint amountETHMin`: Minimum amount of ETH.
* `address to`: Address to receive tokens.
* `uint deadline`: Timestamp after which the transaction will revert.
* `bool approveMax`: Whether to approve the maximum amount.
* `uint8 v`: V value of the permit signature.
* `bytes32 r`: R value of the permit signature.
* `bytes32 s`: S value of the permit signature.

#### `swapExactTokensForTokens`

Swaps an exact amount of tokens for another token.

Parameters:

* `uint amountIn`: Amount of input tokens.
* `uint amountOutMin`: Minimum amount of output tokens.
* `address[] calldata path`: Array of token addresses to trade through.
* `address to`: Address to receive output tokens.
* `uint deadline`: Timestamp after which the transaction will revert.

#### `swapTokensForExactTokens`

Swaps tokens for an exact amount of another token.

Parameters:

* `uint amountOut`: Amount of output tokens.
* `uint amountInMax`: Maximum amount of input tokens.
* `address[] calldata path`: Array of token addresses to trade through.
* `address to`: Address to receive output tokens.
* `uint deadline`: Timestamp after which the transaction will revert.

#### `swapExactETHForTokens`

Swaps an exact amount of ETH for tokens.

Parameters:

* `uint amountOutMin`: Minimum amount of output tokens.
* `address[] calldata path`: Array of token addresses to trade through.
* `address to`: Address to receive output tokens.
* `uint deadline`: Timestamp after which the transaction will revert.

#### `swapTokensForExactETH`

Swaps tokens for an exact amount of ETH.

Parameters:

* `uint amountOut`: Amount of output ETH.
* `uint amountInMax`: Maximum amount of input tokens.
* `address[] calldata path`: Array of token addresses to trade through.
* `address to`: Address to receive ETH.
* `uint deadline`: Timestamp after which the transaction will revert.

#### `swapExactTokensForETH`

Swaps an exact amount of tokens for ETH.

Parameters:

* `uint amountIn`: Amount of input tokens.
* `uint amountOutMin`: Minimum amount of output ETH.
* `address[] calldata path`: Array of token addresses to trade through.
* `address to`: Address to receive ETH.
* `uint deadline`: Timestamp after which the transaction will revert.

#### `swapETHForExactTokens`

Swaps ETH for an exact amount of tokens.

Parameters:

* `uint amountOut`: Amount of output tokens.
* `address[] calldata path`: Array of token addresses to trade through.
* `address to`: Address to receive output tokens.
* `uint deadline`: Timestamp after which the transaction will revert.

### Read Functions

#### `factory`

Returns the address of the factory contract.

Parameters: None

Returns:

* `address`: Address of the factory contract.

Description: Retrieves the address of the factory contract used to create pairs of tokens.

#### `WETH`

Returns the address of the WETH token.

Parameters: None

Returns:

* `address`: Address of the WETH token.

Description: Retrieves the address of the Wrapped ETH (WETH) token used in the router.

#### `quote`

Calculates the amount of token B given an amount of token A and reserves.

Parameters:

* `uint amountA`: Amount of token A.
* `uint reserveA`: Reserve amount of token A.
* `uint reserveB`: Reserve amount of token B.

Returns:

* `uint amountB`: Amount of token B.

Description: Computes the equivalent amount of token B given the amount of token A and their respective reserves.

#### `getAmountOut`

Calculates the maximum output amount of the other asset given an input amount and pair reserves.

Parameters:

* `uint amountIn`: Input amount of the asset.
* `uint reserveIn`: Reserve amount of the input asset.
* `uint reserveOut`: Reserve amount of the output asset.

Returns:

* `uint amountOut`: Output amount of the asset.

Description: Determines the maximum output amount of the other asset given the input amount and the pair reserves.

#### `getAmountIn`

Calculates the required input amount of the other asset given an output amount and pair reserves.

Parameters:

* `uint amountOut`: Output amount of the asset.
* `uint reserveIn`: Reserve amount of the input asset.
* `uint reserveOut`: Reserve amount of the output asset.

Returns:

* `uint amountIn`: Input amount of the asset.

Description: Computes the required input amount of the other asset given the output amount and the pair reserves.

#### `getAmountsOut`

Performs chained `getAmountOut` calculations on any number of pairs.

Parameters:

* `uint amountIn`: Input amount of the first asset.
* `address[] memory path`: Array of token addresses to trade through.

Returns:

* `uint[] memory amounts`: Array of output amounts for each step in the path.

Description: Executes a series of `getAmountOut` calculations along a specified path of token pairs.

#### `getAmountsIn`

Performs chained `getAmountIn` calculations on any number of pairs.

Parameters:

* `uint amountOut`: Output amount of the last asset.
* `address[] memory path`: Array of token addresses to trade through.

Returns:

* `uint[] memory amounts`: Array of input amounts for each step in the path.

Description: Executes a series of `getAmountIn` calculations along a specified path of token pairs.

### Events

#### `PairCreated`

Emitted when a new liquidity pair is created.

* **Indexed Parameters**:
  * `address indexed token0`: The address of the first token in the pair.
  * `address indexed token1`: The address of the second token in the pair.
  * `address pair`: The address of the created pair.
* **Non-Indexed Parameters**:
  * `uint`: The length of allPairs array after the pair is created.

#### `Approval`

Emitted when a token approval is made.

* **Indexed Parameters**:
  * `address indexed owner`: The address of the token owner.
  * `address indexed spender`: The address of the spender.
* **Non-Indexed Parameters**:
  * `uint value`: The amount of tokens approved.

#### `Transfer`

Emitted when a token transfer occurs.

* **Indexed Parameters**:
  * `address indexed from`: The address of the sender.
  * `address indexed to`: The address of the recipient.
* **Non-Indexed Parameters**:
  * `uint value`: The amount of tokens transferred.

#### `Mint`

Emitted when liquidity is added to a pool.

* **Indexed Parameters**:
  * `address indexed sender`: The address that initiated the minting.
* **Non-Indexed Parameters**:
  * `uint amount0`: The amount of token0 added.
  * `uint amount1`: The amount of token1 added.

#### `Burn`

Emitted when liquidity is removed from a pool.

* **Indexed Parameters**:
  * `address indexed sender`: The address that initiated the burning.
  * `address indexed to`: The address that received the tokens.
* **Non-Indexed Parameters**:
  * `uint amount0`: The amount of token0 removed.
  * `uint amount1`: The amount of token1 removed.

#### `Swap`

Emitted when a swap occurs in the pool.

* **Indexed Parameters**:
  * `address indexed sender`: The address that initiated the swap.
  * `address indexed to`: The address that received the output tokens.
* **Non-Indexed Parameters**:
  * `uint amount0In`: The amount of token0 input.
  * `uint amount1In`: The amount of token1 input.
  * `uint amount0Out`: The amount of token0 output.
  * `uint amount1Out`: The amount of token1 output.

#### `Sync`

Emitted when reserves are synced in the pool.

* **Non-Indexed Parameters**:
  * `uint112 reserve0`: The reserve of token0.
  * `uint112 reserve1`: The reserve of token1.

#### `Deposit`

Emitted when ETH is deposited to the WETH contract.

* **Indexed Parameters**:
  * `address indexed sender`: The address that deposited ETH.
* **Non-Indexed Parameters**:
  * `uint value`: The amount of ETH deposited.

#### `Withdraw`

Emitted when ETH is withdrawn from the WETH contract.

* **Indexed Parameters**:
  * `address indexed sender`: The address that withdrew ETH.
* **Non-Indexed Parameters**:
  * `uint value`: The amount of ETH withdrawn.


# User Guides


# Providing Liquidity

To provide and manage the pool liquidity, follow the steps below.

### Adding liquidity

* Go to Fathom [DApp](https://dapp.fathom.fi/#/swap/pool).
* Connect your Web3 wallet (such as [MetaMask](https://metamask.io/)) and make sure your network is set to the intended chain (i.e., [XDC](https://chainlist.org/chain/50)).

<figure><img src="/files/Zcq2fcPGxKFt4wQi3qtQ" alt=""><figcaption></figcaption></figure>

***

* There are 2 options for the next action:
  * Creation of Pair - If there is no such token pair yet (you can validate it on the [charts page](https://dapp.fathom.fi/#/charts)), you can click on the "**Create a pair**" button and fill in the amounts of the initial liquidity in the pool.

<div data-full-width="true"><figure><img src="/files/AmCYVYMQvi8R79Noa7xj" alt=""><figcaption></figcaption></figure></div>

* Adding liquidity to existing Pair - If the pair already exists, you can click the "**Add Liquidity**" button, enter the balance of one of the tokens, and the balance of the second one will be automatically calculated based on the current ratio in the pool.

<div data-full-width="true"><figure><img src="/files/gYzPMj0DmRluNUNoyhEP" alt=""><figcaption></figcaption></figure></div>

***

<div data-full-width="true"><figure><img src="/files/MIak9DZFZ0TCqd8cJ9zY" alt=""><figcaption></figcaption></figure></div>

* Click "**Supply**"
  * You may be required to approve the tokens transfer before the actual transfer (depending on your previous approvals).
  * Sign and send the transaction in your Wallet.
  * Wait for the transaction to be processed.
  * Once the transaction has gone through, you'll see your position in "**Your Liquidity"** has either changed, or appeared.

### Removing Liquidity

* Click "Manage" button.

<figure><img src="/files/2LTM4apfuTsldrIeQmIP" alt=""><figcaption></figcaption></figure>

* Clock "Remove" button.

<figure><img src="/files/RTsZII6D8G98kym66N2S" alt=""><figcaption></figcaption></figure>

* You can remove tokens in percentage to your total share of the pool, or use exact amounts by clicking on "Detailed" button

<figure><img src="/files/v0bAoJBVMHpwDitkkzBL" alt=""><figcaption></figcaption></figure>

* Click "**Remove**"
  * You may be required to approve the lp token transfer before the actual transfer (depending on your previous approvals).
  * Sign and send the transaction in your Wallet.
  * Wait for the transaction to be processed.
  * Once the transaction has gone through, you'll see your position in "**Your Liquidity"** has either changed, or disappeared.


# Swapping Assets

To swap assets, follow the steps below.

### Adding liquidity

* Go to Fathom [DApp](https://dapp.fathom.fi/#/swap).
* Connect your Web3 wallet (such as [MetaMask](https://metamask.io/)) and make sure your network is set to the intended chain (i.e., [XDC](https://chainlist.org/chain/50)).

<figure><img src="/files/knrmMD2IEw6nv4I9TIYG" alt=""><figcaption></figcaption></figure>

* Choose assets you want to swap using the drop-down list.

<div data-full-width="true"><figure><img src="/files/UuxnF7lqfj3ozHJjt83l" alt=""><figcaption></figcaption></figure></div>

* Enter assets amounts.

<figure><img src="/files/LxFQXdI1VxwELMlf2JjP" alt=""><figcaption></figcaption></figure>

* Click "**Swap**"
  * You may be required to approve the tokens transfer before the actual transfer (depending on your previous approvals).
  * Sign and send the transaction in your Wallet.
  * Wait for the transaction to be processed.
  * Once the transaction has gone through, you'll see that your wallet token balances have changed.


# Deployments


# XDC Network

## Addresses on XDC mainnet

* Factory: `0x9fAb572F75008A42c6aF80b36Ab20C76a38ABc4B`
* Router: `0x7e5b4c238A904329596c4094877D48868d739963`
* Multicall `0xeDA95e2B6BA4196A428Dc824B4fBd8f6dd39E518`


# DAO

For the complete explanation refer to the [DAO section in Whitepaper.](/whitepaper)

The Fathom DAO (Decentralized Autonomous Organization) plays a crucial role in the governance of the Fathom Protocol. It is designed to empower the community by allowing token holders to participate directly in decision-making processes. This decentralized governance structure ensures that the development and operational aspects of the Fathom Protocol align with the interests and inputs of the community. Through the Fathom DAO, stakeholders can propose, vote on, and implement changes within the protocol, influencing everything from technical adjustments to financial strategies. This engagement helps ensure the protocol remains secure, innovative, and responsive to the needs of its users.


# DAO Structure

### **Governance Token (FTHM)**

The FTHM token serves as the primary utility token within the Fathom DAO. It is used for both governance and staking purposes, enabling holders to participate actively in the protocol's decisions. The distribution of FTHM tokens is aligned with the protocol's goal to encourage long-term engagement and participation.

### **Voting Token (vFTHM)**

FTHM token holders can convert their tokens into vFTHM, which represents their voting power within the DAO. The vFTHM tokens are non-transferable and are used exclusively for voting on proposals within the DAO, ensuring that voting rights are retained by active participants in the ecosystem.

### **Staking Mechanisms**

Staking FTHM tokens not only secures the network but also enhances decentralization and incentivizes token holders by distributing protocol fees and rewards. Stakers receive vFTHM in proportion to the amount of FTHM they stake, increasing their influence in governance decisions proportionally to their stake. This mechanism promotes a stable and secure network governance structure.

### **Governance Mechanisms**

Governance mechanisms are designed to facilitate decentralized decision-making in the DAO. Token holders use their vFTHM to vote on proposals, electing development directions, and protocol upgrades. This structure ensures that the governance process is democratic and aligns with the interests of active participants.

<div data-full-width="true"><figure><img src="/files/PgnJV5dAIRHUNWwOmR07" alt=""><figcaption><p>Fathom DAO</p></figcaption></figure></div>


# Governance Process

### **Proposal Submission**

Any FTHM holder can submit a proposal to the DAO. Proposals can include protocol upgrades, new feature implementations, or changes in governance rules. Proposals must be well-documented and include clear objectives and potential impacts on the ecosystem.

### **Voting Process**

Once a proposal is submitted, it goes through a voting period where vFTHM holders cast their votes. Each vFTHM represents one vote. The proposal requires a certain quorum to be reached and, if approved by a majority, it is implemented.

### **Role of vFTHM in Governance**

vFTHM tokens are crucial in the governance process. Only holders of vFTHM can vote on proposals, ensuring that those who have staked FTHM and have a vested interest in the protocol's success are making the decisions. This system aligns the incentives of active participants with the long-term health and stability of the Fathom DAO.


# Staking Process

### **How to Stake FTHM**

To stake FTHM, users need to deposit their FTHM tokens into the staking contract via the Fathom platform. This process locks the tokens in the contract, allowing users to earn staking rewards and participate in governance.

### **Lock Positions and Unlocking**

Staked FTHM tokens are locked for a predefined period, during which they cannot be withdrawn. After the lock period, users can unlock their tokens by initiating an unlock request, which may have an additional delay before tokens are fully accessible.

### **Rewards and Incentives**

Stakers earn rewards based on the amount of FTHM staked and the duration of the stake. Rewards can include additional FTHM tokens and governance privileges. The incentive structure encourages long-term participation and alignment with the protocol’s success.


# Treasury Management

### **Multi-sig Treasury Operations**

The Fathom DAO treasury is managed through multi-signature wallets. These wallets require multiple authorized signatures to execute transactions, ensuring security and decentralization. This mechanism prevents unilateral control and enhances trust within the community.

### **Use of Treasury Funds**

Treasury funds are utilized for various purposes including development, marketing, ecosystem growth, and other operational expenses. The strategic allocation of these funds aims to support the long-term sustainability and growth of the Fathom ecosystem.

### **Funding Proposals and Distributions**

Members of the DAO can submit proposals for funding from the treasury. These proposals are reviewed and voted on by the community. Upon approval, funds are distributed according to the proposal's specifications. This process ensures transparent and democratic management of the DAO’s resources.


# Risk Management and Security Measures

**Oversight and Emergency Measures**

Fathom DAO employs continuous oversight through dedicated committees to monitor and manage risks. In case of emergencies, predefined protocols allow for quick and effective responses, including temporary pauses in operations and activating security measures to protect the protocol and its assets.

**Updating and Upgrading Governance Protocols**

Governance protocols are regularly reviewed and updated to adapt to new challenges and opportunities. This includes implementing security patches, enhancing smart contract functionality, and ensuring compliance with industry best practices. Community members are involved in the decision-making process through proposals and votes, maintaining transparency and collective responsibility.


# Contributing to Fathom DAO

**How to Become Involved**

To become involved in Fathom DAO, start by joining the community channels, such as the official Telegram and X(Twitter). Participate in discussions, stay updated on the latest proposals, and contribute your ideas. You can also acquire FTHM tokens to participate in governance and staking activities.

**Community Roles and Responsibilities**

Members can take on various roles, including:

* **Contributors:** Propose and develop new features or improvements.
* **Voters:** Participate in the governance process by voting on proposals.
* **Stakers:** Stake FTHM tokens to support the network and earn rewards.
* **Moderators:** Help manage community discussions and enforce guidelines.

Each role comes with responsibilities, ensuring the smooth operation and growth of the DAO through active and constructive participation.


# Interfaces


# FTHM

https\://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/master/contracts/dao/tokens/MainToken.sol

The `MainToken` contract is an ERC-20 token that includes standard functionalities for managing token balances, allowances, and transfers, following the OpenZeppelin library's specifications. It allows the minting of the initial supply upon deployment, which is assigned to a specified issuer. The contract also manages approvals and transfers from one account to another while ensuring that these operations adhere to the established ERC-20 standard, including handling edge cases like transfers to the zero address and ensuring sufficient balances and allowances for transfers and approvals.

### Set Functions

#### transfer

* **Parameters:**
  * **to** (`address`): The address to transfer tokens to.
  * **amount** (`uint256`): The number of tokens to transfer.
* **Returns:**
  * **bool**: Returns `true` if the transfer was successful.
* **Description:** Transfers a specified amount of tokens from the caller's address to the specified address. Emits a `Transfer` event if successful.

#### approve

* **Parameters:**
  * **spender** (`address`): The address which will spend the funds.
  * **amount** (`uint256`): The amount of tokens they are allowed to spend.
* **Returns:**
  * **bool**: Returns `true` if the approval was successful.
* **Description:** Approves another address to spend a specified amount of tokens on behalf of the caller. Emits an `Approval` event.

#### transferFrom

* **Parameters:**
  * **from** (`address`): The address to transfer tokens from.
  * **to** (`address`): The address to transfer tokens to.
  * **amount** (`uint256`): The number of tokens to transfer.
* **Returns:**
  * **bool**: Returns `true` if the transfer was successful.
* **Description:** Transfers a specified amount of tokens from one address to another, using the allowance mechanism. The caller must have a sufficient allowance from the `from` address. Emits a `Transfer` event.

#### increaseAllowance

* **Parameters:**
  * **spender** (`address`): The address which will spend the funds.
  * **addedValue** (`uint256`): The additional amount of tokens they are allowed to spend.
* **Returns:**
  * **bool**: Returns `true` if the operation was successful.
* **Description:** Increases the allowance granted to another address by the caller. This is an alternative to calling `approve` for modifying allowances.

#### decreaseAllowance

* **Parameters:**
  * **spender** (`address`): The address which will spend the funds.
    * **subtractedValue** (`uint256`): The amount to decrease the allowance by.
* **Returns:**
  * **bool**: Returns `true` if the operation was successful.
* **Description:** Decreases the allowance granted to another address by the caller. This function will revert if the current allowance is less than the subtracted value.

### Read Functions

#### name

* **Parameters**: None
* **Returns**:
  * **string**: The name of the token.
* **Description**: Returns the name of the token as set during the contract initialization.

#### symbol

* **Parameters**: None
* **Returns**:
  * **string**: The symbol of the token.
* **Description**: Returns the symbol of the token, used typically as a ticker-like identifier.

#### decimals

* **Parameters**: None
* **Returns**:
  * **uint8**: The number of decimals the token uses.
* **Description**: Returns the number of decimals used by the token for display and calculations. Standard ERC-20 tokens typically use 18 decimals.

#### balanceOf

* **Parameters**:
  * **account** (`address`): The address to query the balance of.
* **Returns**:
  * **uint256**: The number of tokens owned by the `account`.
* **Description**: Queries the balance of the specified address. Returns the amount of tokens that the address currently holds.

#### totalSupply

* **Parameters**: None
* **Returns**:
  * **uint256**: The total token supply.
* **Description**: Returns the total amount of tokens in existence.

#### allowance

* **Parameters**:
  * **owner** (`address`): The address of the owner of the tokens.
  * **spender** (`address`): The address of the spender allowed to use the tokens.
* **Returns**:
  * **uint256**: The remaining number of tokens that the spender will be allowed to spend on behalf of the owner.
* **Description**: Returns the remaining number of tokens that the spender is allowed to spend on behalf of the owner through `transferFrom`.

### Events

#### Transfer

* **Parameters**:
  * **from** (`address`): The address transferring the tokens.
  * **to** (`address`): The address receiving the tokens.
  * **value** (`uint256`): The amount of tokens being transferred.
* **Description**: Emitted when `value` tokens are moved from one account (`from`) to another (`to`).

#### Approval

* **Parameters**:
  * **owner** (`address`): The address of the token owner.
  * **spender** (`address`): The address approved to spend the tokens.
  * **value** (`uint256`): The amount of tokens approved for spending.
* **Description**: Emitted when `owner` approves `spender` to spend `value` tokens on their behalf.


# Staking

[`StakingProxy`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/master/contracts/common/proxy/StakingProxy.sol) is proxy, and its implementation is [`StakingPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/master/contracts/dao/staking/packages/StakingPackage.sol).

The Staking Package is designed for creating and managing staking streams, handling user stakes with the ability to lock and unlock tokens, and calculating rewards. The contract allows for the addition of new staking streams, each with unique parameters like reward schedules and lock periods. It also enforces rules around the early withdrawal of stakes, calculating penalties, and distributing rewards, ensuring a robust and flexible staking environment.

### State Variables

#### **`mainStreamInitialized`**:

* Type: `bool`
* Description: Indicates whether the main stream has been initialized.

#### **`MAIN_STREAM`**:

* Type: `uint256`
* Description: The constant identifier for the main staking stream.

#### **`streams`**:

* Type: `Stream[]`
* Description: Dynamic array storing all streams available for staking.

#### **`locks`**:

* Type: `mapping(address => LockedBalance[])`
* Description: Maps user addresses to their respective locked balances.

#### **`users`**:

* Type: `mapping(address => User)`
* Description: Maps user addresses to their staking-related data.

#### **`streamTotalUserPendings`**:

* Type: `mapping(uint256 => uint256)`
* Description: Maps stream IDs to total pending tokens for users.

#### **`prohibitedEarlyWithdraw`**:

* Type: `mapping(address => mapping(uint256 => bool))`
* Description: Tracks locks that cannot be unlocked early.

#### **`totalAmountOfStakedToken`**, **`totalStreamShares`**, **`totalAmountOfVoteToken`**:

* Type: `uint256`
* Description: Track the total amounts of staked tokens, stream shares, and vote tokens across all users.

#### **`totalPenaltyBalance`**:

* Type: `uint256`
* Description: Sum of all penalties collected from early withdrawals.

#### **`vault`**, **`treasury`**, **`rewardsCalculator`**, **`mainToken`**, **`voteToken`**:

* Type: `address`
* Description: Addresses of contracts for the vault, treasury, rewards calculation, main token, and voting token.

#### **`minLockPeriod`**, **`maxLockPeriod`**:

* Type: `uint256`
* Description: The minimum and maximum lock periods for staking tokens.

#### **`maxLockPositions`**:

* Type: `uint256`
* Description: Maximum number of lock positions a user can have.

### **Structs**

#### **Schedule**:

* `time`: An array of timestamps indicating the start of each reward distribution interval. The last timestamp marks the stream's end.
* `reward`: An array parallel to `time`, specifying the amount of rewards at the start of each interval. The final entry is always zero, marking the end of rewards.

#### **User**:

* `voteTokenBalance`: Represents the total balance of voting tokens a user possesses.
* `pendings`: A mapping from a stream ID to the amount of tokens pending release for the user.
* `releaseTime`: A mapping from a stream ID to the timestamp when tokens are scheduled for release.
* `rpsDuringLastClaimForLock`: Nested mappings from stream ID and lock ID to the reward-per-share value noted at the last claim.

#### **Weight**:

* `maxWeightShares`, `minWeightShares`: Used to calculate the share weight over time from maximum to minimum.
* `maxWeightPenalty`, `minWeightPenalty`, `penaltyWeightMultiplier`: Parameters for calculating early withdrawal penalties.

#### **VoteCoefficient**:

* `voteShareCoef`, `voteLockCoef`: Coefficients influencing the voting power derived from token shares and lock duration, respectively.

#### **LockedBalance**:

* `amountOfToken`, `positionStreamShares`: Tokens locked and shares of the position within a stream, respectively.
* `end`: The expiration of the lock.
* `owner`: The owner of the lock.
* `amountOfVoteToken`: Amount of vote tokens reflecting the voting power from this lock.

#### **Stream**:

* Contains properties such as the owner, the manager, reward token type, status, financial thresholds, schedule data, and others. Status is managed through an enum (`StreamStatus`), which tracks if a stream is active, proposed, or inactive.

#### **CreateLockParams**:

* Details required to create a lock: `amount` of tokens, `lockPeriod`, and the `account` the lock is associated with.

### Set Functions

#### **`createLock`**

* **Arguments**:
  * `uint256 amount`: The amount of tokens to be locked.
  * `uint256 lockPeriod`: The period for which the tokens are locked.
* **Returns**:
  * No return value. This function processes the locking of tokens and interacts with the internal state.

#### **`unlock`**

* **Arguments**:
  * `uint256 lockId`: The identifier of the lock to be unlocked.
* **Returns**:
  * No return value. This function processes the unlocking of tokens, updating the internal state to reflect the change.

#### **`unlockPartially`**

* **Arguments**:
  * `uint256 lockId`: The identifier of the lock to be partially unlocked.
  * `uint256 amount`: The amount of tokens to unlock from the specified lock.
* **Returns**:
  * No return value. This function allows partial unlocking of locked tokens and modifies the internal state accordingly.

#### **`earlyUnlock`**

* **Arguments**:
  * `uint256 lockId`: The identifier of the lock to be unlocked early.
* **Returns**:
  * No return value. It handles the early unlocking process, adjusting the user's locked tokens and any applicable penalties.

#### **`claimAllStreamRewardsForLock`**

* **Arguments**:
  * `uint256 lockId`: The identifier of the lock for which all stream rewards are claimed.
* **Returns**:
  * No return value. This function processes the claiming of all rewards associated with a particular lock.

#### **`claimAllLockRewardsForStream`**

* **Arguments**:
  * `uint256 streamId`: The identifier of the stream for which all rewards for all locks are claimed.
* **Returns**:
  * No return value. It handles the claiming of rewards for all locks associated with a specific stream.

#### **`withdrawStream`**

* **Arguments**:
  * `uint256 streamId`: The identifier of the stream from which to withdraw rewards.
* **Returns**:
  * No return value. This function processes the withdrawal of rewards from a specific stream.

#### **`withdrawAllStreams`**

* **Arguments**:
  * None.
* **Returns**:
  * No return value. This function facilitates the withdrawal of rewards from all streams associated with the caller.

### Events

#### **`Staked`**

* **Emitted when**: A new lock is created and tokens are staked.
* **Parameters**:
  * `address indexed account`: The account that staked tokens.
  * `uint256 amount`: The amount of tokens staked.
  * `uint256 streamShares`: Shares received in the stream due to staking.
  * `uint256 nVoteToken`: Number of voting tokens allocated.
  * `uint256 indexed lockId`: The identifier of the lock.
  * `uint256 end`: When the lock will end.

#### **`StreamProposed`**

* **Emitted when**: A new stream is proposed.
* **Parameters**:
  * `uint256 indexed streamId`: Identifier of the proposed stream.
  * `address indexed streamOwner`: The owner of the stream.
  * `address indexed rewardToken`: The token used for rewards in the stream.
  * `uint256 maxDepositAmount`: The maximum amount that can be deposited in the stream.

#### **`Released`**

* **Emitted when**: Tokens are released from a stream.
* **Parameters**:
  * `uint256 indexed streamId`: The stream from which tokens are released.
  * `address indexed user`: The user receiving the released tokens.
  * `uint256 pendingAmount`: The amount of tokens released.

#### **`StreamProposalCancelled`**

* **Emitted when**: A proposed stream is cancelled.
* **Parameters**:
  * `uint256 indexed streamId`: The stream that was cancelled.
  * `address indexed owner`: Owner of the stream.
  * `address indexed token`: The reward token associated with the cancelled stream.

#### **`StreamCreated`**

* **Emitted when**: A stream is created and becomes active.
* **Parameters**:
  * `uint256 indexed streamId`: The identifier of the created stream.
  * `address indexed owner`: The owner of the stream.
  * `address indexed token`: The reward token of the stream.
  * `uint256 tau`: The pending time prior reward release for the stream.

#### **`StreamRemoved`**

* **Emitted when**: A stream is removed.
* **Parameters**:
  * `uint256 indexed streamId`: The identifier of the removed stream.
  * `address indexed owner`: The owner of the stream.
  * `address indexed token`: The reward token of the removed stream.

#### **`Unstaked`**

* **Emitted when**: A full unlock is performed on a lock.
* **Parameters**:
  * `address indexed account`: The account that unstaked tokens.
  * `uint256 amount`: The amount of tokens unstaked.
  * `uint256 indexed lockId`: The identifier of the lock from which tokens were unstaked.

#### **`PartialUnstaked`**

* **Emitted when**: A partial unlock is performed on a lock.
* **Parameters**:
  * `address indexed account`: The account that partially unstaked tokens.
  * `uint256 amount`: The amount of tokens unstaked.
  * `uint256 indexed lockId`: The identifier of the lock from which tokens were partially unstaked.

#### **`Pending`**

* **Emitted when**: Rewards are moved to pending for a user in a stream.
* **Parameters**:
  * `uint256 indexed streamId`: The stream where rewards are pending.
  * `address indexed account`: The user for whom rewards are pending.
  * `uint256 pendings`: Amount of tokens that are pending.


# Vault

https\://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/master/contracts/dao/staking/vault/packages/VaultPackage.sol

[`VaultProxy`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/master/contracts/common/proxy/VaultProxy.sol) is proxy, and its implementation is [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/master/contracts/dao/staking/vault/packages/VaultPackage.sol).

The `VaultPackage` contract manages the operations and state related to supported tokens and their deposits within the vault. It handles the addition and removal of tokens, depositing of tokens for rewards, and managing migration of tokens to a new vault package.

### **State Variables:**

#### **deposited (mapping(address => uint256))**

* Description: Tracks the total amount of each token that has been deposited into the vault.
* Key: Token address.
* Value: Amount deposited.

#### **isSupportedToken (mapping(address => bool))**

* Description: Indicates whether a token is supported by the vault.
* Key: Token address.
* Value: Boolean indicating support.

#### **listOfSupportedTokens (address\[])**

* Description: An array of token addresses that are currently supported by the vault.

#### **migrated (bool)**

* Description: A boolean flag indicating if the vault has been migrated to a new package.

### **Set Functions:**

#### **deposit(address \_token, uint256 \_amount)**

* Deposits a specified amount of a supported token into the vault.
* Parameters:
  * `_token` (address): The token's address.
  * `_amount` (uint256): Amount of the token to deposit.
* Returns: None.

#### **payRewards(address \_user, address \_token, uint256 \_amount)**

* Pays out rewards to a user from the deposited tokens.
* Parameters:
  * `_user` (address): The user's address.
  * `_token` (address): The token's address.
  * `_amount` (uint256): Amount of the token to pay out.
* Returns: None.

#### **addSupportedToken(address \_token)**

* Adds a token to the list of supported tokens.
* Parameters:
  * `_token` (address): The token's address.
* Returns: None.

#### **removeSupportedToken(address \_token)**

* Removes a token from the list of supported tokens.
* Parameters:
  * `_token` (address): The token's address.
* Returns: None.

#### **migrate(address newVaultPackage)**

* Migrates the vault to a new package.
* Parameters:
  * `newVaultPackage` (address): The new vault package's address.
* Returns: None.

#### **withdrawExtraSupportedTokens(address \_withdrawTo)**

* Withdraws excess balances of supported tokens.
* Parameters:
  * `_withdrawTo` (address): Address to which the tokens will be withdrawn.
* Returns: None.

#### **withdrawExtraUnsupportedToken(address \_token, address \_withdrawTo)**

* Withdraws all balances of an unsupported token.
* Parameters:
  * `_token` (address): The token's address.
  * `_withdrawTo` (address): Address to which the tokens will be withdrawn.
* Returns: None.

### **Events:**

#### **TokenAdded**

* Emitted when a token is added to the list of supported tokens.
* Parameters:
  * `tokenAddress` (address indexed): Address of the token added.
  * `addedBy` (address indexed): Address of the user who added the token.
  * `timestamp` (uint256): Time at which the token was added.

#### **TokenRemoved**

* Emitted when a token is removed from the list of supported tokens.
* Parameters:
  * `tokenAddress` (address indexed): Address of the token removed.
  * `removedBy` (address indexed): Address of the user who removed the token.
  * `timestamp` (uint256): Time at which the token was removed.


# RewardsCalculator

https\://github.com/Into-the-Fathom/fathom-dao-smart-contracts/tree/master/contracts/dao/staking/packages

The `RewardsCalculator` contract, a component of the Fathom DAO Staking, is designed to handle and calculate rewards distribution for staking activities. It leverages a detailed schedule system to determine rewards over different time frames, ensuring flexibility and accuracy in reward calculations. It also includes functionality to handle errors related to inputs and state conditions rigorously, thus maintaining the integrity and robustness of the rewards distribution mechanism.

### Storage Variables

#### **`MAXIMUM_PERCENT_TO_TREASURY`**

* **Type:** `uint256`
* **Visibility:** `public constant`
* **Description:** Represents the maximum allowable percentage of rewards that can be allocated to the treasury, set at 10,000 to represent 100% using a base-10000 system for precision.

### Read Functions

#### **`validateStreamParameters`**

* **Arguments:**
  * `address streamOwner` - The owner of the reward stream.
  * `address rewardToken` - The token used for rewards.
  * `uint256 percentToTreasury` - The percentage of rewards directed to the treasury.
  * `uint256 maxDepositAmount` - The maximum deposit amount allowed.
  * `uint256 minDepositAmount` - The minimum deposit amount required.
  * `uint256[] scheduleTimes` - An array of times defining the reward schedule.
  * `uint256[] scheduleRewards` - Corresponding rewards for each scheduled time.
  * `uint256 tau` - A specific parameter used in reward calculations.
* **Return Values:** None. Reverts on validation failure with specific errors.

#### **`getRewardsAmount`**

* **Arguments:**
  * `Schedule calldata schedule` - The reward schedule details.
  * `uint256 lastUpdate` - The last update time for calculating incremental rewards.
* **Return Values:**
  * `uint256` - The amount of rewards calculated based on the schedule and time updates.


# vFTHM

https\://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/master/contracts/dao/tokens/VMainToken.sol

vFTHM is a specialized governance token designed for the Fathom protocol. It incorporates features from several OpenZeppelin libraries, providing advanced functionality such as role-based access control, pausing capabilities, and permit-based approvals. The token is non-transferable unless the sender is on an allowlist, ensuring security and control over token transfers. The token's minting and burning capabilities are restricted to accounts with the minter role, which can be dynamically granted or revoked by an admin. This setup ensures that only authorized accounts can manage the token supply while maintaining strict control over token operations.

**Setter Functions**

#### transfer(address to, uint256 amount)

* **Parameters:**
  * `to`: The address of the recipient.
  * `amount`: The number of tokens to transfer.
* **Returns:**
  * `bool`: Whether the transfer was successful.
* **Description:** Transfers tokens to a specified address.

#### approve(address spender, uint256 amount)

* **Parameters:**
  * `spender`: The address of the spender.
  * `amount`: The number of tokens to approve.
* **Returns:**
  * `bool`: Whether the approval was successful.
* **Description:** Approves the specified number of tokens for spending by the spender.

#### transferFrom(address from, address to, uint256 amount)

* **Parameters:**
  * `from`: The address of the sender.
  * `to`: The address of the recipient.
  * `amount`: The number of tokens to transfer.
* **Returns:**
  * `bool`: Whether the transfer was successful.
* **Description:** Transfers tokens from one specified address to another.

#### pause()

* **Parameters:** None
* **Returns:** None
* **Description:** Pauses all token transfers and minting functions, putting the contract in a paused state.

#### unpause()

* **Parameters:** None
* **Returns:** None
* **Description:** Unpauses all token transfers and minting functions, resuming normal contract operations.

**Getter Functions**

#### name()

* **Parameters:** None
* **Returns:**
  * `string`: The name of the token.
* **Description:** Returns the name of the token as set during the contract initialization.

#### symbol()

* **Parameters:** None
* **Returns:**
  * `string`: The symbol of the token.
* **Description:** Returns the symbol of the token as set during the contract initialization.

#### decimals()

* **Parameters:** None
* **Returns:**
  * `uint8`: The number of decimal places the token uses.
* **Description:** Returns the number of decimal places used to get its user representation.

#### totalSupply()

* **Parameters:** None
* **Returns:**
  * `uint256`: The total supply of the token.
* **Description:** Returns the total supply of the token.

#### balanceOf(address account)

* **Parameters:**
  * `account`: The address of the token holder.
* **Returns:**
  * `uint256`: The balance of the specified address.
* **Description:** Returns the token balance of the specified address.

#### allowance(address owner, address spender)

* **Parameters:**
  * `owner`: The address of the token owner.
  * `spender`: The address of the spender.
* **Returns:**
  * `uint256`: The remaining number of tokens that the spender is allowed to spend on behalf of the owner.
* **Description:** Returns the remaining number of tokens that the spender is allowed to spend on behalf of the owner.

#### paused()

* **Parameters:** None
* **Returns:**
  * `bool`: Whether the contract is paused.
* **Description:** Returns whether the contract is in a paused state.

#### nonces(address owner)

* **Parameters:**
  * `owner`: The address to check.
* **Returns:**
  * `uint256`: The current nonce for the address.
* **Description:** Returns the current nonce for an address, used for permit functions.

#### checkpoints(address account, uint32 pos)

* **Parameters:**
  * `account`: The address to check.
  * `pos`: The position of the checkpoint.
* **Returns:**
  * `Checkpoint`: The checkpoint data.
* **Description:** Returns the checkpoint for an address at a specific position.

#### numCheckpoints(address account)

* **Parameters:**
  * `account`: The address to check.
* **Returns:**
  * `uint32`: The number of checkpoints for the address.
* **Description:** Returns the number of checkpoints for an address.

#### getVotes(address account)

* **Parameters:**
  * `account`: The address to check.
* **Returns:**
  * `uint256`: The current voting power of the address.
* **Description:** Returns the current voting power of an address.

#### getPastVotes(address account, uint256 blockNumber)

* **Parameters:**
  * `account`: The address to check.
  * `blockNumber`: The block number to check.
* **Returns:**
  * `uint256`: The voting power of the address at the specified block number.
* **Description:** Returns the voting power of an address at a specific block.

#### getPastTotalSupply(uint256 blockNumber)

* **Parameters:**
  * `blockNumber`: The block number to check.
* **Returns:**
  * `uint256`: The total supply of tokens at the specified block number.
* **Description:** Returns the total supply of tokens at a specific block.

#### delegates(address account)

* **Parameters:**
  * `account`: The address to check.
* **Returns:**
  * `address`: The delegatee of the address.
* **Description:** Returns the delegatee of an address.

### Events

#### Transfer

* **Parameters:**
  * `address indexed from`: The address from which tokens are transferred.
  * `address indexed to`: The address to which tokens are transferred.
  * `uint256 value`: The number of tokens transferred.
* **Description:** Emitted when tokens are transferred from one address to another, including zero value transfers.

#### Approval

* **Parameters:**
  * `address indexed owner`: The address of the token owner.
  * `address indexed spender`: The address of the spender.
  * `uint256 value`: The new allowance granted by the owner.
* **Description:** Emitted when the allowance of a spender for an owner is set by a call to `approve`. This event indicates the amount of tokens the spender is allowed to transfer from the owner’s account.


# Governance

https\://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/master/contracts/dao/governance/MainTokenGovernor.sol

The `MainTokenGovernor` is an advanced governance contract integrates multiple functionalities including proposal management, token governance, timelock control, and emergency stops. It extends several OpenZeppelin contracts to create a robust governance framework.

### Structs

#### **ProposalCore**

* `voteStart` (Timers.BlockNumber): The block number marking the start of the voting period.
* `voteEnd` (Timers.BlockNumber): The block number marking the end of the voting period.
* `executed` (bool): Indicates whether the proposal has been executed.
* `canceled` (bool): Indicates whether the proposal has been canceled.
* `expireTimestamp` (uint256): A timestamp after which the proposal can no longer be executed.

### Storage Variables

#### **`isSupportedToken`** (mapping(address => bool)): Tracks whether a token is supported for operations like relay or recovery.

#### **`listOfSupportedTokens`** (address\[]): A dynamic list of all tokens that have been added as supported, allowing for enumeration and iteration through supported tokens.

#### **`isConfirmed`** (mapping(uint256 => bool)): Maps proposal IDs to their confirmation status, indicating whether a proposal has been confirmed by the multisig.

#### **`isProposalExecuted`** (mapping(uint256 => bool)): Maps proposal IDs to a boolean indicating whether they have been executed. Ensures a proposal can't be executed more than once.

### Set Functions

#### **`relayERC20`**

* Arguments:
  * `target` (address): The address of the token to relay.
  * `data` (bytes): The data payload for the relay transaction.
* Description: Allows the governance system to relay ERC20 tokens that might have been sent to the contract by mistake. It ensures only supported tokens can be relayed.

#### **`relayNativeToken`**

* Arguments:
  * `target` (address): The address of the recipient or contract.
  * `value` (uint256): The amount of native tokens (e.g., ETH) to send.
  * `data` (bytes): The data payload for the relay transaction.
* Description: Similar to `relayERC20` but for native blockchain tokens like ETH, ensuring that any mistakenly sent native tokens can be returned or used in governance operations.

**`propose`**

* Arguments:
  * `targets` (address\[]): Addresses of contracts called under the proposal.
  * `values` (uint256\[]): List of values (in wei) for each call.
  * `calldatas` (bytes\[]): Calldata to be sent to each target.
  * `description` (string): Human-readable description of the proposal.
* Returns: `uint256` (proposalId)
* Description: Initiates a new proposal in the governance system.

**`cancelProposal`**

* Arguments:
  * `targets` (address\[])
  * `values` (uint256\[])
  * `calldatas` (bytes\[])
  * `descriptionHash` (bytes32)
* Returns: `uint256`
* Description: Cancels a proposal, can only be accessed by Multisig.

**`emergencyStop`**

* Description: Halts all contract functions effectively, only callable by Multisig, can also recover and send all supported tokens and native tokens to the multisig's address.

**`addSupportingToken`**

* Arguments:
  * `_token` (address): Address of the token to add as supported.
* Description: Adds a token to the list of supported tokens for relay or recovery operations.

**`removeSupportingToken`**

* Arguments:
  * `_token` (address): Address of the token to remove from supported list.
* Description: Removes a token from the list of supported tokens, disallowing any future relay or recovery operations for it.

### Events

#### **`TokenSupported`**

* **Arguments:** None.
* **Description:** Emitted when a token is added to the list of supported tokens for relay operations.

#### **`TokenUnsupported`**

* **Arguments:** None.
* **Description:** Emitted when a token is removed from the list of supported tokens.

#### **`ProposalQueued`**

* **Parameters:**
  * **proposalId** (uint256): ID of the proposal that has been queued.
  * **eta** (uint256): Estimated time of execution for the proposal.
* **Description:** Emitted when a proposal is successfully queued in the timelock to be executed later.

#### **`ProposalExecuted`**

* **Parameters:**
  * **proposalId** (uint256): ID of the proposal that has been executed.
* **Description:** Emitted when a proposal is successfully executed.

#### **`ConfirmProposal`**

* **Parameters:**
  * **signer** (address): Address of the signer who confirmed the proposal.
  * **proposalId** (uint256): ID of the confirmed proposal.
* **Description:** Emitted when a proposal is confirmed by a multisig signer.

#### **`RevokeConfirmation`**

* **Parameters:**
  * **signer** (address): Address of the signer who revoked the confirmation.
  * **proposalId** (uint256): ID of the proposal whose confirmation was revoked.
* **Description:** Emitted when the confirmation of a proposal is revoked by a multisig signer.

#### **`MaxTargetUpdated`**

* **Parameters:**
  * **newMaxTargets** (uint256): New maximum number of targets allowed in a proposal.
  * **oldMaxTargets** (uint256): Old maximum number of targets that was previously allowed.
* **Description:** Emitted when the maximum number of targets that can be included in a proposal is updated.

#### **`ProposalLifetimeUpdated`**

* **Parameters:**
  * **newProposalLifetime** (uint256): The new duration (in seconds) that a proposal remains valid.
  * **oldProposalLifetime** (uint256): The old duration that a proposal was valid.
* **Description:** Emitted when the lifespan of proposals is updated.

#### **`BlocklistStatusUpdated`**

* **Parameters:**
  * **account** (address): Address of the account whose blocklist status was updated.
  * **isBlocklisted** (bool): New blocklist status of the account.
* **Description:** Emitted when the blocklist status of an account is updated to either restrict or allow proposal creation by that account.


# TimelockController

https\://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/master/contracts/dao/governance/TimelockController.sol

The `TimelockController` is a contract designed to add a delay between the initiation and execution of governance proposals as a security measure. It ensures that actions intended by governance are delayed by a minimum time period (configurable), allowing the community to prepare or respond to upcoming changes. This contract operates with role-based permissions for proposing, executing, and canceling scheduled operations. It supports batch operations and manages operational prerequisites to ensure that proposals are executed in the correct sequence and timing

### Set Functions

#### **schedule**

* **Arguments:**
  * **target** (address): The target address for the operation.
  * **value** (uint256): The amount of ether to send with the operation.
  * **data** (bytes): The data payload for the operation.
  * **predecessor** (bytes32): The identifier of the preceding operation.
  * **salt** (bytes32): A salt to ensure uniqueness of the operation's hash.
  * **delay** (uint256): The delay before the operation can be executed.
* **Description:** Schedules an operation to be executed after a specified delay.

#### **scheduleBatch**

* **Arguments:**
  * **targets** (address\[]): Array of target addresses for the batch operation.
  * **values** (uint256\[]): Array of ether amounts to send with each operation.
  * **payloads** (bytes\[]): Array of data payloads for each operation.
  * **predecessor** (bytes32): The identifier of the preceding operation.
  * **salt** (bytes32): A salt to ensure uniqueness of the batch operation's hash.
  * **delay** (uint256): The delay before the batch operation can be executed.
* **Description:** Schedules a batch of operations to be executed after a specified delay.

#### **cancel**

* **Arguments:**
  * **id** (bytes32): The unique identifier of the operation to cancel.
* **Description:** Cancels a scheduled operation.

#### **execute**

* **Arguments:**
  * **target** (address): The target address for the operation.
  * **value** (uint256): The amount of ether to send with the operation.
  * **payload** (bytes): The data payload for the operation.
  * **predecessor** (bytes32): The identifier of the preceding operation.
  * **salt** (bytes32): A salt to ensure uniqueness of the operation's hash.
* **Description:** Executes a scheduled operation if it is ready and all prerequisites are met.

#### **executeBatch**

* **Arguments:**
  * **targets** (address\[]): Array of target addresses for the batch operation.
  * **values** (uint256\[]): Array of ether amounts to send with each operation.
  * **payloads** (bytes\[]): Array of data payloads for each operation.
  * **predecessor** (bytes32): The identifier of the preceding operation.
  * **salt** (bytes32): A salt to ensure uniqueness of the batch operation's hash.
* **Description:** Executes a batch of scheduled operations if they are ready and all prerequisites are met.

#### **updateDelay**

* **Arguments:**
  * **newDelay** (uint256): The new minimum delay for operations to be executed.
* **Description:** Updates the minimum delay for all future operations.

#### **grantRoleByAdmin**

* **Arguments:**
  * **role** (bytes32): The role identifier.
  * **account** (address): The address to be granted the role.
* **Description:** Grants a specified role to an account, callable only by admin.

#### **revokeRoleByAdmin**

* **Arguments:**
  * **role** (bytes32): The role identifier.
  * **account** (address): The address from which to revoke the role.
* **Description:** Revokes a specified role from an account, callable only by admin.

### Events

#### **CallScheduled**

* **Parameters:**
  * **id** (bytes32): Unique identifier of the operation.
  * **index** (uint256): Index of the specific call in the batch operation.
  * **target** (address): Address of the contract targeted by the call.
  * **value** (uint256): Ether value, in wei, to be sent with the call.
  * **data** (bytes): Data payload to be sent to the target.
  * **predecessor** (bytes32): Identifier of the operation that must be completed before this one.
  * **delay** (uint256): Delay before the operation becomes valid.
* **Description:** Emitted when an operation is scheduled.

#### **CallExecuted**

* **Parameters:**
  * **id** (bytes32): Unique identifier of the executed operation.
  * **index** (uint256): Index of the specific call in the batch operation.
  * **target** (address): Address of the contract targeted by the call.
  * **value** (uint256): Ether value, in wei, used in the call.
  * **data** (bytes): Data payload sent to the target.
* **Description:** Emitted when an operation is successfully executed.

#### **Cancelled**

* **Parameters:**
  * **id** (bytes32): Unique identifier of the operation that was cancelled.
* **Description:** Emitted when a scheduled operation is cancelled.

#### **MinDelayChange**

* **Parameters:**
  * **oldDuration** (uint256): Previous minimum delay before operations can be executed.
  * **newDuration** (uint256): New minimum delay before operations can be executed.
* **Description:** Emitted when the minimum delay for operations is changed.

#### **ExecuteTransaction**

* **Parameters:**
  * **owner** (address): Address initiating the transaction.
  * **success** (bool): Status of the transaction execution.
  * **data** (bytes): Data payload used in the transaction.
* **Description:** Emitted after an execution attempt, detailing the result.


# Deployments


# XDC Network

## Addresses on XDC mainnet

* FTHMToken: `0x3279dBEfABF3C6ac29d7ff24A6c46645f3F4403c`
* vFTHM: `0xB27c3FD774B1a1FbBc17b9E2b62846499Db08A05`
* Staking: `0xCEb16f0de63c006470ED2De9beb7c7dBd47D7437`
* TimelockController: `0xDC44ED5315Cf856E4Ab0915443fbA2A68DF98EC5`
* Governor: `0x81F50223c851DE9A6068c1B7A37aA253227952B0`
* RewardsCalculator: `0x2E12f56b158c2dcf811fda9642755B3929e03a56`
* Vault: `0x4f9592A17a1D4716bfBdF2e221a737f862d00c03`


# User Guides


# Staking

To deposit and then withdraw your FXD in the Vault, follow the steps below:

* Go to Fathom [DApp](https://dapp.fathom.fi/#/dao/staking).
* Connect your Web3 wallet (such as [MetaMask](https://metamask.io/)) and make sure your network is set to the intended chain (i.e., [XDC](https://chainlist.org/chain/50)).

<div data-full-width="true"><figure><img src="/files/QpsCX3EfbppfHpEdidqB" alt=""><figcaption></figcaption></figure></div>

* Enter the amount of FTHM you would like to deposit and lock period. During lock period you can't withdraw tokens without a significant penalty, but you will be receiving more rewards and voting power.
* Click "**Stake**"
  * You may be required to approve the FTHM transfer before the actual transfer (depending on your previous deposits).
  * Sign and send the transaction in your Wallet.
  * Wait for the transaction to be processed.
  * Once the transaction has gone through, you'll see your position in "**My Positions"** on the same page.

<div data-full-width="true"><figure><img src="/files/lIVcLum3VhqZrZzqwzJ2" alt=""><figcaption></figcaption></figure></div>

* If the lock period has passed for the position, you can "**Unstake**" without penalties. You can choose how many tokens you want to unstake.

<div data-full-width="true"><figure><img src="/files/FT3TjJlrR7wdL7WLQyV0" alt=""><figcaption></figcaption></figure></div>

* Otherwise, you can use "**Early Unstake**", which will result in token loss. You can do it only for the full amount of the tokens minus the penalty.

<div data-full-width="true"><figure><img src="/files/RDsavbacl3RmMbIw8SEs" alt=""><figcaption></figcaption></figure></div>

* ATTENTION: Do not forget to claim accrued rewards before unstaking, otherwise you will loose them. Clock "Claim rewards" button and follow the process.
  * Sign and send the transaction in your Wallet.
  * Wait for the transaction to be processed.
* Click "**Yes, Unstake**"
  * You may be required to approve the vFTHM transfer before the actual transfer (depending on your previous deposits).
  * Sign and send the transaction in your Wallet.
  * Wait for the transaction to be processed.
  * Once the transaction has gone through, you'll see your position in "**My Positions"** has either changed, or disappeared. You will also see the "**Unstake Cooling Down**" notification and "**Cooldown in progress**" with timer.

<div data-full-width="true"><figure><img src="/files/UjBqxIu6UljehKyeqhUk" alt=""><figcaption></figcaption></figure></div>

* Wait for the cooldown period to pass. You can withdraw the unstaked and rewarded amount right after it. Clock "**Withdraw**" button.
  * Sign and send the transaction in your Wallet.
  * Wait for the transaction to be processed.


# Proposing

To make the proposal in Governance, follow the steps below:

* Go to Fathom [DApp](https://demo.fathom.fi/#/dao/governance).
* Connect your Web3 wallet (such as [MetaMask](https://metamask.io/)) and make sure your network is set to the intended chain (i.e., [XDC](https://chainlist.org/chain/50)).

<div data-full-width="true"><figure><img src="/files/PirrVkRYECmFstg5tFPM" alt=""><figcaption></figcaption></figure></div>

* Click "**Create a proposal**".
* If you have enough vFTHM, you can fill in the proposal details: Title, Description, and optional details/links.

<figure><img src="/files/Y2M1dWDQfoyD1VFi9vZK" alt=""><figcaption></figcaption></figure>

* You can add automation to a proposal by clicking on the "**Actionable Proposal**" switcher and filling in the details of the calls that should be made if the governance accepts the proposal.

<figure><img src="/files/sxKy9MRYFpRUDEVk0umM" alt=""><figcaption></figcaption></figure>

* [If you don't have enough vFTHM you should stake your FTHM in Staking](/dao/user-guides/staking).
* Click "**Submit proposal**"
  * You may be required to approve the vFTHM transfer before the actual transfer (depending on your previous deposits).
  * Sign and send the transaction in your Wallet.
  * Wait for the transaction to be processed.
  * Once the transaction has gone through, you'll see your proposal in "**All Proposals"** on the same page.
* Now, the proposal is the subject of the voting process. If the governance accepts it - it can be executed.


# Voting

To vote for the proposal in Governance, follow the steps below:

* Go to Fathom [DApp](https://demo.fathom.fi/#/dao/governance).
* Connect your Web3 wallet (such as [MetaMask](https://metamask.io/)) and make sure your network is set to the intended chain (i.e., [XDC](https://chainlist.org/chain/50)).

<div data-full-width="true"><figure><img src="/files/SUvOyUKxj0v6tBQt6ul4" alt=""><figcaption></figcaption></figure></div>

* Click on the proposal in the "**All Proposals**"
* Make yourself familiar with the proposal details and choose one of 3 options in the "Proposal Status": vote For, Against or Abstain the proposal.

<figure><img src="/files/7alEUdH15g2HdgFezzIS" alt=""><figcaption></figcaption></figure>

* Click "**Vote**" button
  * Sign and send the transaction in your Wallet.
  * Wait for the transaction to be processed.
  * Once the transaction has gone through, your vote will be counted in "Proposal Status" on the same page.




---

[Next Page](/llms-full.txt/1)

