Cyril Lapinte - September 05th 2018
In this article, Cyril Lapinte, Mt Pelerin's blockchain lead, reflects on his journey as a blockchain developer and discuss the challenges the team met from the project's genesis until today with the publication of the Mt Pelerin Bridge Protocol for security tokens issuance.
It has now been over three years that I've started my journey into blockchain development. During that time, the blockchain ecosystem has evolved at an incredible pace, so did our approach on technology at Mt Pelerin.
It is an interesting experience to reflect on our journey. I hope that by sharing it, it may very well inspire others and help new projects to avoid some of our initial shortcomings. So let me share with you our experience at Mt Pelerin.
My first project through which I discovered the blockchain was on an on-chain decentralized exchange. By many standards, it is clearly not the simplest project that anyone might want to begin with. The blockchain is already a complex set of topics and you need to proceed step-by-step with it in order to be efficient. I would have been in a lot of troubles if I hadn't had the chance to be mentored at that time by a talented London-based blockchain expert, Xavier Leprêtre.
This project was a huge first step in the team's understanding of the potential of this technology. We understood that a lot of things were possible but most importantly, not without trade-offs. We learnt how interesting was a fully on-chain decentralized exchange, however we also learnt that it would have limited liquidity and it would not be able to offer competitive trade fees. That was the cornerstone for us to commit on a hybrid approach.
Through this project, we also learnt how smart contracts may interact with tokens. When orders are placed and when orders are matched, a decentralized exchange must apply some rules and transfer tokens ownership. And it is what a token provides: transferability and ownership.
However, our challenge was to build a whole regulated banking platform on-chain. A core part of any regulated platform is the ability to handle fiat currencies in full compliance of a given regulatory framework. A fiat currency sounds very simple and many projects have successfully designed stable coins. However, they were - a bit naively - only focused on forcing fixed rates, usually by controlling the quantity of tokens available.
But in reality, a fiat currency comes with a lot of compliance and reporting constraints. A fiat token is an extension of a currency, which belongs to a central bank. It is also important to note that although present compliance rules are known, future ones are not and a fiat token needs to be ready for such ulterior rules. It is clearly not a desirable outcome to have to reissue a token at any point in time.
For the first iteration of Mt Pelerin's fiat token, we did use a very progressive step-by-step approach where we decided to implement the fundamental compliance rules at stake:
Our first fiat token had an embedded whitelist to handle the KYC part. Users were allowed to receive and spend a yearly volume that was configurable for each user. To optimize verifications, amounts sent and received from and to every user were aggregated on a monthly basis. It was an interesting compromise between efficiency and granularity.
That design was then nicely detailed into several layers, and we kept learning along the way. We realized the criticality of thoroughly testing all the features, as it is the only way to be sure that the code works as expected. It also really speeds development time when things start to get a bit complex. We also faced a very interesting challenge to fit all these features into one single contract. Gas is indeed limited within a block to 8M. Any smart contract has to fit within a block, so it is important to decide what matters most to fit in your contracts. I do believe that trying to squeeze your smart contract by shortening your code is a very bad idea. It is clearly the compiler's job and it also greatly increases the safety risks of your smart contracts. It is pretty much like trying to make a car consume less gas by removing airbags and seat belts. I will explain below how you can split code into multiple contracts but it does come with some extra challenges and trade-offs.
Our tokens already had most of our desired features. But as mentioned previously, the initial token design had not much gas left available to support new features. Furthermore, this design would not scale with many issuers, holders and tokens. Lot of code would become duplicated and its management would become tedious and costly.
We thus had to transform the token contract into a set of smart contracts.
We started with the KYC whitelisting and externalized it in a different contract. While doing so, we found out that the KYC of users could have many other uses and that it could transform the whitelist into our current User Registry. The User Registry contains a validity but also supports future attributes already. This last feature is very interesting for adding future flags on users as it has very comprehensive on-chain KYC capabilities.
We integrated the User Registry with the token as a set of generic transfer rules. Administrator of the tokens has the ability to add and remove rules, and each rule must be validated to allow a transfer. It is powerful because it can even allow to pause a token in case of emergency. However, the rules cannot modify how many tokens a user holds. The impact of rules is therefore well described. I must also speak of one of the challenges that one would face when splitting code into multiple contracts. A transaction that spans multiple contracts becomes multiple transaction, one for each contract. This increases the cost and potentially the speed of the operation, but more critically the atomicity of the operation is not guaranteed anymore. This is the kind of behavior that took the Ethereum's Foundation DAO down. That is why we decided that a simple operation such as a token transfer operation should be done within a single small transaction. The consequence is that transfer rules will be read only, and only the token contract can have its state changed by the operation.
We could therefore achieve more refined transferability rules, such as having the possibility to own and transact small amounts without being whitelisted below a threshold (both fixed and over a rolling period), and impose KYC to transact above and other limits that can be defined to trigger an AML pause for off-chain due diligence. These limits can now even be personal (a UHNW should want to pass an extended due diligence up front to be able to send and receive bigger amounts more freely).
In the next step, after adding transfer restrictions we wanted to offer claims based on token ownership. We did introduce the claim mechanism and made a voting and a dividend contract. The challenge with claims is that one must rely on a specific point in time to ensure that each token can only serve once. Claims need to rely on a token snapshot at the time of the claim. That is where we introduced our concept of "proof of ownership". Anytime a claim is available for a user, the token will create a proof of ownership mentioning the balance at that time. The user may use that proof of ownership at any time later on, although some claimable contracts may have a time limit. The user may also trigger a proof of ownership himself, if needed. This enables contracts even outside our protocol to trigger proofs of ownership for their users and benefit from this mechanism.
As we freed some space by externalizing the whitelist and transfer rules, we were able to provide more possibilities for contracts relying on the token. This architecture we chose has allowed us to focus on the life time cycle features of the tokens and not only the issuing part.
One of the critical requirements in banking IT is the auditability of the operations. Blockchain history is audited in a way that it is possible to reproduce all operations since block zero. However, smart contracts cannot use information in this history. Smart contracts can only use what remains on the state at the top of the blockchain. This corresponds to account balances, account nonces and the state within smart contracts. To apply rules based on history, it is therefore necessary to keep the needed information within the state itself. One also needs to keep this information as minimal as possible as it is the most expensive memory space on the blockchain. We ended up choosing a set of attributes that is sufficient for our regulatory needs but also generic and flexible enough to be future-proof.
Our desire to support yet unknown future regulations and needs has pushed our protocol to naturally become very modular and open.
Openness is also a potential weakness as it introduces vulnerabilities that may at some point be used against participants. If doors aren't designed in a vault, it is indeed more robust but loses functionality. One of the classic way to ensure security in the blockchain space is to use multi-signature protocols. Similarly, one of the classic way to ensure security in traditional systems is role-based access control. That is why we are currently designing on top of our protocol a multisig protocol mechanism so that hot accounts have strictly limited access.
We also believe that our multi-signatures contracts will also serve individual needs within a multi-factor authentication strategy. Through our upcoming wallet, we will techies and non-techies alike a very safe and error-tolerant way to handle digital signatures.