Skip to content

Instantly share code, notes, and snippets.

@palas
Last active April 1, 2021 09:54
Show Gist options
  • Save palas/201b773efa87f0357cb96188dde23640 to your computer and use it in GitHub Desktop.
Save palas/201b773efa87f0357cb96188dde23640 to your computer and use it in GitHub Desktop.
Coupon Bond Guaranteed
When
[Case
(Deposit
(Role "Investor")
(Role "Guarantor")
(Token "" "")
(AddValue
(MulValue
(Constant 3)
(ConstantParam "Interest instalment")
)
(ConstantParam "Principal")
)
)
(When
[Case
(Deposit
(Role "Issuer")
(Role "Investor")
(Token "" "")
(ConstantParam "Principal")
)
(Pay
(Role "Issuer")
(Party (Role "Issuer"))
(Token "" "")
(ConstantParam "Principal")
(When
[Case
(Deposit
(Role "Investor")
(Role "Issuer")
(Token "" "")
(ConstantParam "Interest instalment")
)
(Pay
(Role "Investor")
(Party (Role "Investor"))
(Token "" "")
(ConstantParam "Interest instalment")
(Pay
(Role "Investor")
(Party (Role "Guarantor"))
(Token "" "")
(ConstantParam "Interest instalment")
(When
[Case
(Deposit
(Role "Investor")
(Role "Issuer")
(Token "" "")
(ConstantParam "Interest instalment")
)
(Pay
(Role "Investor")
(Party (Role "Investor"))
(Token "" "")
(ConstantParam "Interest instalment")
(Pay
(Role "Investor")
(Party (Role "Guarantor"))
(Token "" "")
(ConstantParam "Interest instalment")
(When
[Case
(Deposit
(Role "Investor")
(Role "Issuer")
(Token "" "")
(AddValue
(ConstantParam "Interest instalment")
(ConstantParam "Principal")
)
)
(Pay
(Role "Investor")
(Party (Role "Investor"))
(Token "" "")
(AddValue
(ConstantParam "Interest instalment")
(ConstantParam "Principal")
)
(Pay
(Role "Investor")
(Party (Role "Guarantor"))
(Token "" "")
(AddValue
(ConstantParam "Interest instalment")
(ConstantParam "Principal")
)
Close
)
)]
150 Close
)
)
)]
120 Close
)
)
)]
90 Close
)
)]
60
(Pay
(Role "Investor")
(Party (Role "Guarantor"))
(Token "" "")
(AddValue
(MulValue
(Constant 3)
(ConstantParam "Interest instalment")
)
(ConstantParam "Principal")
)
Close
)
)]
30 Close
{-# LANGUAGE OverloadedStrings #-}
module CouponBondGuaranteed where
import Language.Marlowe.Extended
main :: IO ()
main = print . pretty $ contract
-- We can set explicitRefunds True to run Close refund analysis
-- but we get a shorter contract if we set it to False
explicitRefunds :: Bool
explicitRefunds = False
guarantor, investor, issuer :: Party
guarantor = Role "Guarantor"
investor = Role "Investor"
issuer = Role "Issuer"
principal, instalment :: Value
principal = ConstantParam "Principal"
instalment = ConstantParam "Interest instalment"
guaranteedAmount :: Integer -> Value
guaranteedAmount instalments = AddValue (MulValue (Constant instalments) instalment) principal
lastInstalment :: Value
lastInstalment = AddValue instalment principal
deposit :: Value -> Party -> Party -> Timeout -> Contract -> Contract -> Contract
deposit amount by toAccount timeout timeoutContinuation continuation =
When [Case (Deposit toAccount by ada amount) continuation]
timeout
timeoutContinuation
refundGuarantor :: Value -> Contract -> Contract
refundGuarantor amount continuation = Pay investor (Party guarantor) ada amount continuation
transfer :: Value -> Party -> Party -> Timeout -> Contract -> Contract -> Contract
transfer amount from to timeout timeoutContinuation continuation =
deposit amount from to timeout timeoutContinuation
$ Pay to (Party to) ada amount
continuation
giveCollateralToInvestor :: Value -> Contract
giveCollateralToInvestor amount
| explicitRefunds = Pay investor (Party investor) ada amount Close
| otherwise = Close
contract :: Contract
contract = deposit (guaranteedAmount 3) guarantor investor
30 Close
$ transfer principal investor issuer
60 (refundGuarantor (guaranteedAmount 3) Close)
$ transfer instalment issuer investor
90 (giveCollateralToInvestor $ guaranteedAmount 3)
$ refundGuarantor instalment
$ transfer instalment issuer investor
120 (giveCollateralToInvestor $ guaranteedAmount 2)
$ refundGuarantor instalment
$ transfer lastInstalment issuer investor
150 (giveCollateralToInvestor $ guaranteedAmount 1)
$ refundGuarantor lastInstalment
Close
{"valueParameterDescriptions":[["Interest instalment","Amount of Lovelace that will be paid by the \"Issuer\" every 30 slots for 3 iterations."],["Principal","Amount of Lovelace that will be borrowed by the \"Issuer\"."]],"slotParameterDescriptions":[],"roleDescriptions":[["Guarantor","Provides a collateral in case the \"Issuer\" defaults."],["Investor","Provides the money that the \"Issuer\" borrows."],["Issuer","Borrows the money provided by the \"Investor\" and returns it together with three \"Interest instalment\"s."]],"contractType":"CB","contractName":"Coupon Bond Guaranteed","contractDescription":"Debt agreement between an \"Investor\" and an \"Issuer\". \"Investor\" will advance the \"Principal\" amount at the beginning of the contract, and the \"Issuer\" will pay back \"Interest instalment\" every 30 slots and the \"Principal\" amount by the end of 3 instalments. The debt is backed by a collateral provided by the \"Guarantor\" which will be refunded as long as the \"Issuer\" pays back on time.","choiceDescriptions":[]}
/* We can set explicitRefunds true to run Close refund analysis
but we get a shorter contract if we set it to false */
const explicitRefunds: Boolean = false;
const guarantor: Party = Role("Guarantor");
const investor: Party = Role("Investor");
const issuer: Party = Role("Issuer");
const principal: Value = ConstantParam("Principal");
const instalment: Value = ConstantParam("Interest instalment");
function guaranteedAmount(instalments: SomeNumber): Value {
return AddValue(MulValue(Constant(instalments), instalment), principal);
}
const lastInstalment: Value = AddValue(instalment, principal);
function deposit(amount: Value, by: Party, toAccount: Party,
timeout: ETimeout, timeoutContinuation: Contract,
continuation: Contract): Contract {
return When([Case(Deposit(toAccount, by, ada, amount), continuation)],
timeout,
timeoutContinuation);
}
function refundGuarantor(amount: Value, continuation: Contract): Contract {
return Pay(investor, Party(guarantor), ada, amount, continuation)
}
function transfer(amount: Value, from: Party, to: Party,
timeout: ETimeout, timeoutContinuation: Contract,
continuation: Contract): Contract {
return deposit(amount, from, to, timeout, timeoutContinuation,
Pay(to, Party(to), ada, amount,
continuation))
}
function giveCollateralToInvestor(amount: Value): Contract {
if (explicitRefunds) {
return Pay(investor, Party(investor), ada, amount,
Close);
} else {
return Close;
}
}
const contract: Contract =
deposit(guaranteedAmount(3n), guarantor, investor,
30n, Close,
transfer(principal, investor, issuer,
60n, refundGuarantor(guaranteedAmount(3n), Close),
transfer(instalment, issuer, investor,
90n, giveCollateralToInvestor(guaranteedAmount(3n)),
refundGuarantor(instalment,
transfer(instalment, issuer, investor,
120n, giveCollateralToInvestor(guaranteedAmount(2n)),
refundGuarantor(instalment,
transfer(lastInstalment, issuer, investor,
150n, giveCollateralToInvestor(guaranteedAmount(1n)),
refundGuarantor(lastInstalment,
Close))))))));
return contract;
When
[Case
(Deposit
(Role "Investor")
(Role "Guarantor")
(Token "" "")
(AddValue
(MulValue
(Constant 3)
(ConstantParam "Interest instalment")
)
(ConstantParam "Principal")
)
)
(When
[Case
(Deposit
(Role "Issuer")
(Role "Investor")
(Token "" "")
(ConstantParam "Principal")
)
(Pay
(Role "Issuer")
(Party (Role "Issuer"))
(Token "" "")
(ConstantParam "Principal")
(When
[Case
(Deposit
(Role "Investor")
(Role "Issuer")
(Token "" "")
(ConstantParam "Interest instalment")
)
(Pay
(Role "Investor")
(Party (Role "Investor"))
(Token "" "")
(ConstantParam "Interest instalment")
(Pay
(Role "Investor")
(Party (Role "Guarantor"))
(Token "" "")
(ConstantParam "Interest instalment")
(When
[Case
(Deposit
(Role "Investor")
(Role "Issuer")
(Token "" "")
(ConstantParam "Interest instalment")
)
(Pay
(Role "Investor")
(Party (Role "Investor"))
(Token "" "")
(ConstantParam "Interest instalment")
(Pay
(Role "Investor")
(Party (Role "Guarantor"))
(Token "" "")
(ConstantParam "Interest instalment")
(When
[Case
(Deposit
(Role "Investor")
(Role "Issuer")
(Token "" "")
(AddValue
(ConstantParam "Interest instalment")
(ConstantParam "Principal")
)
)
(Pay
(Role "Investor")
(Party (Role "Investor"))
(Token "" "")
(AddValue
(ConstantParam "Interest instalment")
(ConstantParam "Principal")
)
(Pay
(Role "Investor")
(Party (Role "Guarantor"))
(Token "" "")
(AddValue
(ConstantParam "Interest instalment")
(ConstantParam "Principal")
)
Close
)
)]
150 Close
)
)
)]
120 Close
)
)
)]
90 Close
)
)]
60
(Pay
(Role "Investor")
(Party (Role "Guarantor"))
(Token "" "")
(AddValue
(MulValue
(Constant 3)
(ConstantParam "Interest instalment")
)
(ConstantParam "Principal")
)
Close
)
)]
30 Close
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment