Skip to content

Instantly share code, notes, and snippets.

@marco-martins
Last active June 24, 2022 21:36
Show Gist options
  • Save marco-martins/8be86ba7c24dd6eafcf8a7288253a7ed to your computer and use it in GitHub Desktop.
Save marco-martins/8be86ba7c24dd6eafcf8a7288253a7ed to your computer and use it in GitHub Desktop.
Bank Loan Using Compound Interest Formula
{"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":[]}
/*
* 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();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment