(* NAME_START:test timelock 1531826400UL (11:20am):NAME_END *)
(* module TimeLock *)
open Zen.Types
open Zen.Base
open Zen.Cost
open Zen.Asset
open Zen.Data
open FStar.UInt64
module D = Zen.Dictionary
module W = Zen.Wallet
module CR = Zen.ContractResult
module RT = Zen.ResultT
module Tx = Zen.TxSkeleton
module U64 = FStar.UInt64
// Edit this to the time at which the tokens can be withdrawn - in UNIX time //
// Format: 0000000000UL //
let maturityTimestamp = 1531826400UL
let getReturnAddress (messageBody: option data): option lock `cost` 77 = //7
messageBody >!= tryDict
>?= D.tryFind "returnAddress"
>?= tryLock
let collateralize (txSkel: txSkeleton) (contractId: contractId)
(messageBody: option data): CR.t `cost` 428 = //28
let! contractToken = Zen.Asset.getDefault contractId in //64
let! amount = Tx.getAvailableTokens zenAsset txSkel in //64
let! returnAddress = getReturnAddress messageBody in //77
match returnAddress with
| Some returnAddress ->
Tx.lockToContract zenAsset amount contractId txSkel //64
>>= Tx.mint amount contractToken //64
>>= Tx.lockToAddress contractToken amount returnAddress //64
>>= CR.ofTxSkel //3
| None -> RT.incFailw 195 "Message body must contain a return address"
let redeem (txSkel: txSkeleton) ({timestamp=timestamp}: context)
(contractId: contractId) (messageBody: option data) (wallet: wallet)
: CR.t `cost` (Zen.Wallet.size wallet * 128 + 567) = //39
let! contractToken = Zen.Asset.getDefault contractId in //64
let! amount = Tx.getAvailableTokens contractToken txSkel in //64
let! returnAddress = getReturnAddress messageBody in //77
match returnAddress with
| Some returnAddress ->
if timestamp >=^ maturityTimestamp then begin
let! txSkel = Tx.destroy amount contractToken txSkel //64
>>= Tx.lockToAddress zenAsset amount returnAddress //64
>>= Tx.fromWallet zenAsset amount contractId wallet in //w*128+192
match txSkel with
| Some txSkel -> CR.ofTxSkel txSkel //3
| None -> RT.incFailw 3 "Something went wrong! could not get txSkel from wallet"
end
else RT.autoFailw "Timestamp is less than maturity timestamp"
| None -> RT.autoFailw "Message body must contain a return address"
let main (txSkel: txSkeleton) (context: context) (contractId: contractId)
(command: string) (_: sender) (messageBody: option data)
(wallet: wallet) (_: option data)
: CR.t `cost` (Zen.Wallet.size wallet * 128 + 575) = //8
match command with
| "Redeem" -> redeem txSkel context contractId messageBody wallet
| "Collateralize" -> collateralize txSkel contractId messageBody
|> autoInc
| _ -> RT.autoFailw "Command not recognised"
let cf _ _ _ _ _ wallet _ : nat `cost` 7 =
W.size wallet * 128 + 575
|> ret