Last active
June 24, 2022 21:36
-
-
Save marco-martins/8be86ba7c24dd6eafcf8a7288253a7ed to your computer and use it in GitHub Desktop.
Bank Loan Using Compound Interest Formula
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"valueParameterInfo":[],"timeParameterDescriptions":[["Bank Deposit Deadline","Bank deposit deadline"],["Client Deposit Deadline","Client deposit deadline"]],"roleDescriptions":[],"contractType":"Other","contractShortDescription":"Unknown","contractName":"Unknown","contractLongDescription":"We couldn't find information about this contract","choiceInfo":[]} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Simulates an auto loan for a used car with compound interest. Native token represents title for the car. | |
* Credits to @johnshearing for providing this example in Haskell | |
* https://gist.github.com/johnshearing/79e4e10cf7ad5860a89c932780e65191 | |
*/ | |
// PARAMS | |
const bankDepositDeadline: Timeout = TimeParam("Bank Deposit Deadline") | |
const clientDepositDeadline: Timeout = TimeParam("Client Deposit Deadline") | |
// PARTIES | |
const bank: Party = Role("Bank") | |
const borrower: Party = Role("Borrower") | |
// SETTINGS | |
// Input loan amount, imagine the car costs 5000 ADA | |
const loanAmount: SomeNumber = 5000000000 | |
// Input number of payments, imagine 36 monthly payments | |
const numberOfPayments: SomeNumber = 36 | |
// Input interest rate in percent per year, this goes to the bank. e.g. 8% | |
const interestPctPerYear: SomeNumber = 8 | |
/* Input the number of payments per year. | |
* The formula compounds the interest every payment period. | |
* Monthly in this case but you can set it to whatever you want using the periods_per_year field. | |
* We imagine monthly payments | |
*/ | |
const periodsPerYear: SomeNumber = 12 | |
/* Imagining a car loan smart contract in Marlowe for 5000 ADA as per the example found at the following link. | |
* https://www.double-entry-bookkeeping.com/periodic-payment/auto-loan-payment/ | |
* paymentAmount = PV x i / (1 - 1 / (1 + i)^n) | |
* PV = value of the auto loan (loanAmount) | |
* n = number of months = 3 x 12 = 36 | |
* i = nominal rate = 8%/12 per month | |
*/ | |
const nominalRate: SomeNumber = (interestPctPerYear / 100) / periodsPerYear | |
const paymentAmount: SomeNumber = loanAmount * nominalRate / (1 - 1 / (1 + nominalRate) ** numberOfPayments) | |
// FUNCTIONS | |
const bankDepositCarTitle = () => | |
Deposit(bank, bank, Token("e0d123", "Car Title"), Constant(1)) | |
const bankPayToClient = () => | |
Pay(bank, Party(borrower), Token("e0d123", "Car Title"), Constant(1), Close) | |
const borrowerMakeDeposits = (i: number): Contract => { | |
i-- | |
return When([ | |
Case( | |
Deposit(bank, borrower, ada, Math.floor(paymentAmount)), | |
// Recursive call, IF the borrower have pending deposits THEN make borrower make deposit ELSE make the final payments | |
i > 0 ? borrowerMakeDeposits(i) : bankPayToClient() | |
) | |
], clientDepositDeadline, Close) | |
} | |
const contract = (): Contract => | |
When([ | |
Case( | |
bankDepositCarTitle(), | |
borrowerMakeDeposits(numberOfPayments) | |
) | |
], bankDepositDeadline, Close) | |
return contract(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment