Thank you for registering.
An email containing a verification link has been sent to {{verificationEmail}}.
Please check your inbox.
Huw Grano
Senior DLT Software Engineer
Asset custody is not always simple. The ownership register of an asset can become complex when multiple custodians who hold assets on behalf of clients are involved. A custodian needs to keep a register of who owns what in order to allow investors to become the beneficiary of assets in different jurisdictions or to perform administration and tax reporting duties on behalf of customers.
While each custodian can use a different system for managing their register, a change in asset ownership may affect multiple providers who need to reconcile each other’s systems. For example, when processing a corporate action such as a dividend or stock split, there are usually delays in propagating changes through the account hierarchy because different systems need to be updated. Listed companies must also deal with various custodians to find out who their beneficial owners are, as is often required by regulations.
The account hierarchy Daml project led by our team of engineers at Synfini provides a solution to these complexities. The project aims to provide a common standard and integrated platform for these registries while maintaining a high level of privacy for custodians and beneficiaries alike. It provides a Daml smart contract library as a building block for other applications, especially those that need to plug into the existing financial markets ecosystem available through ASX’s Synfini. Notably, the library is not specific to one asset class – it can apply to any fungible asset.
Let’s take a deep dive into how this smart contract project is designed.
Representing ownership of an asset in Daml is crucial to creating an account hierarchy. To achieve composability of smart contracts, a common standard is needed. Developers can code to common interfaces such as ERC-20 in Solidity. They can accomplish the same goal in Daml by reusing common templates and composing them together with other templates to create new applications.
Our engineering team chose to use FinLib for its flexibility, range of features and ability to represent any type of fungible asset. This Daml library for fungible assets can support asset transfers, delivery versus payment and corporate actions amongst other features. Please note that the FinLib version described here is earlier than the version which comes with the latest Daml SDK release. Updating the library to use the most recent version of the FinLib is on our roadmap.
Ids and accounts
A very useful property of FinLib is that the template structures are generic and allow for different choices of signatories. All contract keys such as account Ids make use of the following data type:
Source: Digital Asset, FinLib
The key takeaway from this is that the signatories are simply a Set of parties. It’s up to the application developer to choose which parties to include in the Set to sign the contracts – these parties can grant entitlement to an asset.
Another important data type is Account, which combines an Id with the account provider and account owner. In an account hierarchy, the provider is typically a custodian and the owner the beneficiary or possibly another custodian.
Source: Digital Asset, FinLib
Asset and AssetDeposit
The AssetDeposit template is used to represent entitlement to a particular asset and is signed by the Set of account.id.signatories.
Source: Digital Asset, FinLib
The Asset stored on the AssetDeposit is a simple data type containing the Id of the asset and the quantity owned. The asset Id is generic and could identify equity in a company, a currency or another financial instrument.
By having flexible signatories, developers can choose to have the custodian, sub-custodian or a trusted third party authorise the creation of the AssetDeposits, depending on the application’s requirements. The choices on the AssetDeposit allow the owner to split or merge the deposit, making it fungible. The template does not define any rules for how the deposit can be transferred to other accounts. But it is open to implementation using choices on other templates.
Unlike public blockchains where assets can typically be sent to anyone at any time, Daml is suitable for use cases requiring programmable rules to provide guardrails on how assets can be transferred, as a form of regulatory control, for example. It works for an account hierarchy, where assets cannot be transferred without a custodian’s authorisation and changes may be needed in other contracts so all custodians can keep a synchronised view.
AssetSettlementRule
FinLib’s AssetSettlementRule is an example of implementation of transfer rules for AssetDeposits. It grants the account owner the right to move any asset in their account, provided the recipient account is willing to accept transfers from them. Since it doesn’t provide ideal restrictions to prevent beneficial owners from freely transferring assets without their custodians’ consent, customised workflows were developed instead for the account hierarchy use case.
An account hierarchy is a tree data structure, with each account linked to its parent through a CustodyAgreement.
Source: Synfini, Account Hierarchy
Since the account.id is the contract key, only one CustodyAgreement can be created per account, meaning each account has one parent at most.
A CustodyAgreement contract allows an account to be entitled to a portion of the assets held in its parent. Multiple parties sign the contract, so a simple initiate and accept pattern is used to create it. Various workflows can look up the parent of an account to ensure the validity of a transaction.
The following diagram illustrates how the AssetDeposit template can be used together with CustodyAgreements. A hypothetical central securities depository (CSD) maintains the ultimate register of ownership, where the custodian (Acme) has an account labelled “Acme@CSD”. Acme then delegates beneficial ownership of AssetDeposits in this account via CustodyAgreements with the investors (Alice and Bob). The CSD may or may not be aware of who these beneficiaries are or how the asset is divided between them, depending on how observers are set in the contracts and how workflows are structured.
In this example, Acme has 100 units of asset ABC, with Alice and Bob as beneficiaries of 70 and 30 units respectively.
Once a model of how accounts and assets relate to each other is ready, there needs to be a safe way to allocate assets to beneficiaries. The following example – where the goal is to deposit $100 into A3 – illustrates how this can be done.
Account A1 delegates beneficial ownership of its assets to its child (A2) and A2 similarly assigns beneficial ownership to its child (A3). If A3 acquires an asset, this change also affects A2 – and A1. To create these AssetDeposits in all three accounts in a single, atomic transaction, developers should design a Daml workflow. The workflow requires participation from multiple parties and provides a synchronized view over the data on a distributed ledger. This will require authorisation from the account.id.signatories of the various accounts.
The AllocationChangeInstruction template was specifically designed for this purpose:
Source: Synfini, Account Hierarchy
The AllocationChangeInstruction is a proposal to modify the way a particular asset is allocated to beneficiaries in the hierarchy. It’s designed to be flexible and can be used for deposits, withdrawals or asset transfers within the hierarchy. This is done by storing lists of zero or more deallocations and allocations on the contract.
Each deallocation identifies an account and a particular AssetDeposit in it to be archived, while the allocations list indicates the accounts where new AssetDeposits should be created. Allocation changes are not executed until the Process choice is called.
The Process choice performs strict checks on the requested allocation changes to ensure the different accounts in the hierarchy are properly synchronised – that is, the balance of the parent account is equal to the sum of balances of all its child accounts. This is done by lookups or fetches on the CustodyAgreement contracts to make sure the allocation changes respect the tree structure.
The following example of an invalid allocation change illustrates this. There is one allocation to account A3 (in green) and no deallocations. With A2 missing an allocation, the Process choice will abort the transaction.
A corrected version would look like this:
The AllocationChangeInstruction only changes how an asset is allocated to beneficiaries. It doesn’t affect the ultimate legal ownership, which is why the diagram has no allocation for the root account A1. The owner of A1 is responsible for ensuring they have an equal quantity of the asset in their account. If changes to the root account are needed, AllocationChangeInstruction can be used along with other templates.
Assets can also be moved between different accounts in the hierarchy using an AllocationChangeInstruction. The following example shows a transfer of $100 from A5 to A3 using two allocations (in green) and two deallocations (in red):
Contention over a single contract is a common problem in application development on distributed ledgers. Multiple parties may try to exercise consuming choices on a single contract ID. But only one command can succeed because the contract will be archived during the execution of a choice.
A way to mitigate this problem is to require the parties to exercise their choices in a specific order. The controllers of the choices can be altered depending on the contract’s state.
For the AllocationChangeInstruction, relevant parties must first consent to the deallocations in order of appearance in the deallocations list. Only after this can parties agree to the allocations – in the same order as the allocations list. If a party attempts to exercise a choice when it’s not their turn, the command will be rejected during interpretation and will not impact the other parties in the workflow.
The design pattern applied here involves:
FinLib provides a very flexible and reusable set of smart contract templates. Our engineering team at Synfini took advantage of this and combined FinLib’s templates with our own to create a definition of account hierarchy. A generic workflow was developed for allocating or transferring assets among asset beneficiaries, giving all stakeholders a consistent and synchronised view.
Had the team used custom templates entirely instead of FinLib, the process would have been more time consuming and complex. The account hierarchy would also be difficult to reuse or compose with other applications.
Here is a high level breakdown of how FinLib and Account Hierarchy features work together:
FinLib acts the base layer for how assets can be represented generically. The Account Hierarchy library applies these features in the context of custodial account hierarchies. At the top layer, are (potential) use-case specific Daml applications which could be built using Account Hierarchy and FinLib.
We’ll explore these other FinLib and Account Hierarchy features in our future blog posts.
ASX acknowledges the Traditional Owners of Country throughout Australia. We pay our respects to Elders past and present.
Artwork by: Lee Anne Hall, My Country, My People