Canonical account example?

Is there a canonical example of how to model an account, with transfers between account?

In modelling OTC for me it was always a blocker that the OTC template type would be specific to the underlying asset structure. Ie. that there was no way to abstract over contracts. Not (ever?) getting that - I have taken a different approach, so now the OTC life cycling may result in “effects” defined as an agreement to immediately transfer amount of given asset from party A to party B under a given “service” identified by issuer and a text ID.
Separate agreements are then made to exercise that such “effects” into the moving of assets according to predefined settlement instructions.

Curious to experiment with creating such agreement structure to canonical account example, if such exists.


Hi Sofus,

yes, we indeed have a canonical model for asset and accounts, transfers and DvPs between those, as well as a generic lifecycling mechanism, in the form of the DAML Finance Library.

Assets and accounts are simply referred to by a textual, versioned identifier, that also specifies the backing signatories. We define an AssetDeposit as the combination of an asset deposited into an account.

Then, we have a rule contract for transfers, the AssetSettlementRule. And based on that we define a generic DvP structure that leverages this rule in its own settlement rule.

In a similar vein, we’ve implemented generic asset lifecycling, which follows a very similar approach as you describe. Essentially, you define a lifecycle rule that implements the event logic and outputs a generic LifecycleEffects contract, which describes how a position (ie. AssetDeposit) evolves through the event. These effects can then be applied to deposits generically using the AssetLifecycleRule.

An example for this mechanism is implemented in the EquityStockCashDividendRule. It produces effects that reflect a cash dividend paid on a stock position.

Note that this lifecycling mechanism only describes the effects for the position holder within the context of a given account provider. For example a custodian bank would use it to effectuate a cash dividend for all their client positions in their own books (ie. for all AssetDeposits that they are the provider on). On the other side the bank would lifecycle its own stock position at the CSD in a similar manner such that they’re net flat over the event. Ideally, the two sides would happen atomically such that there’s no risk of failure and residual exposure.
What this model doesn’t cover is the issuer side of such an event, ie. the (lump sum) payment of the dividend by the issuer to the CSD. I think it could still fit into this model but we haven’t explored it yet.

I hope this gives you some context on the library and shows possible ways to integrate with it. Let me know if there’s any aspect you need more information on. I’m keen to understand if your OTC design can fit with our model.


Thanks Georg. Although by the looks of it, it hasn’t changed a lot in the last year or so, I will still need to spend so time with it to see how the pieces will fit together.

My primary concern is how AssetDeposit represents an actual asset (IOU smell - amount > 0.0 and not using contract keys). So I am not sure how the involved parties can enter an OTC where they can be made obliges to pay, Whereas with a traditional account structure and an involved issuer - the issuer can guaranteed that any payments will be executed (taking the credit risk).

It was a little painful to hide properly hide disclosure of the account holdings from the other participant in the contract - which is why I was asking for a canonical account example, so hear if you had a better solution.

What I did was to have Transfer represent the obligation to pay, and have a split choice to make the issuer the middle man in order to hide disclosure of transaction details:

template Transfer
    service : Service
    payer : Party
    payee : Party
    asset : Text
    amount : Decimal
    signatory payer, payee
    observer service.issuer

    ensure payer /= payee

    choice Split : (ContractId Transfer, ContractId Transfer)
      controller service.issuer
        l <- create this with payer = service.issuer
        r <- create this with payee = service.issuer
        return (l, r)

Can you elaborate on your concerns here?

The way I think about OTC trades in the context of this library is the following: let’s take a fixed-vs-float IRS with Bank A being fixed receiver and Bank B being float receiver. Both banks would have accounts with each other containing a position on the respective side of the trade. On each payment date the banks can then lifecycle their positions to receive payments in their respective accounts at the other bank. So Bank A would have - through the lifecycle rule contract - the right to transform the [IRS position] into [IRS postion + fixed payment] in their account at Bank B. Similar for Bank B to receive their float payment in their account at Bank A. So the respective payments are simply effected by crediting the mutual accounts. If a bank then wishes to move that money eg. to a central bank account, that would be a separate transaction. Does that make sense to you?

What do you mean by "traditional account structure` here?

Who do you consider the issuer in an OTC transaction? Do you mean the cash issuer eg the central bank? Or simply a CCP that steps in the middle? The model I described above doesn’t use (or require) any intermediary, and yes, OTCs settled via “third-party” (ie CB) money would require a different setup.

Not concern. Just an observation that it’s an IOU and not an account (that can go negative), and hence different from the traditional account structure.

Going negative is (likely to be) needed for guaranteeing a payment. In your example the execution of the fixed payment from the lifecycle event. But maybe there’s something I am misunderstanding there?

My example looks at a OTC between two parties, both having their accounts with the same bank (issuer). The special (but typical) case of that would be where one of the two parties is in fact the issuer - but I believe the generalisation would be useful going forward from there.

Cash issuer IRL is typically a commercial bank and not a central bank.

Hey Sofus - wanted to echo @georg 's points about the design choice in the Finance Library which uses data records for Asset and Account (instead of templates) so it can link any asset with any account. This is done through the concept of an Id which is basically a way to bundle a text identifier with a version and a set of backing parties.

Therefore the balance of an account is just the sum of its AssetDeposits. And since the AssetDeposit is the combination of an Asset and Account (and a set of observers), the account can hold multiple deposits of different assets.

Given that the asset deposits and their quantity is decoupled from the account itself, you can disclose them to the receiving party independently which facilitates in hiding the total balance of an account when you are looking to transfer something.

I do agree however that in your use case there is a limitation of ensure asset.quantity > 0.0 in the AssetDeposit. What I could recommend is perhaps importing the DA.Finance.Types and writing your own version of an AssetDeposit (perhaps call it AssetBalance) that can indeed go negative. The total balance of your account will continue to be the sum of AssetBalances and you would also get the feature of hiding the account holdings out of the box. The drawback would be that you would also have to pretty much copy-paste the AssetLifecycleRule and AssetSettlementRule module to work with your new AssetBalance contract.

For implementing transfer you can then use the AssetSettlementRule. A pattern that has worked for me is to have a contract which references an AssetDeposit’s contract id as well as an Id (the receiver’s account id). Then I have a choice which is taken by the account signatory (the same for both sender and receiver) which creates a sender and a receiver AssetSettlementRule , then exercises AssetSettlement_Transfer on the sender with the receiver and finally archives the AssetSettlementRules. This will result in a recycling of the AssetDeposit contract where the Account field has changed to the new owner, all under a single choice.

1 Like

Hey Dimitri!

Not sure I am buying this as an argument (if that was the intention) for not having a contract key structure to represent account holdings. But perhaps there are other occasions where you’d want to proof ownership of subset of your account holding that justifies this?

I will definitely look into what you’re suggesting with AssetBalance - although my gut feeling right now it that it would be more complex than need be, compare to a contract key based account solution (that still doesn’t disclose balance to counter parties).

I am a little surprised to learn that there isn’t a canonical way to represent accounts that uses contract keys.

Surely you must have considered revising FinLib to represent accounts holdings with contract keys. What was the arguments against doing it?

I personally dislike using singular Account contracts because they make maintaining privacy a bit more cumbersome. Say we want to do an atomic swap. Whoever settles that swap needs to know everything that goes into the settlement transaction. If we don’t want to tell each other our account totals, that means the settlement can’t directly access the accounts. The way to work around that is to have some kind of Allocation contract, but at that point you now have a mix between Assets (/IOUs) and accounts which is less nice than a pure Asset/Iou model in my opinion.

I don’t think the privacy issue was that troublesome to fix - and it’s a trade-off the IOU structure puts additional burden on the client wrt. merging and splitting. I think the number of transactions are the same, perhaps even be a little higher for the bitcoin IOU scheme (if you include the split before the transfer and the merge after).

Why wouldn’t you think the two approaches would go nicely together?
The account is the most intuitive home for the asset - and for certain applications you would break a chunk out in an IOU (AssetDeposit).

Indeed both work. I was just saying that I have stylistic preference for one over the other. With the Account scheme you enforce very orderly merging and splitting, which has some advantages, but it also forces everything through the Account contract which could become a contention bottleneck.

As you say, it’s a tradeoff.

1 Like

Okay. I think we’re on the same page, Bernhard.

An additional argument for the AssetDeposit structure is that if you can report account holdings then it would trivial to extend to a sub account structure as these would be treated the same way.

I still think that for cash payments in context of OTC an Account scheme will be more suitable as AssetDeposit allowing negative amounts is a little odd.

I will try out both approaches.