# 'Interest Accrued' contract flow

{% hint style="info" %}
Prior advised reading and definitions: '[finance view](https://docs.creditcoop.xyz/developer-material/v1-developer-material/functions-and-methods/interestratecredit.sol/accrued-interest-calculation)' of how accrued interest is calculated in our contracts.

The term 'InterestAccrued' is the Interest owed by a Borrower but not yet repaid to the Line of Credit contract and made available for withdrawal by a Lender.
{% endhint %}

Steps 2 - 5 below deal with calculating calculating accrued interest in order to update`InterestAccrued`for a single credit position id as either a direct result of the external function request (step 1) or indirectly as a result of another action such as a change in the balance on a credit line id.

Step 1 is an external function that updates the accrued interest for **all** credit position ids in a Line of Credit facility

<details>

<summary>1) <code>accrueInterest()</code> in LineOfCredit.sol</summary>

This external function *loops over all credit position ids* and calls related internal functions during which InterestRateCredit.sol is called with the id data and then i`nterestAccrued` is updated.

```solidity
 function accrueInterest() external override returns(bool) {
        uint256 len = ids.length;
        bytes32 id;
        for (uint256 i; i < len; ++i) {
          id = ids[i];
          Credit memory credit = credits[id];
          credits[id] = _accrue(credit, id);
          
        }
        
        return true;
    }
```

</details>

<details>

<summary>2) <code>_accrue</code> in LineOfCredit.sol</summary>

This internal function runs within step 1 or otherwise at any time the balance on a credit line changes or the interest rates are changed by mutual consent between a Borrower and a Lender.

```solidity
    function _accrue(Credit memory credit, bytes32 id) internal returns (Credit memory) {
        if (!credit.isOpen) {
            return credit;
        }
        return CreditLib.accrue(credit, id, address(interestRate));
    }
```

</details>

<details>

<summary>3) <code>accrue()</code> in CreditLib.sol</summary>

Called by `_accrue()` in step 2 above any time the balance on a credit position changes or the interest rates are changed by mutual consent between a Borrower and a Lender.

It returns an updated token denominated `interestAccrued` for a single id.

It does so by adding the new amount of interest to accrue to the prior amount of `interestAccrued` recorded.

This new amount of interest to accrue is called `accruedToken` and is calculated in InterestRateCredit.sol (see steps 4 and 5 below).

```solidity
function accrue(
        ILineOfCredit.Credit memory credit,
        bytes32 id,
        address interest
    ) public returns (ILineOfCredit.Credit memory) {
        unchecked {
            // interest will almost always be less than deposit
            // low risk of overflow unless extremely high interest rate

            // get token demoninated interest accrued
            uint256 accruedToken = IInterestRateCredit(interest).accrueInterest(id, credit.principal, credit.deposit);

            // update credit line balance
            credit.interestAccrued += accruedToken;

            emit InterestAccrued(id, accruedToken);
            return credit;
        }
    }
}
```

</details>

<details>

<summary>4) <code>accrueInterest()</code> in InterestRateCredit.sol</summary>

This is the main function for calculating the amount by which `interestAccrued` should be updated for *a single credit position id*, callable indirectly by `_accrue()` in LineOfCredit.sol (step 2 above) and then subsequently directly by `accrue()` in CreditLib.sol (step 3)

```solidity
function accrueInterest(
        bytes32 id,
        uint256 drawnBalance,
        uint256 facilityBalance
    ) external override onlyLineContract returns (uint256) {
        return _accrueInterest(id, drawnBalance, facilityBalance);
    }
```

</details>

<details>

<summary>5) <code>_accrueInterest() and _calculateInterestOwed</code> in InterestRateCredit.sol</summary>

Finally, this is where the amount by which `interestAccrued should be updated` is calculated per credit position id.

[For a detailed explanation of the formula, please see here.](https://docs.creditcoop.xyz/developer-material/v1-developer-material/functions-and-methods/interestratecredit.sol/accrued-interest-calculation)

```solidity
 function _accrueInterest(bytes32 id, uint256 drawnBalance, uint256 facilityBalance) internal returns (uint256) {
        Rate memory rate = rates[id];
        uint256 timespan = block.timestamp - rate.lastAccrued;
        // update last timestamp in storage
        rates[id].lastAccrued = block.timestamp;

        return (_calculateInterestOwed(rate.dRate, drawnBalance, timespan) +
            _calculateInterestOwed(rate.fRate, (facilityBalance - drawnBalance), timespan));
    }
 
 function _calculateInterestOwed(
        uint256 bpsRate,
        uint256 balance,
        uint256 timespan
   ) internal pure returns (uint256) {
        return (bpsRate * balance * timespan) / INTEREST_DENOMINATOR;
   }
```

</details>

*last updated Dec 29 2022*
