Michelson (docs): fixed forward example.

This commit is contained in:
Benjamin Canou 2017-01-17 00:23:50 +01:00 committed by Benjamin Canou
parent 52ec257e1d
commit d72746c990

View File

@ -1524,8 +1524,7 @@ The complete source `scrutable_reservoir.tz` is:
We want to write a forward contract on dried peas. The contract takes We want to write a forward contract on dried peas. The contract takes
as global data the tons of peas `Q`, the expected delivery date `T`, the as global data the tons of peas `Q`, the expected delivery date `T`, the
contract agreement date `Z`, a strike `K`, a collateral `C` per ton of dried contract agreement date `Z`, a strike `K`, a collateral `C` per ton of dried
peas, and the accounts of the buyer `B`, the seller `S` and the warehouse peas, and the accounts of the buyer `B`, the seller `S` and the warehouse `W`.
`W`.
These parameters as grouped in the global storage as follows: These parameters as grouped in the global storage as follows:
@ -1614,131 +1613,148 @@ At the beginning of the transaction:
The contract returns a unit value, and we assume that it is created The contract returns a unit value, and we assume that it is created
with the minimum amount, set to `(Tez "1.00")`. with the minimum amount, set to `(Tez "1.00")`.
The code of the contract is thus as follows. The complete source `forward.tz` is:
DUP ; CDDADDR ; # Z parameter (or string uint32) ;
PUSH uint64 86400 ; SWAP ; ADD ; # one day in second return unit ;
NOW ; COMPARE ; LT ; storage
IF { # Before Z + 24 pair
DUP ; CADR ; # we must receive (Left "buyer") or (Left "seller") pair uint32 (pair tez tez) # counter from_buyer from_seller
IF_LEFT pair
{ DUP ; PUSH string "buyer" ; COMPARE ; EQ ; pair uint32 (pair timestamp timestamp) # Q T Z
IF { DROP ; pair
DUP ; CDADAR ; # amount already versed by the buyer pair tez tez # K C
DIP { DUP ; CAAR } ; ADD ; # transaction pair
# then we rebuild the globals pair (contract unit unit) (contract unit unit) # B S
DIP { DUP ; CDADDR } ; PAIR ; # seller amount (contract unit unit); # W
PUSH uint32 0 ; PAIR ; # delivery counter at 0 code
DIP { CDDR } ; PAIR ; # parameters { DUP ; CDDADDR ; # Z
# and return Unit PUSH uint64 86400 ; SWAP ; ADD ; # one day in second
NOW ; COMPARE ; LT ;
IF { # Before Z + 24
DUP ; CADR ; # we must receive (Left "buyer") or (Left "seller")
IF_LEFT
{ DUP ; PUSH string "buyer" ; COMPARE ; EQ ;
IF { DROP ;
DUP ; CDADAR ; # amount already versed by the buyer
DIP { DUP ; CAAR } ; ADD ; # transaction
# then we rebuild the globals
DIP { DUP ; CDADDR } ; PAIR ; # seller amount
PUSH uint32 0 ; PAIR ; # delivery counter at 0
DIP { CDDR } ; PAIR ; # parameters
# and return Unit
UNIT ; PAIR }
{ PUSH string "seller" ; COMPARE ; EQ ;
IF { DUP ; CDADDR ; # amount already versed by the seller
DIP { DUP ; CAAR } ; ADD ; # transaction
# then we rebuild the globals
DIP { DUP ; CDADAR } ; SWAP ; PAIR ; # buyer amount
PUSH uint32 0 ; PAIR ; # delivery counter at 0
DIP { CDDR } ; PAIR ; # parameters
# and return Unit
UNIT ; PAIR }
{ FAIL } } } # (Left _)
{ FAIL } } # (Right _)
{ # After Z + 24
# test if the required amount is reached
DUP ; CDDAAR ; # Q
DIP { DUP ; CDDDADR } ; MUL ; # C
PUSH uint8 2 ; MUL ;
PUSH tez "1.00" ; ADD ;
BALANCE ; COMPARE ; LT ; # balance < 2 * (Q * C) + 1
IF { # refund the parties
CDR ; DUP ; CADAR ; # amount versed by the buyer
DIP { DUP ; CDDDAAR } # B
UNIT ; TRANSFER_TOKENS ; DROP
DUP ; CADDR ; # amount versed by the seller
DIP { DUP ; CDDDADR } # S
UNIT ; TRANSFER_TOKENS ; DROP
BALANCE ; # bonus to the warehouse to destroy the account
DIP { DUP ; CDDDDR } # W
UNIT ; TRANSFER_TOKENS ; DROP
# return unit, don't change the global
# since the contract will be destroyed
UNIT ; PAIR } UNIT ; PAIR }
{ PUSH string "seller" ; COMPARE ; EQ ; { # otherwise continue
IF { DUP ; CDADDR ; # amount already versed by the seller DUP ; CDDADAR # T
DIP { DUP ; CAAR } ; ADD ; # transaction NOW ; COMPARE ; LT
# then we rebuild the globals IF { FAIL } # Between Z + 24 and T
DIP { DUP ; CDADAR } ; SWAP ; PAIR ; # buyer amount { # after T
PUSH uint32 0 ; PAIR ; # delivery counter at 0 DUP ; CDDADAR # T
DIP { CDDR } ; PAIR ; # parameters PUSH uint64 86400 ; ADD # one day in second
# and return Unit NOW ; COMPARE ; LT
UNIT ; PAIR } IF { # Between T and T + 24
{ FAIL ; CDR ; UNIT ; PAIR }}} # (Left _) # we only accept transactions from the buyer
{ FAIL ; DROP ; CDR ; UNIT ; PAIR }} # (Right _) DUP ; CADR ; # we must receive (Left "buyer")
{ # After Z + 24 IF_LEFT
# test if the required amount is reached { PUSH string "buyer" ; COMPARE ; EQ ;
DUP ; CDDAAR ; # Q IF { DUP ; CDADAR ; # amount already versed by the buyer
DIP { DUP ; CDDDADR } ; MUL ; # C DIP { DUP ; CAAR } ; ADD ; # transaction
PUSH uint8 2 ; MUL ; # The amount must not exceed Q * K
PUSH tez "1.00" ; ADD ; DUP ;
BALANCE ; COMPARE ; LT ; # balance < 2 * (Q * C) + 1 DIIP { DUP ; CDDAAR ; # Q
IF { # refund the parties DIP { DUP ; CDDDAAR } ; MUL ; } ; # K
DUP ; CDADAR ; # amount versed by the buyer DIP { COMPARE ; GT ; # new amount > Q * K
DIP { DUP ; CDDDDAAR } # B IF { FAIL } { } } ; # abort or continue
UNIT ; TRANSFER_TOKENS ; DROP # then we rebuild the globals
DUP ; CDADDR ; # amount versed by the seller DIP { DUP ; CDADDR } ; PAIR ; # seller amount
DIP { DUP ; CDDDDADR } # S PUSH uint32 0 ; PAIR ; # delivery counter at 0
UNIT ; TRANSFER_TOKENS ; DROP DIP { CDDR } ; PAIR ; # parameters
BALANCE ; # bonus to the warehouse to destroy the account # and return Unit
DIP { DUP ; CDDDDDR } # W UNIT ; PAIR }
UNIT ; TRANSFER_TOKENS ; DROP { FAIL } } # (Left _)
# return unit, don't change the global { FAIL } } # (Right _)
# since the contract will be destroyed { # After T + 24
CDR ; UNIT ; PAIR } # test if the required payment is reached
{ # otherwise continue DUP ; CDDAAR ; # Q
DUP ; CDDADAR # T DIP { DUP ; CDDDAAR } ; MUL ; # K
NOW ; COMPARE ; LT DIP { DUP ; CDADAR } ; # amount already versed by the buyer
IF { FAIL ; CDR ; UNIT ; PAIR } # Between Z + 24 and T COMPARE ; NEQ ;
{ # after T IF { # not reached, pay the seller and destroy the contract
DUP ; CDDADAR # T BALANCE ;
PUSH uint64 86400 ; ADD # one day in second DIP { DUP ; CDDDDADR } # S
NOW ; COMPARE ; LT DIIP { CDR } ;
IF { # Between T and T + 24 UNIT ; TRANSFER_TOKENS ; DROP ;
# we only accept transactions from the buyer
DUP ; CADR ; # we must receive (Left "buyer")
IF_LEFT
{ PUSH string "buyer" ; COMPARE ; EQ ;
IF { DUP ; CDADAR ; # amount already versed by the buyer
DIP { DUP ; CAAR } ; ADD ; # transaction
# The amount must not exceed Q * K
DUP ;
DIIP { DUP ; CDDAAR ; # Q
DIP { DUP ; CDDDAAR } ; MUL ; } ; # K
DIP { COMPARE ; GT ; # new amount > Q * K
IF { FAIL } { } } ; # abort or continue
# then we rebuild the globals
DIP { DUP ; CDADDR } ; PAIR ; # seller amount
PUSH uint32 0 ; PAIR ; # delivery counter at 0
DIP { CDDR } ; PAIR ; # parameters
# and return Unit # and return Unit
UNIT ; PAIR } UNIT ; PAIR }
{ FAIL ; CDR ; UNIT ; PAIR }} # (Left _) { # otherwise continue
{ FAIL ; DROP ; CDR ; UNIT ; PAIR }} # (Right _) DUP ; CDDADAR # T
{ # After T + 24 PUSH uint64 86400 ; ADD ;
# test if the required payment is reached PUSH uint64 86400 ; ADD ; # two days in second
DUP ; CDDAAR ; # Q NOW ; COMPARE ; LT
DIP { DUP ; CDDDAAR } ; MUL ; # K IF { # Between T + 24 and T + 48
DIP { DUP ; CDADAR } ; # amount already versed by the buyer # We accept only delivery notifications, from W
COMPARE ; NEQ ; DUP ; CDDDDDR ; MANAGER ; # W
IF { # not reached, pay the seller and destroy the contract SOURCE unit unit ; MANAGER ;
BALANCE ; COMPARE ; NEQ ;
DIP { DUP ; CDDDDADR } # S IF { FAIL } {} # fail if not the warehouse
UNIT ; TRANSFER_TOKENS ; DROP ; DUP ; CADR ; # we must receive (Right amount)
# and return Unit IF_LEFT
CDR ; UNIT ; PAIR } { FAIL } # (Left _)
{ # otherwise continue { # We increment the counter
DUP ; CDDADAR # T DIP { DUP ; CDAAR } ; ADD ;
PUSH uint64 86400 ; ADD ; # And rebuild the globals in advance
PUSH uint64 86400 ; ADD ; # two days in second DIP { DUP ; CDADR } ; PAIR ;
NOW ; COMPARE ; LT DIP { CDDR } ; PAIR ;
IF { # Between T + 24 and T + 48 UNIT ; PAIR ;
# We accept only delivery notifications, from W # We test if enough have been delivered
DUP ; CDDDDDR ; MANAGER ; # W DUP ; CDAAR ;
SOURCE unit unit ; MANAGER ; DIP { DUP ; CDDAAR } ;
COMPARE ; NEQ ; COMPARE ; LT ; # counter < Q
IF { FAIL } {} # fail if not the warehouse IF { CDR } # wait for more
DUP ; CADR ; # we must receive (Right amount) { # Transfer all the money to the seller
IF_LEFT BALANCE ; # and destroy the contract
{ FAIL ; DROP ; CDR ; UNIT ; PAIR } # (Left _) DIP { DUP ; CDDDDADR } # S
{ # We increment the counter DIIP { CDR } ;
DIP { DUP ; CDAAR } ; ADD ; UNIT ; TRANSFER_TOKENS ; DROP } } ;
# And rebuild the globals in advance UNIT ; PAIR }
DIP { DUP ; CDADR } ; PAIR ; { # after T + 48, transfer everything to the buyer
DIP CDDR ; PAIR ; BALANCE ; # and destroy the contract
UNIT ; PAIR ; DIP { DUP ; CDDDDAAR } # B
# We test if enough have been delivered DIIP { CDR } ;
DUP ; CDAAR ; UNIT ; TRANSFER_TOKENS ; DROP ;
DIP { DUP ; CDDAAR } ; # and return unit
COMPARE ; LT ; # counter < Q UNIT ; PAIR } } } } } } }
IF { } # wait for more
{ # Transfer all the money to the seller
BALANCE ; # and destroy the contract
DIP { DUP ; CDDDDADR } # S
UNIT ; TRANSFER_TOKENS ; DROP }}}
{ # after T + 48, transfer everything to the buyer
BALANCE ; # and destroy the contract
DIP { DUP ; CDDDDAAR } # B
UNIT ; TRANSFER_TOKENS ; DROP ;
# and return unit
CDR ; UNIT ; PAIR }}}}}}
X - Full grammar X - Full grammar
---------------- ----------------