American Option

An option is a financial contract that allows an investor to exercise a choice between two subcontracts. We implement in BitML the American option, where the investor can exercise the choice anytime before a given deadline.

We start by defining the parametric contract (AmericanOption Part t Contract1 Contract2 Default). The parameter of the contract are: a participant Part who can choose, before deadline t, to authorise the either Contract1 or Contract2. If time t passes, the contract can proceed as the parameter contract Default.

We exploit the American Option to implement an investment contract between an investor A and an issuer I. After stipulating the contract, A can choose whether to invest, or to retract. If she authorise the contract Invest, she immediately pays her 1 BTC deposit to I, expecting to get back 1.1 BTC from I after block 160000000. If she authorise the contract Retract, she does not invest, but she only gets back 0.95 BTC, paying 0.05 BTC to I as a fee. Otherwise, if she doesn’t chose before the deadline t , I can invoke the contract Default, which returns A’s deposit to her, minus a 0.1 BTC penalty, which goes to I.

Finally, we verify that the contract is liquid.

#lang bitml

(participant "A" "0339bd7fade9167e09681d68c5fc80b72166fe55bbb84211fd12bde1d57247fbe1")
(participant "I" "034a7192e922118173906555a39f28fa1e0b65657fc7f403094da4f85701a5f809")

(debug-mode)

(define (txA) ".")
(define (txFee) "..")
(define (txI) "...")


;; Part can choose at time t whether to execute Contract1 or Contract2
;; after deadline t, the contract Default can be executed
;--------------------------------------------------------------
(define (AmericanOption Part t Contract1 Contract2 Default)
  (choice
   (auth Part (tau (ref (Contract1))))
   (auth Part (tau (ref (Contract2))))
   (after t (tau (ref (Default))))))

; Sub-contracts used to instantiate the American Option
;--------------------------------------------------------------

;; A chooses not to proceed with the investment,
;; and gets back her deposit minus a cancellation fee.
;; I gets gets the fee from A.
(define (Retract)
  (split
   (0.95 -> (withdraw "A"))
   (0.05 -> (withdraw "I"))))

;; A chooses to proceed with the investment.
;; The funds are locked up to a certain time,
;; then she can withdraw the whole balance
(define (Invest)
  (split
   (1 -> (withdraw "I"))
   (0 -> (after 160000000 (put (x) (withdraw "A"))))))

;; A failed to choose whether to invest or retract.
;; She gets back her deposit minus a penalty.
;; I gets gets the penalty from A.
(define (Default)
  (split
   (0.9 -> (withdraw "A"))
   (0.1 -> (withdraw "I"))))
;--------------------------------------------------------------

(contract
 (pre (deposit "A" 1 (ref (txA)))
      (vol-deposit "I" x 1.1 (ref (txI)))
      (fee "A" 0.01 (ref (txFee))))

 (ref (AmericanOption "A" 1550000 Retract Invest Default))

 (check-liquid))

This is the result of the compilation.

const pubkeyA13 = pubkey:0339bd7fade9167e09681d68c5fc80b72166fe55bbb84211fd12bde1d57247fbe1
const pubkeyI2 = pubkey:034a7192e922118173906555a39f28fa1e0b65657fc7f403094da4f85701a5f809
const pubkeyA11 = pubkey:0339bd7fade9167e09681d68c5fc80b72166fe55bbb84211fd12bde1d57247fbe1
const pubkeyA1 = pubkey:0339bd7fade9167e09681d68c5fc80b72166fe55bbb84211fd12bde1d57247fbe1
const pubkeyA9 = pubkey:0339bd7fade9167e09681d68c5fc80b72166fe55bbb84211fd12bde1d57247fbe1
const pubkeyA7 = pubkey:0339bd7fade9167e09681d68c5fc80b72166fe55bbb84211fd12bde1d57247fbe1
const pubkeyI10 = pubkey:034a7192e922118173906555a39f28fa1e0b65657fc7f403094da4f85701a5f809
const pubkeyI6 = pubkey:034a7192e922118173906555a39f28fa1e0b65657fc7f403094da4f85701a5f809
const pubkeyI8 = pubkey:034a7192e922118173906555a39f28fa1e0b65657fc7f403094da4f85701a5f809
const pubkeyA3 = pubkey:0339bd7fade9167e09681d68c5fc80b72166fe55bbb84211fd12bde1d57247fbe1
const pubkeyA5 = pubkey:0339bd7fade9167e09681d68c5fc80b72166fe55bbb84211fd12bde1d57247fbe1
const pubkeyA15 = pubkey:0339bd7fade9167e09681d68c5fc80b72166fe55bbb84211fd12bde1d57247fbe1
const pubkeyI12 = pubkey:034a7192e922118173906555a39f28fa1e0b65657fc7f403094da4f85701a5f809
const pubkeyI4 = pubkey:034a7192e922118173906555a39f28fa1e0b65657fc7f403094da4f85701a5f809
const pubkeyI14 = pubkey:034a7192e922118173906555a39f28fa1e0b65657fc7f403094da4f85701a5f809
const pubkeyI16 = pubkey:034a7192e922118173906555a39f28fa1e0b65657fc7f403094da4f85701a5f809

const pubkeyA = pubkey:0339bd7fade9167e09681d68c5fc80b72166fe55bbb84211fd12bde1d57247fbe1
const pubkeyI = pubkey:034a7192e922118173906555a39f28fa1e0b65657fc7f403094da4f85701a5f809

const sigA0 : signature = _ //add signature for output .
const sigAFee : signature = _ //add signature for output ..

transaction Tinit {
 input = [ .:sigA0; ..:sigAFee ]
 output = 1.0097 BTC : fun(sA, sI) . (( versig(pubkeyA1, pubkeyI2; sA, sI) ||
 versig(pubkeyA3, pubkeyI4; sA, sI) ||
 versig(pubkeyA5, pubkeyI6; sA, sI) ))
}

const sigAT1 : signature = _
const sigIT1 : signature = _


transaction T1 {
 input = [ Tinit@0: sigAT1 sigIT1 ]
 output = 1.0094 BTC : fun(sA, sI) . versig(pubkeyA7, pubkeyI8; sA, sI)
}

const sigAT2 : signature = _
const sigIT2 : signature = _


transaction T2 {
 input = [ T1@0: sigAT2 sigIT2 ]
 output = [ 0.95455 BTC : fun(sA, sI) . ((versig(pubkeyA9, pubkeyI10; sA, sI)));
        0.05455 BTC : fun(sA, sI) . ((versig(pubkeyA11, pubkeyI12; sA, sI))) ]
}

const sigAT3 : signature = _
const sigIT3 : signature = _

transaction T3 {
 input = [ T2@0:  sigAT3 sigIT3 ]
 output = 0.95425 BTC : fun(x) . versig(pubkeyA; x)

}

const sigAT4 : signature = _
const sigIT4 : signature = _

transaction T4 {
 input = [ T2@1:  sigAT4 sigIT4 ]
 output = 0.05425 BTC : fun(x) . versig(pubkeyI; x)

}

const sigAT5 : signature = _
const sigIT5 : signature = _


transaction T5 {
 input = [ Tinit@0: sigAT5 sigIT5 ]
 output = 1.0094 BTC : fun(sA, sI) . versig(pubkeyA13, pubkeyI14; sA, sI)
}

const sigAT6 : signature = _
const sigIT6 : signature = _


transaction T6 {
 input = [ T5@0: sigAT6 sigIT6 ]
 output = [ 1.00455 BTC : fun(sA, sI) . ((versig(pubkeyA11, pubkeyI12; sA, sI)));
        0.00455 BTC : fun(sA, sI) . ((versig(pubkeyA15, pubkeyI16; sA, sI))) ]
}

const sigAT7 : signature = _
const sigIT7 : signature = _

transaction T7 {
 input = [ T6@0:  sigAT7 sigIT7 ]
 output = 1.00425 BTC : fun(x) . versig(pubkeyI; x)

}

const sigx : signature = _ //add signature for output ...
const sigAT8 : signature = _
const sigIT8 : signature = _


transaction T8 {
 input = [ T6@1: sigAT8 sigIT8 ]
 output = 1.10425 BTC : fun(sA, sI) . versig(pubkeyA9, pubkeyI10; sA, sI)
}

const sigAT9 : signature = _
const sigIT9 : signature = _

transaction T9 {
 input = [ T8@0:  sigAT9 sigIT9 ]
 output = 1.10395 BTC : fun(x) . versig(pubkeyA; x)

}

const sigAT10 : signature = _
const sigIT10 : signature = _


transaction T10 {
 input = [ Tinit@0: sigAT10 sigIT10 ]
 output = 1.0094 BTC : fun(sA, sI) . versig(pubkeyA11, pubkeyI12; sA, sI)
}

const sigAT11 : signature = _
const sigIT11 : signature = _

transaction T11 {
 input = [ T10@0:  sigAT11 sigIT11 ]
 output = 1.0091 BTC : fun(x) . versig(pubkeyI; x)

}