da-syndication-finance-temp.../daml/Scripts/Lifecycling.daml
Rune K. Svendsen 1e6d4aa792 Initial commit
2023-05-08 16:09:16 -04:00

159 lines
5.6 KiB
Plaintext

module Scripts.Lifecycling where
import DA.Map qualified as M (empty)
import DA.Set qualified as S (empty, fromList, singleton)
import Daml.Script
-- INTERFACE DEPENDENCIES --
import Daml.Finance.Interface.Instrument.Base.Instrument qualified as Instrument (I)
import Daml.Finance.Interface.Lifecycle.Event qualified as Event (I)
import Daml.Finance.Interface.Lifecycle.Rule.Claim qualified as Claim (ClaimEffect(..), I)
import Daml.Finance.Interface.Lifecycle.Rule.Lifecycle qualified as Lifecycle (Evolve(..), I)
import Daml.Finance.Interface.Settlement.Batch qualified as Batch (Settle(..))
import Daml.Finance.Interface.Settlement.Instruction qualified as Instruction (Allocate(..), Approve(..))
import Daml.Finance.Interface.Settlement.Types (Allocation(..), Approval(..))
import Daml.Finance.Interface.Types.Common.Types (Id(..))
import Daml.Finance.Interface.Util.Common (qty)
-- IMPLEMENTATION DEPENDENCIES --
import Daml.Finance.Instrument.Token.Instrument (Instrument(..))
import Daml.Finance.Lifecycle.Event.Distribution qualified as Distribution (Event(..))
import Daml.Finance.Lifecycle.Rule.Claim qualified as Claim (Rule(..))
import Daml.Finance.Lifecycle.Rule.Distribution qualified as Distribution (Rule(..))
import Scripts.Settlement (SettlementState(..), runSettlement)
-- | Test script that
-- 1. executes the `runSettlement` script
-- 2. creates a distribution lifecycle rule
-- 3. creates a distribution lifecycle event
-- 4. lifecycles the distribution event
-- 5. processes the lifecycle effect
-- 6. settles the distribution
runLifecycling : Script()
runLifecycling = do
-- Execute the `runSettlement` script. Bob now holds 10 tokens in his account.
SettlementState{alice
, bank
, bob
, public
, aliceAccount
, bobAccount
, usdInstrument
, tokenInstrument
, routeProviderCid
, settlementFactoryCid
, aliceHoldingCid
, bobHoldingCid} <- runSettlement
-- The bank creates a new version of the token instrument (the "ex-distribution" version). This is
-- the version Bob will hold after claiming the effect further down below.
-- NEW_VERSION_BEGIN
let newTokenInstrument = tokenInstrument with version = "1"
now <- getTime
tokenInstrumentCid <- toInterfaceContractId @Instrument.I <$> submit bank do
createCmd Instrument with
depository = bank
issuer = bank
id = tokenInstrument.id
version = "1"
description = "Instrument representing units of a generic token"
validAsOf = now
observers = M.empty
-- NEW_VERSION_END
-- Create lifecycle rules
-- LIFECYCLE_RULES_BEGIN
distributionRuleCid <- toInterfaceContractId @Lifecycle.I <$> submit bank do
createCmd Distribution.Rule with
providers = S.singleton bank
lifecycler = bank
observers = S.singleton bob
id = Id "Lifecycle rule for distribution"
description = "Rule contract to lifecycle an instrument following a distribution event"
lifecycleClaimRuleCid <- toInterfaceContractId @Claim.I <$> submitMulti [bank, bob] [] do
createCmd Claim.Rule with
providers = S.fromList [bank, bob]
claimers = S.singleton bob
settlers = S.singleton bob
routeProviderCid
settlementFactoryCid
netInstructions = False
-- LIFECYCLE_RULES_END
-- Create cash distribution event
-- CREATE_EVENT_BEGIN
distributionEventCid <- toInterfaceContractId @Event.I <$> submit bank do
createCmd Distribution.Event with
providers = S.singleton bank
id = Id "DISTRIBUTION"
description = "Profit distribution"
effectiveTime = now
targetInstrument = tokenInstrument
newInstrument = newTokenInstrument
perUnitDistribution = [qty 0.02 usdInstrument]
observers = S.empty
-- CREATE_EVENT_END
-- Lifecycle distribution event
-- LIFECYCLE_EVENT_BEGIN
(_, [effectCid]) <- submit bank do
exerciseCmd distributionRuleCid Lifecycle.Evolve with
eventCid = distributionEventCid
observableCids = []
instrument = tokenInstrument
-- LIFECYCLE_EVENT_END
-- Claim effect
-- CLAIM_EVENT_BEGIN
result <- submitMulti [bob] [public] do
exerciseCmd lifecycleClaimRuleCid Claim.ClaimEffect with
claimer = bob
holdingCids = [bobHoldingCid]
effectCid
batchId = Id "DistributionSettlement"
let [bobInstructionCid, bankInstructionCid, couponInstructionCid] = result.instructionCids
-- CLAIM_EVENT_END
-- EFFECT_SETTLEMENT_BEGIN
-- Allocate instruction
(bobInstructionCid, _) <- submit bob do
exerciseCmd bobInstructionCid Instruction.Allocate with
actors = S.singleton bob
allocation = Pledge bobHoldingCid
(bankInstructionCid, _) <- submit bank do
exerciseCmd bankInstructionCid Instruction.Allocate with
actors = S.singleton bank
allocation = CreditReceiver
(couponInstructionCid, _) <- submit bank do
exerciseCmd couponInstructionCid Instruction.Allocate with
actors = S.singleton bank
allocation = CreditReceiver
-- Approve instruction
bobInstructionCid <- submit bank do
exerciseCmd bobInstructionCid Instruction.Approve with
actors = S.singleton bank
approval = DebitSender
bankInstructionCid <- submit bob do
exerciseCmd bankInstructionCid Instruction.Approve with
actors = S.singleton bob
approval = TakeDelivery bobAccount
couponInstructionCid <- submit bob do
exerciseCmd couponInstructionCid Instruction.Approve with
actors = S.singleton bob
approval = TakeDelivery bobAccount
-- Settle batch
submitMulti [bob] [public] do
exerciseCmd result.batchCid Batch.Settle with actors = S.singleton bob
-- EFFECT_SETTLEMENT_END
pure ()