The aim of this document is to provide high-level documentation of the loan smart contract. It gives an overall picture of the operations done in the smart contract. It does not focus on technical or financial details.

For the installment plan calculation and more detailed financial flow, details see Loan installment plan calculation.

For the posting listing see Personal loan postings.

For the debt manager postings sequences with the examples see https://safibank.atlassian.net/wiki/spaces/ITArch/pages/114819318/Debt+Manager+Documentation#Debt-manager-postings.1.

The deployment of smart contracts is described at Deployment of smart contracts.

Installment plan calculation

In the smart contract, we often need the loan installment plan. It is used mainly for the allocation of overdue payments and for getting the right installment number for various postings.

Since it is not recommended to store the installment plan directly as a TM parameter, we have to calculate it using the parameters that are available in the TM.

The early repayments and associated changes of the EMI are handled using time series of emi and early_repayment parameters.

The installment plan calculation is located in loan/features/installment_plan.py in the smart contract source code directory. The calculation itself is done by get_installments method, the assignment of already paid amounts is done by get_installments_with_paid_amounts and the current installment number is calculated by get_installment_by_remaining_principal method.

Schedules

There are three schedules in the smart contract - interest accruing, due date, and overdue date schedules. All the schedules are planned using execution_schedules hook and executed by the execution_schedules hook.

Interest accruing

The schedule runs every day at 00:00:01 local Philippines time.

It calculates the daily interest rate and increases the ACCRUED_INTEREST address accordingly.

Due date schedule

The schedule runs on the loan due date at 00:01:00 local Philippines time.

On this schedule, the accrued interest is rounded to two decimal places and transferred to the INTEREST_DUE address. Using the installment plan the current installment principal amount is got and it is transferred to the PRINCIPAL_DUE address.

If there is a nonzero prepaid amount, it is used to pay the due amounts.

As the last step, the Kafka event with the remaining due amounts is emitted. It is used by the service to perform an auto deduction.

Overdue date schedule

The schedule runs on the loan due date at 23:59:00 local Philippines time.

The schedule checks if there is a nonzero due interest and principal. If there is any, it transfers due amounts to the overdue addresses.

The debt manager postings are posted to deduct the debt immediately after there are enough funds on the main and pocket accounts.

Incoming transactions

There are multiple types of transactions that are accepted by the smart contract. All the others are rejected. The rejections are implemented in pre_posting_code hook and the following logic in post_posting_code hook.

Regular and debt repayment

The regular payments are initiated by the loan-manager and the debt payments are initiated by the debt manager. They are the same from the view of the smart contract.

The payment is rejected if it is greater than the outstanding payments amount.

The overdue installments are repaid first. The smart contract goes through all overdue installments and it repays the installment followed by the principal until the whole repayment is used or the overdue installments are completely paid.

If the repayment is not fully used, the due installment is paid in the same order - the interest at first followed by the principal.

If the all planned installments are fully paid, the Kafka event message is sent to notify the service about loan closure.

The implementation is done in handle_regular_repayment method in loan/features/repayment.py.

Early repayment

The early repayment can be performed on the loan where are no outstanding payments only.

The already accrued interest is collected, rounded and moved to the interest due. The principal is transferred to the principal due so the sum of the interest due and the principal due equals the amount of the early repayment.

The installment plan parameters are not updated here. The installment plan is always calculated based on the parameters set up by the loan-manager as the account instance parameters.

If the loan is fully paid after the early repayment, the Kafka event message is sent to notify the service about loan closure.

The prepayment amount is not touched by the early repayment except the situation when the early repayment together with the prepayment is enough to repay to whole loan. In that situation the loan is fully repaid.

The implementation is done in handle_early_repayment method in loan/features/repayment.py.

Prepayment

The prepayment can be performed on the loan where are no outstanding payments only. The incoming funds are moved to the PREPAID address and the Kafka message with the new prepayment amount is emitted.

The implementation is done in handle_prepayment method in loan/features/repayment.py.

Debug postings

The debug postings are used to bypass the restrictions and allows to send arbitrary postings the loan. The main purpose of these postings is to allow fix of the loan in inconsistent state and to perform various debug scenarios.

This postings are allowed when the debug mode is enabled by the global parameter only.

Account opening

After the loan opening, the principal is transferred to the deposit account - the customer’s main account.

If there is an opening fee it is deducted from the deposit account. Since the opening fee is always smaller than the principal, this operation cannot fail.

The implementation is done in post_activate_code hook.

Account closing

Before closing the account the total outstanding debt is checked and it is rejected if there is an outstanding debt. The marked paid interest is moved to the internal bank account.

The implementation is done in close_code hook.

Loan account addresses

Address

Value

Description

PRINCIPAL

Positive

The remaining principal do be paid. The sum of all future installment principals. It is partially moved to the PRINCIPAL_DUE on the due date.

PRINCIPAL_DUE

Positive

The principal of current unpaid installment. The value stays here for the due day only. It is moved to the PRINCIPAL_OVERDUE after one day.

PRINCIPAL_OVERDUE

Positive

The sum of all overdue installments principal.

ACCRUED_INTEREST

Positive

The accrued interest. It is fully moved to the INTEREST_DUE on the due date.

INTEREST_DUE

Positive

The interest of current unpaid installment. The value stays here for the due day only. It is moved to the INTEREST_OVERDUE after one day.

INTEREST_OVERDUE

Positive

The sum of all overdue installments interest.

INTEREST_PAID

Negative

The total value of the already paid interest.

INTERNAL_CONTRA

Positive

The contra address for the interest accruing. It is the target on interest accruing and source on interest paying.

PREPAID

Negative

The total prepaid amount. It is used on due date to pay the loan.

DEFAULT

Negative

The default address for all incoming postings. It should be zero after the incoming postings are processed.