1. Home
  2. Knowledge Base
  3. Educational
  4. Explainers
  5. DeFi Protocols

DeFi Protocols

DeFi protocols are a system of interrelated smart contracts and their decentralized governing arrangements that enable P2P financial transactions. DeFi protocols offer communication, connectivity, or software services that parties can utilize to communicate trading interests, but they do not intermediate transactions. Even when DeFi protocols originate from a single software developer or small group of developers, they can be designed to ensure distributed governing authority among a decentralized and disaggregated group of unrelated users.

It’s important to recognize that while the term ‘protocol’ is used interchangeably between P2P networks and DeFi protocols, the two are distinct. As noted in the previous section, a P2P network is simply the governing model for communication method between two or more devices (nodes), and a blockchain is the mechanism used to store and communicate the data (transactions) between nodes; whereas, the term “protocol” in DeFi encompasses the rules, functions, and interactions defined by a collection of smart contracts that allow people to engage in specific activities.

Upgradability

Since a smart contract’s code is immutable once deployed on a blockchain, which ensures security and trust, it also means that bugs and inefficiencies in the smart contract code are permanent unless mechanisms for upgradability are implemented in the protocol. This means that a specific smart contract can be replaced by a new smart contract within the protocol, “upgrading the protocol,” but an individual smart contract itself is immutable and its code cannot be rewritten. One approach is to deploy a new smart contract and migrate users over to the new one. This poses a challenge of upgrading a contract’s code while preserving its existing state – i.e., data such as transaction history, user balances, etc. In this context, the migration from one smart contract to another involves transferring data which could lead to disruptions.

Data Separation Pattern

Fortunately, DeFi protocols can be designed to be upgradable through various architectural patterns. This has led to more innovative approaches to upgradability, such as a data separation pattern. In a general sense, a data separation pattern is a software design pattern that splits functionality between two smart contracts: one for storing data (i.e., state) and another for operational logic (i.e., how software behaves). The data contract stores all the data and includes functions that allow for other contracts to access and modify the data. This contract remains persistent and is not typically the focus for upgrades. The logic contract maintains operational functions (e.g., transferring tokens, updating balances, etc.) and it refers to the data contract when it needs to read or modify data.

When upgrading a DeFi protocol that is designed with a data separation pattern, the logic contract is the smart contract that undergoes an upgrade and the data contract remains persistent. Due to the immutability of smart contracts, this means that the protocol’s governance would choose a new logic contract to deploy on the blockchain and ensure that the new logic contract refers to the existing data contract.

The problem with the data separation method is that once a new logic contract is made, any smart contract connected to the original logic contract, or any front-end providing access to it, must be updated to reference the new logic contract. Furthermore, separating the data and logic into separate contracts can be expensive, as the logic contract has to make external calls to the data contract and requires more gas to do so than a smart contract that can read or modify the data stored within itself. Given these two factors, protocol developers have opted to a proxy pattern design which also separates the data but differs in how it handles the contract logic and data storage.

Proxy Pattern

In a proxy pattern, a placeholder or intermediary (i.e., the proxy) controls access to another object (i.e., the target). In the context of a DeFi protocol, there are two smart contracts: a proxy contract and an implementation contract. The proxy contract acts as a front-facing contract for users and other smart contracts, and delegates their calls to the implementation contract, which holds the main business logic. Importantly, the proxy contract typically stores all the contract’s state.

An implementation contract contains the actual business logic and can be updated or replaced to upgrade the system. If there is an upgrade to the smart contract’s logic, it is simply deployed as a new smart contract and the proxy contract is redirected to the new implementation contract. One way to understand the two contracts’ relationship is to imagine the proxy contract as a universal remote and the implementation contract as a TV – the remote adds a layer of convenience and functionality to controlling what the TV does, but does not need to be changed when the TV’s system is upgraded.

The proxy pattern approach allows for smart contract upgrades without changing the smart contract’s address, preserving the contract’s state, and ensuring continuity for the protocol’s users. However, it’s important to note that upgradability is typically left to smart contracts that are less foundational to the protocol’s functionality such as those that handle auxiliary functions – i.e., features and operations that support the main functionality of the protocol, but are not central to the core mechanics. Smart contracts that are essential to the core mechanics of the protocol – e.g., privacy pools – are often made immutable to ensure a high level of security, as changes could threaten the integrity of the protocol.

Importantly, while a proxy pattern utilizes two smart contracts, just like a data separation pattern, it uses a specific function that allows it to execute the logic contracts code as if it were its own. In other words, users, front-ends, and other smart contracts use the proxy contract to directly execute code in the logic contract. Meanwhile, protocols that are designed with a data separation pattern require users, front-ends, and other smart contracts to interact with the logic contract that then executes external calls to the data contract, making the process more expensive and less convenient when there is an upgrade.

How can we help?