Ensure the security of your smart contracts

Modern Lending protocols,
how it's made:
the compilation

Author: Sergey Boogerwooger, Dmitry Zakharov
Security researchers at MixBytes
Intro
In our series of articles on modern lending protocol implementations, we've explored a variety of new protocols, each with its unique features and implementation tricks. Now, it's time to bring together the most important ideas and implementation insights to help DeFi developers and auditors built more efficient, safe and innovative DeFi structures.

Developing new lending protocols comes with its share of challenges, both from a business and technical standpoint. On the business side, there's the need to ensure the safety and incentivisation of both borrowers and suppliers, manage bad debt, etc. On the technical side, considerations include keeping transactions affordable, performing liquidations effectively, protecting the protocol from abrupt changes and safeguarding its core logic against breaches.

The solutions to these problems are complex — we’re dealing with advanced mathematical models, dynamic rate limiting, additional aggregation structures for "range" operations within the protocol, multi-layer architectures, and more. In this article, we’ll explore these solutions in detail. As with our previous discussions, we won't label any approach as strictly "good" or "bad" because the range of considerations is too vast. Whether it’s advanced mathematics that tackles economic issues or simpler and safer code with strong governance, or a fully permissionless setup, only time will tell which approach is best.

That said, all these improvements should be described to give DeFi developers and auditors fresh insights on how to address these challenges. Let’s get into it.
Concentrated liquidity and operations over ranges
Uniswap v3
The idea of splitting price ranges into separate ticks was first implemented on a wide scale by Uniswap V3, allowing liquidity providers to place their liquidity within a specific price range. The price (a ratio between two assets) in these protocols is defined by the equation: ratio=G, where G is a value, slightly above 1.0 (like 1.0015 or 1.005) and t is a signed "tick" (or "band", or "bucket") number. Each value of t represents some fixed ratio (or range) of the price:

Uniswap V3 ticks
The efficiency of this approach lies not only in the ability of liquidity providers to precisely position their liquidity but also in the algorithmic ability to track additional values within the "ticks". In Uniswap V3, this leads to a highly efficient fee system that allows LPs to provide liquidity to the range of "ticks" without having to perform "for each" tick operations. Collected fees can be gathered also without needing to touch each tick in the range (only the lower and upper ticks are affected (article)).

In lending protocols, "ticks" usually represent the ratio between the debt token and the collateral token. We've discussed these implementations for CrvUSD LlamaLend, Fluid + Vault protocol, and Ajna. While all these protocols use the same concept of price ranges, the way they apply this concept varies.
CrvUSD LlamaLend
In CrvUSD LlamaLend, each "band" contains its own liquidity, and the protocol also has an external oracle price. This allows for the "movement" of bands' liquidity toward the oracle price, continuously swapping debt-to-collateral or collateral-to-debt. This process leaves all bands to the left fully in debt assets and bands to the right fully in collateral assets (similar to Uniswap V3 ticks). In CrvUSD, the pool with bands also acts as a DEX, enabling market makers to swap debt for collateral and vice versa. This makes these actions profitable in the direction that shifts the current band closer to the actual market price. The very interesting mechanic in CrvUSD includes not only the movement of current price band, but also the "resising" of the whole price range scale, making bands ranges "wider" or "narrower" to make soft liquidations more profitable. At the same time, this movement replaces undercollateralized debt with collateral, functioning like liquidations in traditional lending protocols.

CrvUSD LlamaLend bands
Fluid Vault
The Fluid Vault protocol also uses the concept of concentrated liquidity, splitting the entire debt-collateral amounts in the pool into "ticks", each representing a particular debt-collateral ratio. Similar to CrvUSD, the external oracle price determines which tick next lender/borrower will land in. However, the rest of the protocol differs significantly from CrvUSD.

In Fluid Vault, the protocol tracks the movement of the oracle price. When the collateral price drops, the protocol starts aggregating information about ticks that are becoming undercollateralized in special structures called "branches". These branches are used to shift liquidity from undercollateralized ticks to collateralized ones, sequentially removing "bad" liquidity and placing it into "safe" ticks:

Fluid + Vault ticks liquidations
These operations in Fluid Vault are not performed on a "per-position" basis and, similar to Uinswap V3's fee system, are highly efficient because many lenders' positions become "safer" at once after a single "liquidation" operation.
Ajna
The Ajna project (article) uses the same debt-collateral ratio ticks (or "buckets"), but the "no-oracle" concept makes this protocol stand out. Each lender's position belongs to a specific bucket and represents a fixed price of the debt unit. Lenders can place their deposits in any "allowed" bucket, where "allowed" means the range of buckets where the debt is collateralized (which is really simple in Ajna because each bucket directly represents a price between debt and collateral):

Ajna buckets
Ajna tracks the range of buckets using two threshold values: Lowest Utilized Price (LUP) and Highest Threshold Price (HTP). Every operation with debt/collateral in the protocol shifts these values closer to the market price. Unlike CrvUSD or Fluid Vault, where operations can be aggregated, Ajna requires direct interaction with each position and bucket. As a result, there's no aggregation of operations. Instead, Ajna uses special data structures to track partial sums of debt/collateral in buckets (using Fenwick trees) and a "max heap" tree to track maximum values.
All protocols that use the concentrated liquidity concept - splitting liquidity into discrete buckets/ticks/bands - do it differently. This approach allows for "soft" liquidations, aggregate operations over multiple positions, and the creation of "no-oracles" mechanics. However, it also demands much more granular control over multiple entities and requires advanced data structures to be efficient enough for DeFi. Nevertheless, this is one of the key modern DeFi mechanics used in modern lending protocols.
Multi-layer protocols
DeFi stands for "decentralized finance", so, minimizing governance and external control is crucial for DeFi projects. All modern DeFi projects, on one hand, aim to work with any ERC20 assets, offering users maximum flexibility, but, on the other hand, arbitrary ERC20 tokens, such as those with attackers' traps, rebaseable tokens, or tokens with "fee-on-transfer" mechanisms, can break a project's logic and lead to vulnerabilities or hacks. The same applies to strategies and vaults logic, which might work well with one set of assets but become unsuccessful with a different set or under changing market conditions.

One approach to addressing these issues is the multi-layer strategy. It uses several layers (at least two), providing essential functionality on a "base" layer while giving users and projects more freedom on the second layer. As mentioned above, the tradeoff between lenders/borrowers safety is unavoidable. The search for the most effective solutions is an ongoing process, and it's natural to give users and "child" protocols the ability to implement their own risk management schemes without needing to rebuild the "base" layer.

This "base" layer can be responsible for holding the underlying assets, providing oracle prices, and implementing some defensive functions (such as reentrancy protection or rate limiting). An interesting aspect of this approach is that it requires less advanced maths and complicated models. Instead, it calls for simpler, more readable, and reliable code - at least at the base layer - to ensure safety. Developers cannot afford to compromise the base layer, so the code should be well-documented, audited, and easily usable by external projects.
Euler V2
The key idea of Euler V2 (article) is a "modular lending ecosystem" that implements the multi-layer approach. It's not just a single lending project but an ecosystem for building various types of lending platforms on a pack of token vaults created by users. The important point is that the Euler V2 vaults contain only one asset, and each vault works with a single underlying token:
Euler V2 vaults and controller
The multi-layer approach in Euler V2 is achieved through the Controller, which interconnects multiple vaults using access controls and multicalls. A user's operation in Euler V2 is essentially a multicall to several different vaults, storing collateral and borrowing assets. So, the base layer in Euler V2 is the Controller, responsible for access controls (determining which account has access to a particular vault), reentrancy guard, impersonation of accounts (operating an account from another "operator" address), and atomic execution of multi-vault operations.

Vaults can be created by users, and their combinations can implement various risk management profiles. Some vaults are immutable, have no governance, and serve as true "vaults" for collateral. Others can provide borrowing, be upgradeable, implement external incentivisation, and, when combined with collateral vaults, form many different lending solutions using a single entry point at the Controller.
Fluid
Fluid (and the multiple protocols built upon it) also demonstrates a multi-layer approach for building DeFi projects (not just lending). Fluid has a base layer, called "the liquidity layer", with admin and user components. The admin component is responsible for governance actions, setting model parameters, exchange prices, and token configurations, while the user component handles basic operations, including supply/withdraw and borrow/payback operations in protocols.

The base layer in Fluid protects critical protocol aspects: oracle prices, borrow/supply rates, final token transfers, and a very important feature - rate-limiting operations within the protocol to protect it from abrupt movements of funds.

The second protocol layer in Fluid leverages the base layer but implements its own logic, allowing Fluid to build several protocols using the same base layer. For instance, it can be a "traditional" lending protocol built using a conventional scheme (like Fluid's Lending), or a more advanced and complex protocol, like Fluid's Vault (article), which uses concentrated liquidity, ticks, and soft liquidations. All these protocols first implement their logic to calculate target amounts, perform their own state updates, and then use the base layer to "settle" the results. The logic of these protocols can be very flexible because the base layer tracks only global supply/borrow balances and deposit/withdraw limits, while in the protocol, the same supply/borrow balance can be handled differently - for example, split into price "ticks", rebalanced across different assets, or used to implement any other logic.
Morpho Blue
Morpho Blue is a project aimed at serving as a base layer for other protocols. It has a very clear, minimalistic and reliable codebase, implementing pure lending/borrowing logic without any surprises. It allows permissionless and immutable markets in Morpho Blue to be used as vaults for other external protocols. In this case, Morpho Blue can function as a "settlement" layer for more complicated protocols.
CrvUSD LLamaLend
CrvUSD LLAMMA is the key component of the CrvUSD stablecoin. It is a decentralized exchange (DEX) that also uses the concentrated liquidity concept and price bands, allowing it to rebalance its reserves between stablecoin and collateral assets. However, in LLamaLend, LLAMMA is used as a layer responsible for debt/collateral rebalancing (described here). Its design allows the lending protocol to swap collateral for stablecoin and vice versa, shifting the pool closer to market value. In this protocol, LLAMMA helps avoid direct liquidations of "unhealthy" positions by incentivising market makers to remove "unhealthy" assets (stablecoin or collateral) and add "healthy" ones (collateral or stablecoin). This approach of using a DEX as the layer responsible for collateral/debt rebalancing is very attractive, allowing the protocol to function as both "lending" and "DEX" simultaneously, making traders perform the liquidators' job.
Aggregation, optimization, data structures
Modern DeFi requires increasingly complex maths and operations over large sets of entities (ticks, positions, markets). As a result, one of the key directions in DeFi development is optimizing calculations and using specialized data structures to reduce gas costs. From an algorithmic standpoint, the best achievement in this area is a constant(!) transaction cost, as predictability is crucial for market-making software. The EVM lacks many specialized math instructions and cannot use FPUs due to determinism restrictions. Consequently, DeFi protocols often implement specialized calculations and use tailored data structures. Let's explore some of these solutions.
Uniswap
Uniswap is not a lending protocol, but starting from V2 and especially in V3, Uniswap has demonstrated how a specialized math model can replace heavy computations. This is explained in greater detail in our article, where we show how the use of sqrtPrice and liquidity, defined as:

allowed the protocol to completely avoid calculating sqrt() in its code (since sqrt in Solidity is an iterative algorithm). Nearly all operations in Uniswap v3 are simple additions/multiplications/divisions. Replacing key protocol variables in this way has led to highly efficient solutions. Another important feature of Uniswap V3 is its ability to operate with a constant number of entities (ticks) when placing/removing liquidity without touching every tick in the range and to effectively calculate collected fees, achieved by storing partial global fees values in the price ticks.
This approach is particularly useful when the protocol model requires non-standard operations (beyond addition/multiplication/division) across various transaction types . In this case, replacing state variables with their pre-calculated versions (like xy->sqrt(xy) or y/x -> sqrt(y/x)) simplifies protocol interactions and avoids the use of non-constant numeric computations. There's no need to blindly adhere to traditional financial patterns when they can be implemented in a more efficient way.
Fluid Vault
Fluid's Vault protocol, as mentioned earlier, uses the concentrated liquidity concept, similar to Uniswap V3. One of the key features of the Vault protocol is the effective liquidation process, comparable to soft liquidations in CrvUSD and fee collection in Uniswap V3. This is achieved through additional aggregation structures called "branches" that accumulate information about ticks becoming "unhealthy" and enable liquidations that impact multiple users' positions at once. This approach is efficient for operations involving multiple entities. By using "accumulating" structures, the protocol can avoid interacting with each entity directly, thereby reducing gas costs.

Additionally, Fluid uses non-standard bit lengths (like 19 or 51 bits), so the structures in Fluid (and Vault) are tightly packed into 256-bit values, with read and write operations primarily relying on bitwise masking and shifting. You can read more about it in our previous article. This method is particularly advantageous when a protocol employs numerous non-standard bit lengths within structs and requires tight packing of values.
Aave
Aave (V2 and V3) handles users' collateral-debt positions with rebaseable tokens. A user supplying to the protocol receives supply tokens, while a user borrowing assets receives non-transferrable debt tokens. Both assets have a continuously incrementing balance, accumulating interest over time. In contrast, other protocols prefer to handle users collateral-debt positions as complex structs, holding amounts of supplied-borrowed assets, and require manual calculations of accrued interest during operations.

The approach with rebaseable tokens allows for straightforward and efficient borrow/repay/supply/withdraw procedures, which involve simply minting/burning corresponding assets and transferring underlying tokens to/from user. However, working with rebaseable tokens can be tricky in certain cases, i.e. requiring periodic "rebasing" or making it difficult to integrate these assets into external protocols.

Also, the rebaseable tokens approach streamlines the calculation of protocol reserves and debts by simply taking the totalSupply of protocol tokens, making possible flexible and simple market strategy updates. In addition, this approach allows for efficient operations (like repayments/liquidations) using protocol tokens only (paying debt with own supply tokens or seizing collateral as protocol supply tokens).
Ajna
The Ajna project, with its use of price "buckets" and liquidity movement, requires more efficient solutions than simply iterating over the set of buckets. To address this, it employs two data structures that could be a game-changer for DeFi developers and auditors.

First, there's the Fenwick tree - a structure that allows for the calculation of partial sums in an array. This can be especially useful for protocols that need to determine totals over specific ranges.

The second data structure is the "max heap" (or "min heap") tree, allowing trivial access to the maximum (minimum) value in an array by simply retrieving the first element (a good visualisation of building this tree is here). Although inserting into the tree takes a bit more time, this structure is ideal when operations with insertion/removal (like deposit/withdraw) are rare, but quick access to the top value is required.

Permissionless and trustless

Well-known lending protocols like Aave or Compound have serious governance procedures, with their DAOs making decisions about everything from protocol changes to supported assets, fees, and limits. This approach makes these protocols very safe, with many security incidents mitigated by the correct actions of the controlling DAOs. However, it also complicates the process of creating new (potentially risky) markets. Naturally, many actors want to have more simplified access to markets and the ability to introduce new tokens and strategies more easily.

A more open approach may not provide the same level of safety as well-structured, expert-driven DAOs, but it does offer a valuable alternative in the DeFi space. Uniswap has demonstrated that building fully permissionless and trustless markets is something the market really wants, and it can work effectively. So, the shift toward permissionless and trustless DeFi seems to be an ongoing trend in DeFi today.
Ajna
In the race for "permissionless and trustless", Ajna undoubtedly holds a leading position. Like Uniswap, Ajna allows anyone to create an immutable lending pool, and it operates with no governance at all. In addition, Ajna doesn't rely on price oracles - the collateral price and unhealthy positions are handled by the movement of liquidity between differently priced buckets.

While it's still uncertain how this will play out in the long term in the real market, this approach completely eliminates potential issues with oracle price manipulation and governance complications. Sometimes, the best way to solve an engineering problem is simply to eliminate the problem altogether :)
Euler V2
Euler V2 also reflects the trend toward permissionless and trustless markets, allowing users to create markets for any assets. Its Controller layer only connects various single-token vaults and operates solely with the shares of these vaults. If needed, Euler V2 enables the creation of permissionless, immutable vaults. For example, the most security-critical vaults can be deployed as non-governed and immutable, ensuring users that they can always retrieve their assets from these vaults.

This design gives Euler V2 the flexibility to support both custodial and DAO-governed projects as well as fully permissionless ones, all combined through the Controller layer’s multicall capability.
Morpho Blue
Morpho Blue emphasizes minimizing governance actions and supporting oracle-agnostic markets. Governance in Morpho Blue focuses on managing allowed values for fees, LTV (Loan-To-Value) ratios, and introducing new market types. After deployment, the only governance action permitted is setting the protocol fee. Therefore, Morpho Blue also reflects a shift toward decentralization in DeFi, fostering more secure and trustless markets.
Conlcusion
Of course, we cannot cover every new feature of modern lending protocols; much has changed as Solidity and Ethereum have evolved over the years. However, the key innovations in the lending world are:

  • Permissionless and trustless markets
  • Concentrated liquidity (ticks, buckets, bands of collateral/debt ratios)
  • Multi-layer protocols and ecosystems
  • Aggregated operations (soft liquidations, fee collection, accumulating data structures)
  • New gas-efficient math models and optimization techniques
  • The no-price-oracles approach

So, if anyone thinks that DeFi development has stalled, they’re mistaken. Protocols are constantly evolving, with new data structures, designs and patterns emerging in many projects. We’re also seeing a wave of innovative DeFi designs inspired by SNARKs, offering an original vision of the entire DeFi space.

This article concludes our series of articles on modern lending implementations. We covered: Euler V2, CrvUSD LLamaLend, Fluid + Vault, Ajna, Morpho Blue, Aave V3.

Stay tuned for our upcoming articles!
Who is MixBytes?
MixBytes is a team of expert blockchain auditors and security researchers specializing in providing comprehensive smart contract audits and technical advisory services for EVM-compatible and Substrate-based projects. Join us on Twitter to stay up-to-date with the latest industry trends and insights.
Disclaimer
The information contained in this Website is for educational and informational purposes only and shall not be understood or construed as financial or investment advice.
Other posts