Engineering is largely about containing complexity. By creating well-defined interfaces, and enforcing that modules interact through these interfaces, each module can ignore the inner workings of the other modules and focus on its own implementation.
Consider engineers building a bridge. They don’t need to work out a new chemical composition of metal specific for their project. Instead, they will take an existing steel “off the shelf”. The steel is a module, and the interface is the desired properties, such as tensile strength, weight etc. If some new material came along with these same properties, it could be used for future bridges without requiring any new bridge-level redesigns.
In electronics, products are built out of reusable components such as microchips. These components were often designed without any knowledge of the final product they will be used in. In fact, they are usually designed to first be plugged into a testing fixture, during which they are called the “device under test”. Later on, when the end product is assembled, it too will be a device under test before it is finally shipped to customers. Treating components as modules that conform to interfaces tames the complexity.
That is the theory. As components themselves become more complicated, using them effectively requires understanding their inner design. In software engineering this is common enough to be given a name: Leaky abstraction.
Consider the simple case of numbers. Programmers can’t even treat these as pure modules. For example, you might assume that adding 1 to a number will always give you a new number that is greater than the original. In many programming systems, including Solidity, this is not so: a fixed amount of memory is allocated to store a number, and if you exceed this it will either throw an error or wrap back around to a lower number, as in a car odometer.
Modularity in Finance
Financial systems are also designed to be modular and standardised.
When you trade stocks, you will typically see them listed according to their ticker symbols, such as GOOG for Google. But underneath this, securities also have special numbers called CUSIPs. For instance, Google’s class A shares have code 38259P508. In a sense, you can think of these as equivalent to Ethereum addresses: They are unique identifiers that exchanges, brokers, etc., can use to ensure they (or their computers) are all talking about the same thing.
How do their computers talk to each other? Most often, it is over a protocol called FIX. This protocol specifies various fields that are common to different message types and gives them numeric tags. For example, CUSIP codes are stored in the SecurityID field, which is given tag 48. Since every company is speaking FIX, it is relatively easy to plug in new connections to existing systems.
That is the theory. In practice, the numbering system is a mess. Before using the SecurityID field, you need to also check IDSource (22). As well as CUSIPs, many other numbering standards are in common use: RIC, ISIN, ISO currency codes, exchange-specific numbers, and more. And this is just talking about the US. Most other countries have their own numbering standards, such as SEDOL in the UK.
The FIX protocol itself is only superficially compatible. Every different provider has their own custom variations of which FIX version they support, which fields they use, and the meanings of those fields. Each entity has its own bespoke interface documentation (often hundreds of pages long), and it is a significant engineering effort to integrate anything at all.
In my opinion, this is the true opportunity of DeFi: finally making good on the largely unfulfilled promise of FIX and the numbering authorities and creating a seamlessly interoperable international financial system.
On the blockchain, the primary unit of modularity is the smart contract. Smart contracts have their own internal storage, and other smart contracts cannot directly read this storage. Why is this? It is not so that contracts can store secret values: Everything on the blockchain is public information and can be read off-chain by anyone with access to a node.
This restriction is there to enforce modularity. Contracts have no way to interact with other contracts except through the interfaces that these other contracts choose to provide.
In the context of DeFi, sophisticated systems will typically be constructed as a constellation of contracts that communicate via well-defined interfaces. For example, rather than having a single lending contract, Compound uses special-purpose cToken contracts to hold each asset.
Building systems as intercommunicating contracts has the benefit that individual components can be accessed by external systems as well, as long as they conform to the exposed interfaces. Additionally, separation into contracts can be used to form trust boundaries between components to increase system security.
In the original version of the Euler contracts, there was a module called the Swap module. This allowed users to swap their eTokens for other eTokens by effectively withdrawing them, swapping on a DEX like Uniswap, and then re-depositing them. Because all user funds were retained in a “singleton” contract, tokens never needed to transit any other wallet for a swap, and this operation was maximally gas efficient.
However, the Swap module had to be very carefully coded and audited because it ran in the context of the main contract. In other words, it was part of the trusted code base (TCB).
To add an additional layer of defense, we created a new module called SwapHub that invoked “swap handlers” outside the TCB. Swap handlers are isolated contracts and are treated as though they could themselves be malicious actors. They are given the funds the customer wants to swap, and then are invoked. If they do not send back a sufficient amount of the desired token to meet the customer’s slippage checks, then the transaction is aborted. In this way, any defects in the swap handler — malicious or not — are fully isolated.
Based on decomposing how DeFi systems work today, our own experience, and some of the current thinking around intents-based systems, we have decided to take this concept much further. In the new system we’re designing at Euler Labs, we have created a flexible but minimal TCB, and have moved as much of the possible system outside of this trust boundary.
As the number of modules in a system increases, the number of possible interconnection pairs grows quadratically. Therefore, coding each contract to specifically interact with all other possible contracts is infeasible.
The way we solve this is with standardised interfaces: Every token-like contract exposes a balanceOf method, no matter what type of asset it is storing, or how it is implemented internally. ERC-20 is the basis for standard tokens on Ethereum. Even though it has several well-known shortcomings, all tokens are written to conform to it. This itself is proof of how powerful standards are: Any possible gain from improving the interface would be much smaller than the loss of breaking compatibility with the rest of the network.
Another standard is ERC-4626, the Tokenised Vault Standard. This standard is wisely backward-compatible with ERC-20, but adds new interfaces suitable for yield-bearing tokens.
At Euler Labs, we believe ERC-4626 will be a fundamental standard. In our interpretation, lending activity will involve multiple vault contracts working together: at least one as collateral and one as a liability. To make this work, we are building a meta-layer for vaults to interact with each other and generate interconnected liquidity, which will also benefit Euler v2. Powered by a modular design, these vaults will also be highly customisable: creators will be able to choose oracles, set LTV, risk managers, and take advantage of additional functionality such as batching, gasless transactions, simulations, and more. Ultimately, standardising modularity at this level will create an ecosystem that will eclipse isolated and bespoke lending markets.
This content is brought to you by Euler Labs, which wants you to know a few important things.
This content is provided by Euler Labs, Ltd., for informational purposes only and should not be interpreted as investment, tax, legal, insurance, or business advice. Euler Labs, Ltd, is an independent software development company.
Neither Euler Labs, Ltd. nor any of its owners, members, directors, officers, employees, agents, independent contractors or affiliates are registered as an investment advisor, broker-dealer, futures commission merchant or commodity trading advisor or are members of any self-regulatory organization.
The information provided herein is not intended to be, and should not be construed in any manner whatsoever, as personalized advice or advice tailored to the needs of any specific person. Nothing on the Website should be construed as an offer to sell, a solicitation of an offer to buy, or a recommendation for any asset or transaction.
Euler Labs Ltd, does not represent or speak for on or behalf of Euler Finance or the users of Euler Finance. The commentary and opinions provided by Euler Labs Ltd., are for general informational purposes only, are provided “AS IS,” and without any warranty of any kind. To the best of our knowledge and belief, all information contained herein is accurate and reliable, and has been obtained from public sources we believe to be accurate and reliable at the time of publication.
All content provided is presented only as of the date published or indicated, and may be superseded by subsequent events or for other reasons. As events markets change continuously, previously published information and data may not be current and should not be relied upon.