Contract - TL0
Address:
ID:

SUMMARY
FULL NAMETime lock of 1531826400UL
STATUSInactive
TRANSACTIONS0
LAST ACTIVATION BLOCK6,279
BALANCES
ASSETAMOUNT
(* 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