# OCC\_Modular.sol

## Introduction

OCC stands for "On-Chain Credit".

A "Bullet" loan is an interest-only loan, with principal repaid in full at the end.

An "Amortization" loan is a principal and interest loan, with consistent payments until fully "Repaid".

This locker is responsible for handling accounting of loans.

This locker is responsible for handling payments and distribution of payments.

This locker is responsible for handling defaults and liquidations (if needed).

{% embed url="<https://www.figma.com/board/qjuQ0uGQl9QD7KeBwyf73d/Zivoe-Visualization?node-id=207-549&t=20BBLjcVYjmjSO7L-4>" %}

#### State Variables

<table><thead><tr><th width="186.33333333333331">Type</th><th width="150">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>GBL</td><td>The ZivoeGlobals contract.</td></tr><tr><td>address</td><td>stablecoin</td><td>The stablecoin for this OCC contract.</td></tr><tr><td>address</td><td>underwriter</td><td>The entity that is allowed to underwrite (a.k.a. issue) loans.</td></tr><tr><td>address</td><td>OCT_YDL</td><td>Facilitates swaps and forwards distributedAsset() to YDL.</td></tr><tr><td>uint256</td><td>combineCounter</td><td>Incrementor for "combinations" mapping.</td></tr><tr><td>uint256</td><td>loanCounter</td><td>Incrementor for "loans" mapping.</td></tr><tr><td>uint256</td><td>BIPS</td><td>Private constant, <code>10000</code></td></tr><tr><td>mapping(uint256 => <a data-mention href="#combine">#combine</a>)</td><td>combinations</td><td>Mapping of approved loan combinations.</td></tr><tr><td>mapping(uint256 => bool)</td><td>conversionToAmortization</td><td>Mapping of loans approved for conversion to amortization payment schedule.</td></tr><tr><td>mapping(uint256 => bool)</td><td>conversionToBullet</td><td>Mapping of loans approved for conversion to bullet payment schedule.</td></tr><tr><td>mapping(uint256 => uint256)</td><td>extensions</td><td>Mapping of loans approved for extension, key is the loan ID, output is paymentIntervals extension.</td></tr><tr><td>mapping(uint256 => <a data-mention href="#loan">#loan</a>)</td><td>loans</td><td>Mapping of loans and their information, key is the ID of the loan, output is the Loan struct information.</td></tr><tr><td>mapping(uint256 => uint256)</td><td>refinancing</td><td>Mapping of loans approved for refinancing, key is the ID of the loan, output is APR it can refinance to.</td></tr></tbody></table>

#### `Loan`

This struct stores information for loans.

<table><thead><tr><th width="165.33333333333331">Type</th><th width="238">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>borrower</td><td>The address that receives capital when the loan is funded.</td></tr><tr><td>uint256</td><td>principalOwed</td><td>The amount of principal still owed on the loan.</td></tr><tr><td>uint256</td><td>APR</td><td>The annualized percentage rate charged on the outstanding principal.</td></tr><tr><td>uint256</td><td>APRLateFee</td><td>The APR charged on the outstanding principal if payment is late.</td></tr><tr><td>uint256</td><td>paymentDueBy</td><td>The timestamp (in seconds) for when the next payment is due.</td></tr><tr><td>uint256</td><td>paymentsRemaining</td><td>The number of payments remaining until the loan is "Repaid".</td></tr><tr><td>uint256</td><td>term</td><td>The number of paymentIntervals that will occur (e.g. 12, 24).</td></tr><tr><td>uint256</td><td>paymentInterval</td><td>The interval of time between payments (in seconds).</td></tr><tr><td>uint256</td><td>offerExpiry</td><td>The block.timestamp at which the offer for this loan expires.</td></tr><tr><td>uint256</td><td>gracePeriod</td><td>The number of seconds a borrower has to makePayment() before default.</td></tr><tr><td>int8</td><td>paymentSchedule</td><td>The payment schedule of the loan (0 = "Bullet" or 1 = "Amortization").</td></tr><tr><td><a data-mention href="#loanstate">#loanstate</a></td><td>state</td><td>The state of the loan.</td></tr></tbody></table>

#### `Combine`

This struct stores information for loan combinations.

<table><thead><tr><th width="165.33333333333331">Type</th><th width="196">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256[]</td><td>loans</td><td>The loans approved for combination.</td></tr><tr><td>uint256</td><td>term</td><td>The term of the resulting combined loan.</td></tr><tr><td>uint256</td><td>paymentInterval</td><td>The paymentInterval of the resulting combined loan.</td></tr><tr><td>uint256</td><td>gracePeriod</td><td>The gracePeriod of the resulting combined loan.</td></tr><tr><td>uint256</td><td>expires</td><td>The expiration of this combination.</td></tr><tr><td>int8</td><td>paymentSchedule</td><td>The paymentSchedule of the resulting combined loan.</td></tr><tr><td>bool</td><td>valid</td><td>The validity of the combination (if it can be executed).</td></tr></tbody></table>

#### `LoanState`

This enumerator tracks loan states.

<table><thead><tr><th width="141">State</th><th>Description</th></tr></thead><tbody><tr><td>Null</td><td>Default state, loan isn't offered yet.</td></tr><tr><td>Offered</td><td>Loan offer has been created, not accepted (it could have passed expiry date).</td></tr><tr><td>Active</td><td>Loan has been accepted, is currently receiving payments.</td></tr><tr><td>Repaid</td><td>Loan was accepted, and has been fully repaid.</td></tr><tr><td>Defaulted</td><td>Loan has defaulted, payments were missed, gracePeriod passed, and markDefault() called.</td></tr><tr><td>Cancelled</td><td>Loan offer was created, then cancelled prior to acceptance.</td></tr><tr><td>Resolved</td><td>Loan was accepted, then there was a default, then the full amount of principal was repaid.</td></tr><tr><td>Combined</td><td>Loan was accepted, then combined with other loans while active.</td></tr></tbody></table>

#### `LoanSchedule`

This enumerator tracks the payment schedule type for a loan.

<table><thead><tr><th width="186">State</th><th>Description</th></tr></thead><tbody><tr><td>Bullet</td><td>An interest-only loan, with principal repaid in full at the end.</td></tr><tr><td>Amortization</td><td>A principal and interest loan, with consistent payments until fully "Repaid".</td></tr></tbody></table>

## **Sections**

[#read-functions](#read-functions "mention")

* [#canpush](#canpush "mention") - Permission for owner to call `pushToLocker()`. See [ZivoeLocker.sol](/developer-docs/core-contracts/zivoelocker.sol.md)
* [#canpull](#canpull "mention") - Permission for owner to call `pullFromLocker()`. See [ZivoeLocker.sol](/developer-docs/core-contracts/zivoelocker.sol.md)
* [#canpullpartial](#canpullpartial "mention") - Permission for owner to call `pullFromLockerPartial()`. See [ZivoeLocker.sol](/developer-docs/core-contracts/zivoelocker.sol.md)
* [#loaninfo](#loaninfo "mention") - Returns information for a given loan. Refer to [#loan](#loan "mention")
* [#amountowed](#amountowed "mention") - Returns information for amount owed on next payment of a particular loan

[#write-functions-core](#write-functions-core "mention")

* [#acceptoffer](#acceptoffer "mention") - Funds and initiates a loan.
* [#callloan](#callloan "mention") - Pays off the loan in full, plus additional interest for paymentInterval.
* [#canceloffer](#canceloffer "mention") - Cancels a loan offer.
* [#createoffer](#createoffer "mention") - Create a loan offer.
* [#makepayment](#makepayment "mention") - Make a payment on a loan. Anyone is allowed to make a payment on someone's loan.
* [#markdefault](#markdefault "mention") - Mark a loan insolvent if a payment hasn't been made beyond the corresponding grace period.
* [#markrepaid](#markrepaid "mention") - Underwriter specifies a loan has been repaid fully via interest deposits in terms of off-chain debt.
* [#processpayment](#processpayment "mention") - Process a payment for a loan, on behalf of another borrower.
* [#resolvedefault](#resolvedefault "mention") - Make a full (or partial) payment to resolve an insolvent loan.
* [#supplyinterest](#supplyinterest "mention") - Supply interest to a repaid loan (for arbitrary interest repayment).
* [#updateoctydl](#updateoctydl "mention") - Updates the OCT\_YDL endpoint.

[#write-functions-loan-management](#write-functions-loan-management "mention")

* [#applycombine](#applycombine "mention") - Combines multiple loans into a single loan.
* [#applyconversiontoamortization](#applyconversiontoamortization "mention") - Converts a loan to amortization payment schedule.
* [#applyconversionbullet](#applyconversionbullet "mention") - Converts a loan to bullet payment schedule.
* [#applyextension](#applyextension "mention") - Applies an extension to a loan.
* [#applyrefinance](#applyrefinance "mention") - Refinances a loan.
* [#approvecombine](#approvecombine "mention") - Approves a borrower for combining loans.
* [#approveconversiontoamortization](#approveconversiontoamortization "mention") - Approves a loan for conversion to amortization payment schedule.
* [#approveconversiontobullet](#approveconversiontobullet "mention") - Approves a loan for conversion to bullet payment schedule.
* [#approveextension](#approveextension "mention") - Approves an extension for a loan.
* [#approverefinance](#approverefinance "mention") - Approves a loan for refinancing.
* [#unapprovecombine](#unapprovecombine "mention") - Unapproves a borrower for combining loans.
* [#unapproveconversiontoamortization](#unapproveconversiontoamortization "mention") - Unapproves a loan for conversion to amortization payment schedule.
* [#unapproveconversionbullet](#unapproveconversionbullet "mention") - Unapproves a loan for conversion to bullet payment schedule.
* [#unapproveextension](#unapproveextension "mention") - Unapproves an extension for a loan.
* [#unapproverefinance](#unapproverefinance "mention") - Unapproves a loan for refinancing.

[#events](#events "mention")

* [#combineapplied](#combineapplied "mention")
* [#combineapproved](#combineapproved "mention")
* [#combineloancreated](#combineloancreated "mention")
* [#combineunapproved](#combineunapproved "mention")
* [#conversiontoamortizationapplied](#conversiontoamortizationapplied "mention")
* [#conversiontoamortizationapproved](#conversiontoamortizationapproved "mention")
* [#conversiontoamortizationunapproved](#conversiontoamortizationunapproved "mention")
* [#conversiontobulletapplied](#conversiontobulletapplied "mention")
* [#converesiontobulletapproved](#converesiontobulletapproved "mention")
* [#conversiontobulletunapproved](#conversiontobulletunapproved "mention")
* [#defaultmarked](#defaultmarked "mention")
* [#defaultresolved](#defaultresolved "mention")
* [#extensionapplied](#extensionapplied "mention")
* [#extensionapproved](#extensionapproved "mention")
* [#extensionunapproved](#extensionunapproved "mention")
* [#interestsupplied](#interestsupplied "mention")
* [#loancalled](#loancalled "mention")
* [#offeraccepted](#offeraccepted "mention")
* [#offercancelled](#offercancelled "mention")
* [#offercreated](#offercreated "mention")
* [#paymentmade](#paymentmade "mention")
* [#refinanceapplied](#refinanceapplied "mention")
* [#refinanceapproved](#refinanceapproved "mention")
* [#refinanceunapproved](#refinanceunapproved "mention")
* [#repaidmarked](#repaidmarked "mention")
* [#updatedoctydl](#updatedoctydl "mention")

## Read Functions

#### `canPush()`

Permission for owner to call `pushToLocker()`. See [ZivoeLocker.sol](/developer-docs/core-contracts/zivoelocker.sol.md)

```solidity
 function canPush() public override pure returns (bool) { return true; }
```

#### `canPull()`

Permission for owner to call `pullFromLocker()`. See [ZivoeLocker.sol](/developer-docs/core-contracts/zivoelocker.sol.md)

```solidity
function canPull() public override pure returns (bool) { return true; }
```

#### `canPullPartial()`

Permission for owner to call `pullFromLockerPartial()`. See [ZivoeLocker.sol](/developer-docs/core-contracts/zivoelocker.sol.md)

```solidity
function canPullPartial() public override pure returns (bool) { return true; }
```

#### `loanInfo()`

Returns information for a given loan. Refer to [#loan](#loan "mention")

```solidity
function loanInfo(uint256 id) public view returns (
    address borrower, 
    int8 paymentSchedule,
    uint256[10] memory details
);
```

<table><thead><tr><th width="122.33333333333331">Type</th><th width="118">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID of the loan.</td></tr></tbody></table>

*Returns*

<table><thead><tr><th width="182.33333333333331">Type</th><th width="210">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>borrower</td><td>The borrower of the loan.</td></tr><tr><td>int8</td><td>paymentSchedule</td><td>The structure of the payment schedule.</td></tr><tr><td>uint256[10]</td><td>details</td><td>Loan details. Refer to code block below ...</td></tr></tbody></table>

```
/// @return info The remaining information for the loan:
///                  info[0] = principalOwed
///                  info[1] = APR
///                  info[2] = APRLateFee
///                  info[3] = paymentDueBy
///                  info[4] = paymentsRemaining
///                  info[5] = term
///                  info[6] = paymentInterval
///                  info[7] = offerExpiry
///                  info[8] = gracePeriod
///                  info[9] = loanState
```

#### `amountOwed()`

Returns information for amount owed on next payment of a particular loan

```solidity
function amountOwed(uint256 id) public view returns (
    uint256 principal, 
    uint256 interest,
    uint256 lateFee, 
    uint256 total
);
```

<table><thead><tr><th width="122.33333333333331">Type</th><th width="118">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID of the loan.</td></tr></tbody></table>

*Returns*

<table><thead><tr><th width="170.33333333333331">Type</th><th width="204">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>principal</td><td>The amount of principal owed.</td></tr><tr><td>uint256</td><td>interest</td><td>The amount of interest owed.</td></tr><tr><td>uint256</td><td>lateFee</td><td>The amount of late fees owed.</td></tr><tr><td>uint256</td><td>total</td><td>Full amount owed, combining principal plus interest.</td></tr></tbody></table>

## Write Functions - Core

#### `acceptOffer()`

Funds and initiates a loan.

```solidity
function acceptOffer(uint256 id) external nonReentrant;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="184">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID of the loan to pay off early.</td></tr></tbody></table>

Emits the [#offeraccepted](#offeraccepted "mention") event

#### `callLoan()`

Pays off the loan in full, plus additional interest for paymentInterval.

```solidity
function callLoan(uint256 id) external nonReentrant;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="184">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID of the loan to pay off early.</td></tr></tbody></table>

Emits the [#loancalled](#loancalled "mention") event

#### `cancelOffer()`

Cancels a loan offer.

```solidity
function cancelOffer(uint256 id) isUnderwriter external;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="184">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID of the loan.</td></tr></tbody></table>

Emits the [#offercancelled](#offercancelled "mention") event

#### `createOffer()`

Create a loan offer.

```solidity
function createOffer(
    address borrower,
    uint256 borrowAmount,
    uint256 APR,
    uint256 APRLateFee,
    uint256 term,
    uint256 paymentInterval,
    uint256 gracePeriod,
    int8 paymentSchedule
) isUnderwriter external;
```

<table><thead><tr><th width="173.33333333333331">Type</th><th width="184">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>borrower</td><td>The address to borrow (that receives the loan)</td></tr><tr><td>uint256</td><td>borrowAmount</td><td>The amount to borrow (in other words, initial principal).</td></tr><tr><td>uint256</td><td>APR</td><td>The annualized percentage rate charged on the outstanding principal.</td></tr><tr><td>uint256</td><td>APRLateFee</td><td>The APR charged for late payments.</td></tr><tr><td>uint256</td><td>term</td><td>The term or "duration" of the loan (number of paymentIntervals that will occur).</td></tr><tr><td>uint256</td><td>paymentInterval</td><td>The interval of time between payments (in seconds).</td></tr><tr><td>uint256</td><td>gracePeriod</td><td>The number of seconds a borrower has to makePayment() before loan could default.</td></tr><tr><td>int8</td><td>paymentSchedule</td><td>The payment schedule type ("Bullet" or "Amortization").</td></tr></tbody></table>

Emits the [#offercreated](#offercreated "mention") event

#### `makePayment()`

Make a payment on a loan. Anyone is allowed to make a payment on someone's loan.

```solidity
function makePayment(uint256 id) external nonReentrant;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="184">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID of the loan.</td></tr></tbody></table>

Emits the [#paymentmade](#paymentmade "mention") event

#### `markDefault()`

Mark a loan insolvent if a payment hasn't been made beyond the corresponding grace period.

```solidity
function markDefault(uint256 id) external isUnderwriter;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="184">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID of the loan.</td></tr></tbody></table>

Emits the [#defaultmarked](#defaultmarked "mention") event

#### `markRepaid()`

Underwriter specifies a loan has been repaid fully via interest deposits in terms of off-chain debt.

```solidity
function markRepaid(uint256 id) external isUnderwriter;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="184">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID of the loan.</td></tr></tbody></table>

Emits the [#repaidmarked](#repaidmarked "mention") event

#### `processPayment()`

Process a payment for a loan, on behalf of another borrower.

```solidity
function processPayment(uint256 id) external nonReentrant;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="184">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID of the loan.</td></tr></tbody></table>

Emits the [#paymentmade](#paymentmade "mention") event

#### `resolveDefault()`

Make a full (or partial) payment to resolve an insolvent loan.

```solidity
function resolveDefault(uint256 id, uint256 amount) external;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="184">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID of the loan.</td></tr><tr><td>uint256</td><td>amount</td><td>The amount of principal to pay down.</td></tr></tbody></table>

Emits the [#defaultresolved](#defaultresolved "mention") event

#### `supplyInterest()`

Supply interest to a repaid loan (for arbitrary interest repayment).

```solidity
function supplyInterest(uint256 id, uint256 amount) external nonReentrant;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="184">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID of the loan.</td></tr><tr><td>uint256</td><td>amount</td><td>The amount of interest to supply.</td></tr></tbody></table>

Emits the [#interestsupplied](#interestsupplied "mention") event

#### `updateOCTYDL()`

Updates the OCT\_YDL endpoint.

```solidity
function updateOCTYDL(address _OCT_YDL) external;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="184">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td><code>_OCT_YDL</code></td><td>The new address for OCT_YDL.</td></tr></tbody></table>

Emits the [#updatedoctydl](#updatedoctydl "mention") event

## Write Functions - Loan Management

#### `applyCombine()`

Combines multiple loans into a single loan.

```solidity
function applyCombine(uint256 id) external;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="119">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID to reference from "combinations" mapping.</td></tr></tbody></table>

Emits the [#combineapplied](#combineapplied "mention") and [#combineloancreated](#combineloancreated "mention") event(s)

#### `applyConversionToAmortization()`

Converts a loan to amortization payment schedule.

```solidity
function applyConversionToAmortization(uint256 id) external;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="119">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID for the loan.</td></tr></tbody></table>

Emits the [#conversiontoamortizationapplied](#conversiontoamortizationapplied "mention") event

#### `applyConversionBullet()`

Converts a loan to bullet payment schedule.

```solidity
function applyConversionToBullet(uint256 id) external;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="119">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID for the loan.</td></tr></tbody></table>

Emits the [#conversiontobulletapplied](#conversiontobulletapplied "mention") event

#### `applyExtension()`

Applies an extension to a loan.

```solidity
function applyExtension(uint256 id) external;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="119">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID for the loan.</td></tr></tbody></table>

Emits the [#extensionapplied](#extensionapplied "mention") event

#### `applyRefinance()`

Refinances a loan.

```solidity
function applyRefinance(uint256 id) external;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="119">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID for the loan.</td></tr></tbody></table>

Emits the [#refinanceapplied](#refinanceapplied "mention")

#### `approveCombine()`

Approves a borrower for combining loans.

```solidity
function approveCombine(
    uint256[] calldata loanIDs, 
    uint256 term,
    uint256 paymentInterval, 
    uint256 gracePeriod,
    int8 paymentSchedule
) external isUnderwriter;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="172">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256[]</td><td>loanIDs</td><td>The IDs of the loans that can be combined.</td></tr><tr><td>uint256</td><td>term</td><td>The term that loans can be combined into.</td></tr><tr><td>uint256</td><td>paymentInterval</td><td>The paymentInterval that loans can be combined into.</td></tr><tr><td>uint256</td><td>gracePeriod</td><td>The number of seconds a borrower has to makePayment() before loan could default.</td></tr><tr><td>int8</td><td>paymentSchedule</td><td>The payment schedule of the loan (0 = "Bullet" or 1 = "Amortization").</td></tr></tbody></table>

Emits the [#combineapproved](#combineapproved "mention") event

#### `approveConversionToAmortization()`

Approves a loan for conversion to amortization payment schedule.

```solidity
function approveConversionToAmortization(uint256 id) external isUnderwriter;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="119">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID for the loan.</td></tr></tbody></table>

Emits the [#conversiontoamortizationapproved](#conversiontoamortizationapproved "mention") event

#### `approveConversionToBullet()`

Approves a loan for conversion to bullet payment schedule.

```solidity
function approveConversionToBullet(uint256 id) external isUnderwriter;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="119">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID for the loan.</td></tr></tbody></table>

Emits the [#conversiontobulletapproved](#conversiontobulletapproved "mention") event

#### `approveExtension()`

Approves an extension for a loan.

```solidity
function approveExtension(uint256 id, uint256 intervals) external isUnderwriter;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="119">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID for the loan.</td></tr><tr><td>uint256</td><td>intervals</td><td>The amount of intervals to approve for extension.</td></tr></tbody></table>

Emits the [#extensionapproved](#extensionapproved "mention") event

#### `approveRefinance()`

Approves a loan for refinancing.

```solidity
function approveRefinance(uint256 id, uint256 apr) external isUnderwriter;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="119">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID for the loan.</td></tr><tr><td>uint256</td><td>APR</td><td>The APR the loan can refinance to.</td></tr></tbody></table>

Emits the [#refinanceapproved](#refinanceapproved "mention") event

#### `unapproveCombine()`

Unapproves a borrower for combining loans.

```solidity
function unapproveCombine(uint256 id) external isUnderwriter;
```

<table><thead><tr><th width="137.33333333333331">Type</th><th width="161">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID of the combine to unapprove.</td></tr></tbody></table>

Emits the [#combineunapproved](#combineunapproved "mention") event

#### `unapproveConversionToAmortization()`

Unapproves a loan for conversion to amortization payment schedule.

```solidity
function unapproveConversionToAmortization(uint256 id) external isUnderwriter;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="119">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID for the loan.</td></tr></tbody></table>

Emits the  [#conversiontoamortizationunapproved](#conversiontoamortizationunapproved "mention") event

#### `unapproveConversionBullet()`

Unapproves a loan for conversion to bullet payment schedule.

```solidity
function unapproveConversionToBullet(uint256 id) external isUnderwriter;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="119">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID for the loan.</td></tr></tbody></table>

Emits the [#conversiontobulletunapproved](#conversiontobulletunapproved "mention") event

#### `unapproveExtension()`

Unapproves an extension for a loan.

```solidity
function unapproveExtension(uint256 id) external isUnderwriter;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="119">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID for the loan.</td></tr></tbody></table>

Emits the [#extensionunapproved](#extensionunapproved "mention") event

#### `unapproveRefinance()`

Unapproves a loan for refinancing.

```solidity
function unapproveRefinance(uint256 id) external isUnderwriter;
```

<table><thead><tr><th width="171.33333333333331">Type</th><th width="119">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>id</td><td>The ID for the loan.</td></tr></tbody></table>

Emits the [#refinanceunapproved](#refinanceunapproved "mention") event

###

## Events

#### **`CombineApplied()`**

Emitted during [#applycombine](#applycombine "mention")

```solidity
event CombineApplied(
    address indexed borrower, 
    uint256[] loanIDs, 
    uint256 term,
    uint256 paymentInterval,
    uint256 gracePeriod,
    int8 indexed paymentSchedule
);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>True</td><td>borrower</td><td>The borrower combining their loans.</td></tr><tr><td>uint256[]</td><td>False</td><td>loanIDs</td><td>The IDs of the loans that were combined.</td></tr><tr><td>uint256</td><td>False</td><td>term</td><td>The resulting term of the combined loan.</td></tr><tr><td>uint256</td><td>False</td><td>paymentInterval</td><td>The resulting paymentInterval of the combined loan.</td></tr><tr><td>uint256</td><td>False</td><td>gracePeriod</td><td>The resulting gracePeriod of the combined loan.</td></tr><tr><td>int8</td><td>True</td><td>paymentSchedule</td><td>The payment schedule of the combined loan (0 = "Bullet" or 1 = "Amortization").</td></tr></tbody></table>

#### **`CombineApproved()`**

Emitted during [#approvecombine](#approvecombine "mention")

```solidity
event CombineApproved(
    uint256 indexed id, 
    uint256[] loanIDs,
    uint256 term,
    uint256 paymentInterval, 
    uint256 gracePeriod,
    uint256 expires,
    int8 indexed paymentSchedule
);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>The ID of the combination approval in "combinations" mapping.</td></tr><tr><td>uint256[]</td><td>False</td><td>loanIDs</td><td>The IDs of the loans that can be combined.</td></tr><tr><td>uint256</td><td>False</td><td>term</td><td>The resulting term of the combined loan that is permitted.</td></tr><tr><td>uint256</td><td>False</td><td>paymentInterval</td><td>The resulting paymentInterval of the combined loan.</td></tr><tr><td>uint256</td><td>False</td><td>gracePeriod</td><td>The resulting gracePeriod of the combined loan that is permitted.</td></tr><tr><td>uint256</td><td>False</td><td>expires</td><td>The expiration of this combination.</td></tr><tr><td>int8</td><td>True</td><td>paymentSchedule</td><td>The payment schedule of the combined loan (0 = "Bullet" or 1 = "Amortization").</td></tr></tbody></table>

#### **`CombineLoanCreated()`**

Emitted during [#applycombine](#applycombine "mention")

```solidity
event CombineLoanCreated(
    address indexed borrower,
    uint256 indexed id,
    uint256 borrowAmount,
    uint256 APR,
    uint256 APRLateFee,
    uint256 paymentDueBy,
    uint256 term,
    uint256 paymentInterval,
    uint256 gracePeriod,
    int8 indexed paymentSchedule
);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>True</td><td>borrower</td><td>The address borrowing (that will receive the loan).</td></tr><tr><td>uint256</td><td>True</td><td>id</td><td>Identifier for the loan offer created.</td></tr><tr><td>uint256</td><td>False</td><td>borrowAmount</td><td>The amount to borrow (in other words, initial principal).</td></tr><tr><td>uint256</td><td>False</td><td>APR</td><td>The annualized percentage rate charged on the outstanding principal.</td></tr><tr><td>uint256</td><td>False</td><td>APRLateFee</td><td>The APR charged for late payments.</td></tr><tr><td>uint256</td><td>False</td><td>paymentDueBy</td><td>The timestamp (in seconds) for when the next payment is due.</td></tr><tr><td>uint256</td><td>False</td><td>term</td><td>The term or "duration" of the loan (number of paymentIntervals that will occur).</td></tr><tr><td>uint256</td><td>False</td><td>paymentInterval</td><td>The interval of time between payments (in seconds).</td></tr><tr><td>uint256</td><td>False</td><td>gracePeriod</td><td>The number of seconds a borrower has to makePayment() before loan could default.</td></tr><tr><td>int8</td><td>True</td><td>paymentSchedule</td><td>The payment schedule of the combined loan (0 = "Bullet" or 1 = "Amortization").</td></tr></tbody></table>

#### **`CombineUnapproved()`**

Emitted during [#unapprovecombine](#unapprovecombine "mention")

```solidity
event CombineUnapproved(uint256 id);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>The ID of the combine to unapprove.</td></tr></tbody></table>

#### **`ConversionToAmortizationApplied()`**

Emitted during [#applyconversiontoamortization](#applyconversiontoamortization "mention")

```solidity
event ConversionToAmortizationApplied(uint256 indexed id);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>The loan ID converted to amortization payment schedule.</td></tr></tbody></table>

#### **`ConversionToAmortizationApproved()`**

Emitted during [#approveconversiontoamortization](#approveconversiontoamortization "mention")

```solidity
event ConversionToAmortizationApproved(uint256 indexed id);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>The loan ID approved for conversion.</td></tr></tbody></table>

#### **`ConversionToAmortizationUnapproved()`**

Emitted during [#unapproveconversiontoamortization](#unapproveconversiontoamortization "mention")

```solidity
event ConversionToAmortizationUnapproved(uint256 indexed id);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>The loan ID unapproved for conversion.</td></tr></tbody></table>

#### **`ConversionToBulletApplied()`**

Emitted during [#applyconversionbullet](#applyconversionbullet "mention")

```solidity
event ConversionToBulletApplied(uint256 indexed id);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>The loan ID converted to bullet payment schedule.</td></tr></tbody></table>

#### **`ConversionToBulletApproved()`**

Emitted during [#approveconversiontobullet](#approveconversiontobullet "mention")

```solidity
event ConversionToBulletApproved(uint256 indexed id);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>The loan ID approved for conversion.</td></tr></tbody></table>

#### **`ConversionToBulletUnapproved()`**

Emitted during [#unapproveconversionbullet](#unapproveconversionbullet "mention")

```solidity
event ConversionToBulletUnapproved(uint256 indexed id);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>The loan ID unapproved for conversion.</td></tr></tbody></table>

#### **`DefaultMarked()`**

Emitted during [#markdefault](#markdefault "mention")

```solidity
event DefaultMarked(uint256 indexed id, uint256 principalDefaulted);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>Identifier for the loan which is now "defaulted".</td></tr><tr><td>uint256</td><td>False</td><td>principalDefaulted</td><td>The amount defaulted on.</td></tr></tbody></table>

#### **`DefaultResolved()`**

Emitted during [#resolvedefault](#resolvedefault "mention")

```solidity
event DefaultResolved(
    uint256 indexed id, 
    uint256 amount, 
    address indexed payee, 
    bool resolved
);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>The identifier for the loan in default that is resolved (or partially).</td></tr><tr><td>uint256</td><td>False</td><td>amount</td><td>The amount of principal paid back.</td></tr><tr><td>address</td><td>True</td><td>payee</td><td>The address responsible for resolving the default.</td></tr><tr><td>bool</td><td>False</td><td>resolved</td><td>Denotes if the loan is fully resolved (false if partial).</td></tr></tbody></table>

#### **`ExtensionApplied()`**

Emitted during [#applyextension](#applyextension "mention")

```solidity
event ExtensionApplied(uint256 indexed id, uint256 intervals);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>The identifier of the loan extending its payment schedule.</td></tr><tr><td>uint256</td><td>False</td><td>interval</td><td>The number of intervals the loan is extended for.</td></tr></tbody></table>

#### **`ExtensionApproved()`**

Emitted during [#approveextension](#approveextension "mention")

```solidity
event ExtensionApproved(uint256 indexed id, uint256 intervals);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>The identifier of the loan receiving approval for extension.</td></tr><tr><td>uint256</td><td>False</td><td>intervals</td><td>The number of intervals the approved loan may be extended.</td></tr></tbody></table>

#### **`ExtensionUnapproved()`**

Emitted during [#unapproveextension](#unapproveextension "mention")

```solidity
event ExtensionUnapproved(uint256 indexed id);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>The identifier of the loan losing approval for extension.</td></tr></tbody></table>

#### **`InterestSupplied()`**

Emitted during [#supplyinterest](#supplyinterest "mention")

```solidity
event InterestSupplied(
    uint256 indexed id, 
    uint256 amount, 
    address indexed payee
);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>The identifier for the loan that is supplied additional interest.</td></tr><tr><td>uint256</td><td>False</td><td>amount</td><td>The amount of interest supplied.</td></tr><tr><td>address</td><td>True</td><td>payee</td><td>The address responsible for supplying additional interest.</td></tr></tbody></table>

#### **`LoanCalled()`**

Emitted during [#callloan](#callloan "mention")

```solidity
event LoanCalled(
    uint256 indexed id, 
    uint256 amount, 
    uint256 principal, 
    uint256 interest, 
    uint256 lateFee
);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>Identifier for the loan which was called.</td></tr><tr><td>uint256</td><td>False</td><td>amount</td><td>The total amount of the payment.</td></tr><tr><td>uint256</td><td>False</td><td>principal</td><td>The principal portion of "amount" paid.</td></tr><tr><td>uint256</td><td>False</td><td>interest</td><td>The interest portion of "amount" paid.</td></tr><tr><td>uint256</td><td>False</td><td>lateFee</td><td>The lateFee portion of "amount" paid.</td></tr></tbody></table>

#### **`OfferAccepted()`**

Emitted during [#acceptoffer](#acceptoffer "mention")

```solidity
event OfferAccepted(
    uint256 indexed id, 
    uint256 principal, 
    address indexed borrower, 
    uint256 paymentDueBy
);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>Identifier for the offer accepted.</td></tr><tr><td>uint256</td><td>False</td><td>principal</td><td>The amount of stablecoin lent out.</td></tr><tr><td>address</td><td>True</td><td>borrower</td><td>The address borrowing the amount (principal).</td></tr><tr><td>uint256</td><td>False</td><td>paymentDueBy</td><td>Timestamp (unix seconds) by which next payment is due.</td></tr></tbody></table>

#### **`OfferCancelled()`**

Emitted during [#canceloffer](#canceloffer "mention")

```solidity
event OfferCancelled(uint256 indexed id);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>Identifier for the loan offer cancelled.</td></tr></tbody></table>

#### **`OfferCreated()`**

Emitted during [#createoffer](#createoffer "mention")

```solidity
event OfferCreated(
    address indexed borrower,
    uint256 indexed id,
    uint256 borrowAmount,
    uint256 APR,
    uint256 APRLateFee,
    uint256 term,
    uint256 paymentInterval,
    uint256 offerExpiry,
    uint256 gracePeriod,
    int8 indexed paymentSchedule
);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>True</td><td>borrower</td><td>The address borrowing (that will receive the loan).</td></tr><tr><td>uint256</td><td>True</td><td>id</td><td>Identifier for the loan offer created.</td></tr><tr><td>uint256</td><td>False</td><td>borrowAmount</td><td>The amount to borrow (in other words, initial principal).</td></tr><tr><td>uint256</td><td>False</td><td>APR</td><td>The annualized percentage rate charged on the outstanding principal.</td></tr><tr><td>uint256</td><td>False</td><td>APRLateFee</td><td>The APR charged for late payments.</td></tr><tr><td>uint256</td><td>False</td><td>term</td><td>The term or "duration" of the loan (number of paymentIntervals that will occur).</td></tr><tr><td>uint256</td><td>False</td><td>paymentInterval</td><td>The interval of time between payments (in seconds).</td></tr><tr><td>uint256</td><td>False</td><td>offerExpiry</td><td>The block.timestamp at which the offer for this loan expires (hardcoded 2 weeks).</td></tr><tr><td>uint256</td><td>False</td><td>gracePeriod</td><td>The number of seconds a borrower has to makePayment() before loan could default.</td></tr><tr><td>int8</td><td>True</td><td>paymentSchedule</td><td>The payment schedule type ("Bullet" or "Amortization").</td></tr></tbody></table>

#### **`PaymentMade()`**

Emitted during [#makepayment](#makepayment "mention") and [#processpayment](#processpayment "mention")

```solidity
event PaymentMade(
    uint256 indexed id, 
    address indexed payee, 
    uint256 amount, 
    uint256 principal, 
    uint256 interest, 
    uint256 lateFee, 
    uint256 nextPaymentDue
);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>Identifier for the loan on which payment is made.</td></tr><tr><td>address</td><td>True</td><td>payee</td><td>The address which made payment on the loan.</td></tr><tr><td>uint256</td><td>False</td><td>amount</td><td>The total amount of the payment.</td></tr><tr><td>uint256</td><td>False</td><td>principal</td><td>The principal portion of "amount" paid.</td></tr><tr><td>uint256</td><td>False</td><td>interest</td><td>The interest portion of "amount" paid.</td></tr><tr><td>uint256</td><td>False</td><td>lateFee</td><td>The lateFee portion of "amount" paid.</td></tr><tr><td>uint256</td><td>False</td><td>nextPaymentDue</td><td>The timestamp by which next payment is due.</td></tr></tbody></table>

#### **`RefinanceApplied()`**

Emitted during [#applyrefinance](#applyrefinance "mention")

```solidity
event RefinanceApplied(uint256 indexed id, uint256 APRNew, uint256 APRPrior);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>The loan ID refinancing its APR.</td></tr><tr><td>uint256</td><td>False</td><td>APRNew</td><td>The new APR of the loan.</td></tr><tr><td>uint256</td><td>False</td><td>APRPrior</td><td>The prior APR of the loan.</td></tr></tbody></table>

#### **`RefinanceApproved()`**

Emitted during [#approverefinance](#approverefinance "mention")

```solidity
event RefinanceApproved(uint256 indexed id, uint256 APR);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>The loan ID approved for refinance.</td></tr><tr><td>uint256</td><td>False</td><td>APR</td><td>The APR the loan is approved to refinance to.</td></tr></tbody></table>

#### **`RefinanceUnapproved()`**

Emitted during [#unapproverefinance](#unapproverefinance "mention")

```solidity
event RefinanceUnapproved(uint256 indexed id);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>The loan ID unapproved for refinance.</td></tr></tbody></table>

#### **`RepaidMarked()`**

Emitted during [#markrepaid](#markrepaid "mention")

```solidity
event RepaidMarked(uint256 indexed id);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>True</td><td>id</td><td>Identifier for the loan which is now "repaid".</td></tr></tbody></table>

#### **`UpdatedOCTYDL()`**

Emitted during [#updateoctydl](#updateoctydl "mention")

```solidity
event UpdatedOCTYDL(address indexed newOCT, address indexed oldOCT);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>True</td><td>newOCT</td><td>The new OCT_YDL contract.</td></tr><tr><td>address</td><td>True</td><td>oldOCT</td><td>The old OCT_YDL contract.</td></tr></tbody></table>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.zivoe.com/developer-docs/lockers/occ_modular.sol.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
