Universal: example parties renamed

This commit is contained in:
sofusmortensen 2016-09-07 10:42:39 +02:00
parent 1ceee48696
commit c7b164897b
10 changed files with 125 additions and 130 deletions

View File

@ -12,7 +12,6 @@ import java.util.*
interface Arrangement
// A base arrangement with no rights and no obligations. Contract cancellation/termination is a transition to ``Zero``.
class Zero() : Arrangement {
override fun hashCode(): Int {
@ -28,11 +27,7 @@ class Zero() : Arrangement {
//
// todo: should be replaced with something that uses Corda assets and/or cash?
// todo: should only be allowed to transfer non-negative amounts
data class Transfer(val amount: Perceivable<BigDecimal>, val currency: Currency, val from: Party, val to: Party) : Arrangement {
constructor(amount: BigDecimal, currency: Currency, from: Party, to: Party ) : this(const(amount), currency, from, to)
constructor(amount: Amount<Currency>, from: Party, to: Party ) : this(const(BigDecimal(amount.quantity)), amount.token, from, to)
}
data class Transfer(val amount: Perceivable<BigDecimal>, val currency: Currency, val from: Party, val to: Party) : Arrangement
// A combinator over a list of arrangements. Each arrangement in list will create a separate independent arrangement state.
// The ``And`` combinator cannot be root in a arrangement.

View File

@ -141,7 +141,7 @@ class UniversalContract : Contract {
is Transfer -> {
val amount = eval(tx, arrangement.amount)
requireThat { "transferred quantity is non-negative" by (amount >= BigDecimal.ZERO) }
Transfer(amount, arrangement.currency, arrangement.from, arrangement.to)
Transfer(const(amount), arrangement.currency, arrangement.from, arrangement.to)
}
is And -> And(arrangement.arrangements.map { validateImmediateTransfers(tx, it) }.toSet())
else -> arrangement

View File

@ -24,7 +24,7 @@ open class ContractBuilder {
val contracts = mutableListOf<Arrangement>()
fun Party.gives(beneficiary: Party, amount: BigDecimal, currency: Currency) : Transfer {
val c = Transfer(amount, currency, this, beneficiary)
val c = Transfer(const(amount), currency, this, beneficiary)
contracts.add( c )
return c
}

View File

@ -20,14 +20,14 @@ class Cap {
val contract = arrange {
rollOut("2016-04-01", "2017-04-01", Frequency.Quarterly) {
(roadRunner or wileECoyote).may {
(acmeCorp or highStreetBank).may {
"exercise".anytime {
val floating = interest(notional, "act/365", fix("LIBOR", start, Tenor("6M")), start, end)
val fixed = interest(notional, "act/365", 0.5.bd, start, end)
wileECoyote.gives(roadRunner, floating - fixed, currency)
highStreetBank.gives(acmeCorp, floating - fixed, currency)
next()
}
} or roadRunner.may {
} or acmeCorp.may {
"skip".anytime {
next()
}
@ -42,15 +42,15 @@ class Cap {
rollOut("2016-04-01", "2017-04-01", Frequency.Quarterly, object {
val limit = variable(150.K)
}) {
(roadRunner or wileECoyote).may {
(acmeCorp or highStreetBank).may {
"exercise".anytime {
val floating = interest(notional, "act/365", fix("LIBOR", start, Tenor("6M")), start, end)
val fixed = interest(notional, "act/365", 0.5.bd, start, end)
val payout = (floating - fixed).plus()
wileECoyote.gives(roadRunner, payout, currency)
highStreetBank.gives(acmeCorp, payout, currency)
next(vars.limit to vars.limit - payout)
}
} or roadRunner.may {
} or acmeCorp.may {
"skip".anytime {
next()
}
@ -67,11 +67,11 @@ class Cap {
this `fails with` "transaction has a single command"
tweak {
command(roadRunner.owningKey) { UniversalContract.Commands.Issue() }
command(acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
this `fails with` "the transaction is signed by all liable parties"
}
command(wileECoyote.owningKey) { UniversalContract.Commands.Issue() }
command(highStreetBank.owningKey) { UniversalContract.Commands.Issue() }
this.verifies()
}

View File

@ -24,26 +24,26 @@ class Caplet {
val currency = EUR
val contract = arrange {
(roadRunner or wileECoyote).may {
(acmeCorp or highStreetBank).may {
"exercise".anytime() {
val floating = interest(notional, "act/365", fix("LIBOR", dt, Tenor("6M")), "2016-04-01", "2016-10-01")
val fixed = interest(notional, "act/365", 0.5.bd, "2016-04-01", "2016-10-01")
wileECoyote.gives(roadRunner, (floating - fixed).plus(), currency)
highStreetBank.gives(acmeCorp, (floating - fixed).plus(), currency)
}
}
}
val contractFixed = arrange {
(roadRunner or wileECoyote).may {
(acmeCorp or highStreetBank).may {
"exercise".anytime() {
val floating = interest(notional, "act/365", 1.0.bd, "2016-04-01", "2016-10-01")
val fixed = interest(notional, "act/365", 0.5.bd, "2016-04-01", "2016-10-01")
wileECoyote.gives(roadRunner, (floating - fixed).plus(), currency)
highStreetBank.gives(acmeCorp, (floating - fixed).plus(), currency)
}
}
}
val contractFinal = arrange { wileECoyote.gives(roadRunner, 250.K, EUR) }
val contractFinal = arrange { highStreetBank.gives(acmeCorp, 250.K, EUR) }
val stateStart = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), contract)
@ -60,11 +60,11 @@ class Caplet {
this `fails with` "transaction has a single command"
tweak {
command(roadRunner.owningKey) { UniversalContract.Commands.Issue() }
command(acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
this `fails with` "the transaction is signed by all liable parties"
}
command(wileECoyote.owningKey) { UniversalContract.Commands.Issue() }
command(highStreetBank.owningKey) { UniversalContract.Commands.Issue() }
this.verifies()
}
@ -78,11 +78,11 @@ class Caplet {
timestamp(TEST_TX_TIME_1)
tweak {
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("some undefined name") }
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
this `fails with` "action must be defined"
}
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("exercise") }
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("exercise") }
this.verifies()
}
@ -96,38 +96,38 @@ class Caplet {
timestamp(TEST_TX_TIME_1)
tweak {
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("some undefined name") }
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
this `fails with` "action must be defined"
}
tweak {
// wrong source
command(wileECoyote.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBORx", dt, Tenor("6M")), 1.0.bd))) }
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBORx", dt, Tenor("6M")), 1.0.bd))) }
this `fails with` "relevant fixing must be included"
}
tweak {
// wrong date
command(wileECoyote.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", dt.plusYears(1), Tenor("6M")), 1.0.bd))) }
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", dt.plusYears(1), Tenor("6M")), 1.0.bd))) }
this `fails with` "relevant fixing must be included"
}
tweak {
// wrong tenor
command(wileECoyote.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", dt, Tenor("3M")), 1.0.bd))) }
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", dt, Tenor("3M")), 1.0.bd))) }
this `fails with` "relevant fixing must be included"
}
tweak {
command(wileECoyote.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", dt, Tenor("6M")), 1.5.bd))) }
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", dt, Tenor("6M")), 1.5.bd))) }
this `fails with` "output state does not reflect fix command"
}
command(wileECoyote.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", dt, Tenor("6M")), 1.0.bd))) }
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", dt, Tenor("6M")), 1.0.bd))) }
this.verifies()
}

View File

@ -10,9 +10,9 @@ import java.util.*
*/
// Test parties
val roadRunner = Party("Road Runner", generateKeyPair().public)
val wileECoyote = Party("Wile E. Coyote", generateKeyPair().public)
val porkyPig = Party("Porky Pig", generateKeyPair().public)
val acmeCorp = Party("ACME Corporation", generateKeyPair().public)
val highStreetBank = Party("High Street Bank", generateKeyPair().public)
val momAndPop = Party("Mom and Pop", generateKeyPair().public)
val acmeCorporationHasDefaulted = DummyPerceivable<Boolean>()
@ -28,11 +28,11 @@ class ContractDefinition {
val cds_contract = arrange {
roadRunner.may {
acmeCorp.may {
"payout".givenThat(acmeCorporationHasDefaulted and before("2017-09-01")) {
wileECoyote.gives(roadRunner, 1.M, USD)
highStreetBank.gives(acmeCorp, 1.M, USD)
}
} or wileECoyote.may {
} or highStreetBank.may {
"expire".givenThat(after("2017-09-01")) {
zero
}
@ -41,12 +41,12 @@ class ContractDefinition {
val american_fx_option = arrange {
roadRunner.may {
acmeCorp.may {
"exercise".anytime {
wileECoyote.gives(roadRunner, 1.M, EUR)
roadRunner.gives(wileECoyote, 1200.K, USD)
highStreetBank.gives(acmeCorp, 1.M, EUR)
acmeCorp.gives(highStreetBank, 1200.K, USD)
}
} or wileECoyote.may {
} or highStreetBank.may {
"expire".givenThat(after("2017-09-01")) {
zero
}
@ -55,16 +55,16 @@ class ContractDefinition {
val european_fx_option = arrange {
roadRunner.may {
acmeCorp.may {
"exercise".anytime {
(roadRunner or wileECoyote).may {
(acmeCorp or highStreetBank).may {
"execute".givenThat(after("2017-09-01")) {
wileECoyote.gives(roadRunner, 1.M, EUR)
roadRunner.gives(wileECoyote, 1200.K, USD)
highStreetBank.gives(acmeCorp, 1.M, EUR)
acmeCorp.gives(highStreetBank, 1200.K, USD)
}
}
}
} or wileECoyote.may {
} or highStreetBank.may {
"expire".givenThat(after("2017-09-01")) {
zero
}

View File

@ -15,23 +15,23 @@ class FXSwap {
val TEST_TX_TIME_TOO_EARLY: Instant get() = Instant.parse("2017-08-31T12:00:00.00Z")
val contract = arrange {
(roadRunner or wileECoyote).may {
(acmeCorp or highStreetBank).may {
"execute".givenThat(after("2017-09-01")) {
wileECoyote.gives(roadRunner, 1200.K, USD)
roadRunner.gives(wileECoyote, 1.M, EUR)
highStreetBank.gives(acmeCorp, 1200.K, USD)
acmeCorp.gives(highStreetBank, 1.M, EUR)
}
}
}
val transfer1 = arrange { wileECoyote.gives(roadRunner, 1200.K, USD) }
val transfer2 = arrange { roadRunner.gives(wileECoyote, 1.M, EUR) }
val transfer1 = arrange { highStreetBank.gives(acmeCorp, 1200.K, USD) }
val transfer2 = arrange { acmeCorp.gives(highStreetBank, 1.M, EUR) }
val outState1 = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), transfer1 )
val outState2 = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), transfer2 )
val transferBad1 = arrange { wileECoyote.gives(roadRunner, 1200.K, GBP) } // wrong currency
val transferBad2 = arrange { roadRunner.gives(wileECoyote, 900.K, EUR) } // wrong amount
val transferBad3 = arrange { wileECoyote.gives(wileECoyote, 1.M, EUR) } // wrong party
val transferBad1 = arrange { highStreetBank.gives(acmeCorp, 1200.K, GBP) } // wrong currency
val transferBad2 = arrange { acmeCorp.gives(highStreetBank, 900.K, EUR) } // wrong amount
val transferBad3 = arrange { highStreetBank.gives(highStreetBank, 1.M, EUR) } // wrong party
val outStateBad1 = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), transferBad1 )
val outStateBad2 = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), transferBad2 )
@ -49,15 +49,15 @@ class FXSwap {
this `fails with` "transaction has a single command"
tweak {
command(roadRunner.owningKey) { UniversalContract.Commands.Issue() }
command(acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
this `fails with` "the transaction is signed by all liable parties"
}
tweak {
command(wileECoyote.owningKey) { UniversalContract.Commands.Issue() }
command(highStreetBank.owningKey) { UniversalContract.Commands.Issue() }
this `fails with` "the transaction is signed by all liable parties"
}
command(wileECoyote.owningKey, roadRunner.owningKey) { UniversalContract.Commands.Issue() }
command(highStreetBank.owningKey, acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
this.verifies()
}
@ -72,11 +72,11 @@ class FXSwap {
timestamp(TEST_TX_TIME_1)
tweak {
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("some undefined name") }
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
this `fails with` "action must be defined"
}
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("execute") }
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("execute") }
this.verifies()
}
@ -91,11 +91,11 @@ class FXSwap {
timestamp(TEST_TX_TIME_1)
tweak {
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("some undefined name") }
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
this `fails with` "action must be defined"
}
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("execute") }
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("execute") }
this.verifies()
}
@ -109,7 +109,7 @@ class FXSwap {
output { outState2 }
timestamp(TEST_TX_TIME_1)
command(porkyPig.owningKey) { UniversalContract.Commands.Action("execute") }
command(momAndPop.owningKey) { UniversalContract.Commands.Action("execute") }
this `fails with` "action must be authorized"
}
}
@ -122,7 +122,7 @@ class FXSwap {
output { outState2 }
timestamp(TEST_TX_TIME_TOO_EARLY)
command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") }
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("execute") }
this `fails with` "condition must be met"
}
}
@ -134,7 +134,7 @@ class FXSwap {
output { outState1 }
timestamp(TEST_TX_TIME_1)
command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") }
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("execute") }
this `fails with` "output state must match action result state"
}
}
@ -147,7 +147,7 @@ class FXSwap {
output { outStateBad2 }
timestamp(TEST_TX_TIME_1)
command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") }
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("execute") }
this `fails with` "output states must match action result state"
}
}
@ -160,7 +160,7 @@ class FXSwap {
output { outState2 }
timestamp(TEST_TX_TIME_1)
command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") }
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("execute") }
this `fails with` "output states must match action result state"
}
}
@ -173,7 +173,7 @@ class FXSwap {
output { outStateBad3 }
timestamp(TEST_TX_TIME_1)
command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") }
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("execute") }
this `fails with` "output states must match action result state"
}
}

View File

@ -17,28 +17,28 @@ class Swaption {
val coupon = 1.5.bd
val dreary_contract = arrange {
(wileECoyote or roadRunner).may {
(highStreetBank or acmeCorp).may {
"proceed".givenThat(after("01/07/2015")) {
wileECoyote.gives(roadRunner, libor(notional, "01/04/2015", "01/07/2015"), currency)
roadRunner.gives(wileECoyote, interest(notional, "act/365", coupon, "01/04/2015", "01/07/2015"), currency)
(wileECoyote or roadRunner).may {
highStreetBank.gives(acmeCorp, libor(notional, "01/04/2015", "01/07/2015"), currency)
acmeCorp.gives(highStreetBank, interest(notional, "act/365", coupon, "01/04/2015", "01/07/2015"), currency)
(highStreetBank or acmeCorp).may {
"proceed".givenThat(after("01/10/2015")) {
wileECoyote.gives(roadRunner, libor(notional, "01/07/2015", "01/10/2015"), currency)
roadRunner.gives(wileECoyote, interest(notional, "act/365", coupon, "01/07/2015", "01/10/2015"), currency)
highStreetBank.gives(acmeCorp, libor(notional, "01/07/2015", "01/10/2015"), currency)
acmeCorp.gives(highStreetBank, interest(notional, "act/365", coupon, "01/07/2015", "01/10/2015"), currency)
(wileECoyote or roadRunner).may {
(highStreetBank or acmeCorp).may {
// etc ...
}
}
} or roadRunner.may {
} or acmeCorp.may {
"cancel".anytime {
roadRunner.gives(wileECoyote, 10.K, USD)
acmeCorp.gives(highStreetBank, 10.K, USD)
}
}
}
} or roadRunner.may {
} or acmeCorp.may {
"cancel".anytime {
roadRunner.gives(wileECoyote, 10.K, USD)
acmeCorp.gives(highStreetBank, 10.K, USD)
}
}
}
@ -46,15 +46,15 @@ class Swaption {
val elegant_contract = arrange {
rollOut("01/04/2015", "01/04/2025", Frequency.Quarterly) {
(wileECoyote or roadRunner).may {
(highStreetBank or acmeCorp).may {
"proceed".givenThat(after(start)) {
wileECoyote.gives(roadRunner, libor(notional, start, end), currency)
roadRunner.gives(wileECoyote, interest(notional, "act/365", coupon, start, end), currency)
highStreetBank.gives(acmeCorp, libor(notional, start, end), currency)
acmeCorp.gives(highStreetBank, interest(notional, "act/365", coupon, start, end), currency)
next()
}
} or roadRunner.may {
} or acmeCorp.may {
"cancel".anytime {
roadRunner.gives(wileECoyote, 10.K, currency)
acmeCorp.gives(highStreetBank, 10.K, currency)
}
}
}
@ -66,18 +66,18 @@ class Swaption {
rollOut("01/04/2015", "01/04/2016", Frequency.Quarterly, object {
val cap = variable(150.K)
}) {
roadRunner.may {
acmeCorp.may {
"exercise".givenThat(before(end)) {
val payout = (EUR / USD - strike).plus() * notional
(roadRunner or wileECoyote).may {
(acmeCorp or highStreetBank).may {
"proceed".givenThat(after(end)) {
wileECoyote.gives(roadRunner, payout, USD)
highStreetBank.gives(acmeCorp, payout, USD)
next(vars.cap to vars.cap - payout)
}
}
}
} or (roadRunner or wileECoyote).may {
} or (acmeCorp or highStreetBank).may {
"proceedWithoutExercise".givenThat(after(end)) {
next()
}
@ -89,18 +89,18 @@ class Swaption {
rollOut("01/04/2015", "01/04/2016", Frequency.Quarterly, object {
val uses = variable(4)
}) {
roadRunner.may {
acmeCorp.may {
"exercise".givenThat(before(end)) {
val payout = (EUR / USD - strike).plus() * notional
(roadRunner or wileECoyote).may {
(acmeCorp or highStreetBank).may {
"proceed".givenThat(after(end)) {
wileECoyote.gives(roadRunner, payout, currency)
highStreetBank.gives(acmeCorp, payout, currency)
next(vars.uses to vars.uses - 1)
}
}
}
} or (roadRunner or wileECoyote).may {
} or (acmeCorp or highStreetBank).may {
"proceedWithoutExercise".givenThat(after(end)) {
next()
}

View File

@ -12,26 +12,26 @@ import java.time.Instant
class ZeroCouponBond {
val contract = arrange {
(roadRunner or wileECoyote).may {
(acmeCorp or highStreetBank).may {
"execute".givenThat(after("2017-09-01")) {
wileECoyote.gives(roadRunner, 100.K, GBP)
highStreetBank.gives(acmeCorp, 100.K, GBP)
}
}
}
val contractMove = arrange {
(porkyPig or wileECoyote).may {
(momAndPop or highStreetBank).may {
"execute".givenThat(after("2017-09-01")) {
wileECoyote.gives(porkyPig, 100.K, GBP)
highStreetBank.gives(momAndPop, 100.K, GBP)
}
}
}
val TEST_TX_TIME_1: Instant get() = Instant.parse("2017-09-02T12:00:00.00Z")
val transfer = arrange { wileECoyote.gives(roadRunner, 100.K, GBP) }
val transferWrong = arrange { wileECoyote.gives(roadRunner, 80.K, GBP) }
val transfer = arrange { highStreetBank.gives(acmeCorp, 100.K, GBP) }
val transferWrong = arrange { highStreetBank.gives(acmeCorp, 80.K, GBP) }
val inState = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), contract )
@ -55,11 +55,11 @@ class ZeroCouponBond {
this `fails with` "transaction has a single command"
tweak {
command(roadRunner.owningKey) { UniversalContract.Commands.Issue() }
command(acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
this `fails with` "the transaction is signed by all liable parties"
}
command(wileECoyote.owningKey) { UniversalContract.Commands.Issue() }
command(highStreetBank.owningKey) { UniversalContract.Commands.Issue() }
this.verifies()
}
@ -73,11 +73,11 @@ class ZeroCouponBond {
timestamp(TEST_TX_TIME_1)
tweak {
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("some undefined name") }
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
this `fails with` "action must be defined"
}
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("execute") }
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("execute") }
this.verifies()
}
@ -90,7 +90,7 @@ class ZeroCouponBond {
output { outState }
timestamp(TEST_TX_TIME_1)
command(porkyPig.owningKey) { UniversalContract.Commands.Action("execute") }
command(momAndPop.owningKey) { UniversalContract.Commands.Action("execute") }
this `fails with` "action must be authorized"
}
}
@ -102,7 +102,7 @@ class ZeroCouponBond {
output { outStateWrong }
timestamp(TEST_TX_TIME_1)
command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") }
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("execute") }
this `fails with` "output state must match action result state"
}
}
@ -114,24 +114,24 @@ class ZeroCouponBond {
tweak {
output { outStateMove }
command(roadRunner.owningKey) {
UniversalContract.Commands.Move(roadRunner, porkyPig)
command(acmeCorp.owningKey) {
UniversalContract.Commands.Move(acmeCorp, momAndPop)
}
this `fails with` "the transaction is signed by all liable parties"
}
tweak {
output { inState }
command(roadRunner.owningKey, porkyPig.owningKey, wileECoyote.owningKey) {
UniversalContract.Commands.Move(roadRunner, porkyPig)
command(acmeCorp.owningKey, momAndPop.owningKey, highStreetBank.owningKey) {
UniversalContract.Commands.Move(acmeCorp, momAndPop)
}
this `fails with` "output state does not reflect move command"
}
output { outStateMove}
command(roadRunner.owningKey, porkyPig.owningKey, wileECoyote.owningKey) {
UniversalContract.Commands.Move(roadRunner, porkyPig)
command(acmeCorp.owningKey, momAndPop.owningKey, highStreetBank.owningKey) {
UniversalContract.Commands.Move(acmeCorp, momAndPop)
}
this.verifies()
}

View File

@ -14,9 +14,9 @@ import java.util.*
// various example arrangements using basic syntax
val cds_contract = arrange {
roadRunner.may {
acmeCorp.may {
"claim".givenThat(acmeCorporationHasDefaulted and before("2017-09-01")) {
wileECoyote.gives(roadRunner, 1.M, USD)
highStreetBank.gives(acmeCorp, 1.M, USD)
}
}
}
@ -24,29 +24,29 @@ val cds_contract = arrange {
// fx swap
// both parties have the right to trigger the exchange of cash flows
val an_fx_swap = arrange {
(roadRunner or wileECoyote).may {
(acmeCorp or highStreetBank).may {
"execute".givenThat(after("2017-09-01")) {
wileECoyote.gives(roadRunner, 1200.K, USD)
roadRunner.gives(wileECoyote, 1.M, EUR)
highStreetBank.gives(acmeCorp, 1200.K, USD)
acmeCorp.gives(highStreetBank, 1.M, EUR)
}
}
}
val american_fx_option = arrange {
roadRunner.may {
acmeCorp.may {
"exercise".givenThat(before("2017-09-01")) {
wileECoyote.gives(roadRunner, 1200.K, USD)
roadRunner.gives(wileECoyote, 1.M, EUR)
highStreetBank.gives(acmeCorp, 1200.K, USD)
acmeCorp.gives(highStreetBank, 1.M, EUR)
}
}
}
val european_fx_option = arrange {
roadRunner.may {
acmeCorp.may {
"exercise".givenThat(before("2017-09-01")) {
fx_swap("2017-09-01", 1.M, 1.2.bd, EUR, USD, roadRunner, wileECoyote)
fx_swap("2017-09-01", 1.M, 1.2.bd, EUR, USD, acmeCorp, highStreetBank)
}
} or (roadRunner or wileECoyote).may {
} or (acmeCorp or highStreetBank).may {
"expire".anytime {
zero
}
@ -54,18 +54,18 @@ val european_fx_option = arrange {
}
val zero_coupon_bond_1 = arrange {
roadRunner.may {
acmeCorp.may {
"execute".givenThat(after("2017-09-01")) {
wileECoyote.gives(roadRunner, 1.M, USD)
highStreetBank.gives(acmeCorp, 1.M, USD)
}
}
}
// maybe in the presence of negative interest rates you would want other side of contract to be able to take initiative as well
val zero_coupon_bond_2 = arrange {
(roadRunner or wileECoyote).may {
(acmeCorp or highStreetBank).may {
"execute".givenThat(after("2017-09-01")) {
wileECoyote.gives(roadRunner, 1.M, USD)
highStreetBank.gives(acmeCorp, 1.M, USD)
}
}
}
@ -80,23 +80,23 @@ val zero_coupon_bond_2 = arrange {
// Assume observable is using FX fixing
//
val no_touch = arrange {
(roadRunner or wileECoyote).may {
(acmeCorp or highStreetBank).may {
"execute".givenThat(after("2017-09-01")) {
wileECoyote.gives(roadRunner, 1.M, USD)
highStreetBank.gives(acmeCorp, 1.M, USD)
}
} or wileECoyote.may {
} or highStreetBank.may {
"knock out".givenThat(EUR/USD gt 1.3)
}
}
val one_touch = arrange {
wileECoyote.may {
highStreetBank.may {
"expire".givenThat(after("2017-09-01")) {
zero
}
} or roadRunner.may {
} or acmeCorp.may {
"knock in".givenThat(EUR / USD gt 1.3) {
wileECoyote.gives(roadRunner, 1.M, USD)
highStreetBank.gives(acmeCorp, 1.M, USD)
}
}
}