📜 ⬆️ ⬇️

Blockchain without intermediaries: how we sent securities to a distributed registry

All economic activity is historically built on intermediaries. Any, even simple transaction between the two parties is accompanied by the involvement of various intermediaries - banks, stock exchanges, clearing houses, etc. Excluding the middlemen would probably make the interaction more efficient. So why not try to build a new, decentralized infrastructure based on the blockchain, where the participants in the transaction can work directly? In this post, we will talk about how we started the path to such an infrastructure: we developed blockchain transactions in our country and, as a result, carried out repos - borrowing money to be provided with securities.



Short Term Bonds


Our first over-the-counter financial transaction on the blockchain was the issue of a short-term bond of the mobile operator MTS with the participation of the National Settlement Depository (NSD). This is a kind of "central bank" of all depositories. Depositaries are infrastructure intermediaries that keep records of holders of securities and their issuance.

In that transaction, MTS, by calling the function of the smart contract, recorded in the blockchain the will of the sale of securities to Sberbank, and he confirmed in the blockchain agreement with the terms of the transaction. The counter-orders signed by both parties were received by the NSD node that executed them in their accounting systems. In addition, the blockchain displayed the accounts of participants in the transaction in securities and money.
')
In that project, we chose the open source platform Hyperledger Fabric 1.1 , designed to create closed corporate blockchain solutions. Public blockchains are not suitable here, because we need to ensure the privacy of data. We encountered such limitations in the factoring pilot of Sberbank with M.Video, which was implemented on the Ethereum blockchain. In contrast, Hyperledger Fabric allows you to place all participants in a transaction on a dedicated channel, where they can exchange any necessary information and process it with full-featured smart contracts.

The source code for the MTS bond issue project was made publicly available on GitHub. Even without going into the algorithm of work, it can be understood that in the life cycle of the transaction, the blockchain was given the rather modest role of transport of clearing orders. On the other hand, on the basis of these instructions, the balance of accounts was changing - so from the point of view of business logic, this was more interesting than a simple electronic document management service.

The main advantage of the solution was versatility. The “two counterparties and registrar” scheme covers almost any transaction on the over-the-counter market, and with minor changes - most commercial transactions in general.

REPO 1.0


In the new blockchain project we decided to show how to implement a repurchase agreement in the decentralized system to borrow money against securities. Usually, these and other transactions in the over-the-counter market go through intermediaries - depository, clearing houses, brokers.

In this project we made a repo transaction between Sberbank and a foreign partner. It already used Hyperledger Fabric version 1.2. Compared to MTS bonds, we had two differences:


Between contractors organized a chat and document flow within the channel. Data on them was stored in the blockchain. After each change in the distributed registry, channel participants received an email alert.

"REPO 1.0" we have worked with the legal side. With the help of one large law firm, they analyzed the cases of the High Court of London. In addition, the EDS of the bank and its counterparty used different cryptographic algorithms.

How does REPO 1.0 work?


Each transaction participant has its own blockchain node. All nodes are connected to each other in a P2P network. Suppose you need to make a deal. We are deploying a smart contract between the parties to the transaction, which fully describes the financial instrument.



After creating a contract on our part, the trader signs it. The client also reviews and signs the contract. Then the signatures are reviewed and verified. In this case, the transaction was carried out according to English law, data on EDS were entered into the GMRA document. For signing by the client, it is necessary to verify that an authorized person is present in the signature certificate. Finally, the client accepts the contract and agrees to all the conditions. You can attach any number of documents to the signed contract.

After that, the contract receives the status of "in work". The contract “in work” is automatically recalculated when new market prices are uploaded. If there is a security in the contract, the market price is taken, the Loan-To-Value (LTV) is recalculated - the ratio of the loan amount to the value of the collateral in securities. LTV is one of the key terms in a repo transaction, its meaning is stated in the contract. The stock price has increased dramatically - and LTV is becoming less than what is specified in the GMRA (when it comes to English law). Accordingly, the bank returns securities to the client (as one of the options), since, taking into account new prices, it turns out that the bank holds higher collateral.

But if the LTV becomes larger, then the program allows you to print a collateral notice to the client about the need to make additional collateral (shares or money) so that the LTV value returns to the initial one. Previously, collateral notice could only be sent by mail, separate documents were created for this, and during the creation of these documents the LTV could change again. Now we see the same calculations online with a client, we can easily interact.

In addition, the program every day fixes the price of the repurchase of securities, taking into account interest. If a client disagrees with the market price upload, he watches the full log of recalculations - what happened, what happened, what price was loaded, where it came from. And then begins the discussion in the chat.

REPO 2.0


We wanted our repo on the blockchain to initiate the movement of real assets based on its internal logic. But in REPO 1.0, due to organizational difficulties with connecting Western depositories, we have not yet been able to achieve this. So we started the new pilot REPO 2.0. He had two goals:


NSD immediately wanted to join the project. In order to land a deal initiated in the blockchain on the conservative field of federal laws regulating the domestic financial market, we worked with lawyers to a five-page additional agreement to the electronic document contract. It was signed by all participants in the transaction and NSD.

NSD made a clearing house in this transaction. He carried out all orders on the movement of funds and securities. This transaction was concluded under Russian law.

The client has accepted the contract by electronic signature. Then the contract with his signature accepted Sberbank - checked the compliance of all parameters with the required values ​​and the powers of the person who accepted from the client. After that, the contract went to work. NSD loaded market data, the smart contract produced recalculations.

How does REPO 2.0 work?


We used the Fabric Starter solution to deploy the network and the interaction of the client interface with the cheyne code. Instead of the standard grpc interface for the HLF, it provides the REST API, which in our case has significantly reduced the complexity of the integration.



The network went up as follows. Each of the three parties, after the pre-installation on the Docker server, launched the Fabric Starter, which created the containers with the node components. These components included an external peer for interaction with other organizations and a REST API service through which the node interacted with the client application. When Starter was launched, the blockchain-network configuration was also set up and a private channel was created, in which the chein code with endorsement-policy was installed. In our case, each transaction must be signed by all three participants.

Docker Swarm was used to organize the communication of the servers of the participants during the testing phase, however, they switched to DNS for security reasons. The platform itself is responsible for transporting messages, data is transmitted via the Internet with TLS encryption.

The technical side of the issue


The process of developing a distributed application in HLF begins quite traditionally - with data structures and a cheyne code (in fact, a set of stored procedures), the call of which leads to the preservation, modification or reading of these structures from the legger. The platform allows the use of various programming languages ​​for the development of chain codes and DBMS for local storage. We prefer Go and CouchDB respectively.

The central entity for repos in our data model is the contract itself and its subsidiary obligations. They were created for each of the two pilots, as well as for margin calls. This architecture was a step forward compared with the MTS bond model, which was based on the entity “Instruction”. Independent objects were also created for securities, which, thus, were partially tokenized. But we decided to postpone the development of the experiment with account management and virtual tokenization of money until one of the following versions of the solution.

The main functions of our solution:


On the technical side, the revaluation procedure is most interesting here. Let us examine it in more detail.

According to the business process, the procedure should be launched once a day, after Oracle (in the REPO 2.0 pilot, NSD performed its role) updated quotations of securities were loaded into the system.

func (t *CIBContract) recalculationData(stub shim.ChaincodeStubInterface, loadData *loadDataType, curDay string) pb.Response {...} 

The main procedure cycle runs on all securities for which quotes have been updated.

 for _, securities := range loadData.Securities {...} 

Further several checks are carried out. For example, if the exchange, which received market data, is today a day off, then recalculation should not occur.

 if t.checkHoliday(stub, contract.Settings.Calendars) == "yes" { hisYes := historyType{curDay, "LoadData. Calendar", "System", "LoadData. Today is holiday ! No load market data to contract !"} ... contract.History = append(contract.History, hisYes) … err = stub.PutState(contrID, contractJSONasBytes) } 

To calculate the updated price of the bonds, the accrued coupon yield (ACY) is added to the loaded net price. The pilot implemented support for the 30/360 scheme for calculating ACI.

 priceIzm = float64(securities.Price + float64(securities.CouponRate)*float64((int(settlementDate.Year()) - int(dateStart.Year()))*360 + (int(settlementDate.Month()) - int(dateStart.Month()))*30 + (int(settlementDate.Day()) - int(dateStart.Day())))*100/360/100) curCurrVal = priceIzm 

If the currency of the transaction differs from the currency in which the security is listed, the exchange conversion is carried out.

 if contract.GeneralTerms.PurchasePrice.Currency != securities.Currency { curCurrName = securities.Currency + "-" + contract.GeneralTerms.PurchasePrice.Currency               for _, currency := range loadData.Currencies {              if currency.Name == curCurrName {                           curCurrVal = priceIzm * currency.Value } } } 

Now we need to calculate the LTV. Keep the old value of the coefficient for the history.

 oldCurLTV := contract.MarginingTerms.CurrentLTV 

It is necessary to take into account the margin calls made during the life of the transaction. Requirements can come from both sides, and in two forms:


In the first case, the number of securities in the collateral is simply updated. And in the case of depositing money on them, it is also necessary to accrue the yield indicated in the additional terms of the transaction.

 for _, addCollateral := range contract.MarginingTerms.AddCollateral { currSumCollateral := addCollateral.Sum + (addCollateral.Sum*contract.MarginingTerms.RateOnCashMargin*float64(deltaColDate) / float64(contract.MarginingTerms.Basis))/100 ... allSumCollateral = allSumCollateral + currSumCollateral ... ht := historyType{curDay, System", "LoadData. Recalculation data(addCollateral) Contract " + contrID + " - currSumCollateral: " + strconv.FormatFloat(float64(currSumCollateral), 'f', 2, 64) ... }        ... contract.History = append(contract.History, ht) } 

We calculate the total amount of the repurchase - in fact, it is the value of the loan with interest, which we need to return.

 rePurchasePriceCur := contract.GeneralTerms.PurchasePrice.Sum + (contract.GeneralTerms.PurchasePrice.Sum*contract.GeneralTerms.RepoRate*float64(deltaSigningDate)/float64(contract.MarginingTerms.Basis))/100 

Now we calculate the LTV coefficient. To do this, we deduct the collateral in money paid from the buy-out price and divide the resulting value by the total value of the securities in the security. The amounts that the lender paid come with a “-” sign and will be added to the redemption price.

 contract.MarginingTerms.CurrentLTV = (rePurchasePriceCur - allSumCollateral) * float64(100) / (float64(contract.GeneralTerms.PurchasedSecurities.Quantity) * curCurrVal) 

Finally we count the triggers in the contract. The same procedure will create objects for margin call calls if the LTV value deviates from the specified corridor.

 contract = t.checkTriggerEvents(stub, "LoadData", contract, curDay, securities) 

And write information to the history for display on the UI.

 ht := historyType{curDay, "System", "LoadData. Recalculation data(change curLTV, ADTV) Contract " + contrID + " - oldCurLTV: " + strconv.FormatFloat(float64(oldCurLTV), 'f', 2, 64) + ", newCurLTV: " + strconv.FormatFloat(float64(contract.MarginingTerms.CurrentLTV), 'f', 2, 64)...} contract.History = append(contract.History, ht) 

Let's sum up


Such a scheme can work not only with securities and contracts, but also in other scenarios. For example, with the supply of electricity, where there are different rates, different connections at different times. Or with factoring - lending to suppliers on signals of shipment of goods. In economics, there are a lot of yuzkeys, when each uses its own data sources, which have to be verified.

Our goal is to create a network that connects banks with each other and their clients across the country, and using smart contracts to describe in it contracts not of a crypto, but of a traditional economy, financial instruments. Such a network will be stable, open, and, as it should be in a P2P network, no one will have a special status here.

Source: https://habr.com/ru/post/442692/


All Articles