---
# System prepended metadata

title: Vulnerable spots of lending protocols

---

# Vulnerable spots of lending protocols

In this article we will try to go through core security vulnerabilities common for lending protocol.

Lending protocols gathered the long list of hacks, so they can be categorized. The understanding of these vulnerabilities is a perfect tool for an auditor - lending protocol have same vulnerable spots and typical attack vectors. It is a good idea for an auditor to start the analysis from investigating these vectors or, at least, to have these vectors in mind when auditing, as a tool applied to lending protocols. It is applicable both for forked lending protocols and those with unique logic.

## The market overview for an auditor

The idea of lending protocols is very straightforward. 

**1) Users can borrow**
You put 1 ETH as collateral (1000$ value) and is allowed to take 700 USDC. Yes, it is required that you borrow less value than your collateral. Is may sound useless, but the usecase is the following: No matter how token prices go - you can get back 1 ETH only if you return 700 USDC. In this sense, a lending protocol allows you fix the price of USDC/ETH.

**2) Users can lend**
Previously borrowed 700 USDC are not taken from nowhere. Lenders are those who put capital. These tokens are stored on smart contracts, some portion of these token lies untouched, not borrowed by anyone. [Tokens Borrowed] / [Tokens Lent] = is called “Utilization”. “60% Utilization” means that lenders put 10 ETH on smart contract, but borrowers borrowed only 6 ETH.

**3) Lenders earn when funds are borrowed**
Previously we said that that you should give back 700 USDC to receive your collateralized 1 ETH. Well, it is not so true - be ready to give back 702 USDC. Funds borrowed accrue interest in time, like 6% annually, for instance. These 2 USDC is the earning for lenders, and it is their motivation to provide liquidity.

**4) The rate is dynamic and usually (but not always) depends on Utilization**
Protocols experiment with the exact formulas. But in the majority of cases the rate rises with the utilization rising.

**5) As prices move, protocols protect themselves so that your funds borrowed do not exceed funds collaterized**

Market price of your assets changes in time. So the protocol tracks that your value borrowed is not above the value of your collateral. Even worse, not above ~80% of your collateral. This 80% is Max LTV - Max Loan-To-Value coefficient. 

**6) You can lose your right to repay your borrowed funds to receive your collateral**

When the LTV of your position is above Max LTV, liquidation happens. Your collateral is sold and you lose your initial opportunity to receive your 1 ETH for 700 USDC, your position is closed.

### Leverage usecase
It is very common for DeFi users to utilize a “folding” strategy. 
Imagine you have 1000 ETH.
You deposit 1000 ETH on Lido and receive 1000 stETH. This is your investment in liquid staking and you will receive gradual returns.

Then you put 1000 stETH as collateral on Aave. Then you borrow 700 ETH. Then you deposit them on Lido and receive 700 stETH. Then put 700stETH as collateral on Aave….
… and repeat multiple times.

It turns out that you deposited in Lido = 1000 ETH + 700 ETH + 490 ETH ….
So you receive “leverage” on your return on Lido.

It is simple when you expect that stETH and ETH exchange rate is not volatile. But things become complicated when you have non-correlated assets - little price move would destroy all the folding, as positions will be liquidated.

### Types of projects

The audit process for a lending protocol depends on its type. There are two categories:

**1) Aave/Compound forks**

These projects copy the codebase of Aave or Compound.

One of the options for an auditor is to focus on spots where a project is different from Aave or Compound. As practice shows, these differences are usually the targets for a hacker, as they allow new transaction flows, not possible on Aave and Compound.

The vast majority of projects are forks, and usually they differentiate with the list of allowed tokens and oracles for these tokens. They are straightforward for security analysis, because:
- Aave and Compound code is highly researched in the industry, with many audits done (for Aave and Compound themselves and for their forks). Also, it is likely that an auditor has at least one Aave/Compound fork previously audited in experience.
- The majority of lending protocol hacks touched these forks (usually because they introduced new logic, tokens or oracle logic). So auditors are aware of things that attract vulnerabilities.

**2) Projects with specifics**

They are not forks. They introduce new mechanics.

Auditors treat such a project just as a DeFi project, in general, meaning the whole set of audit instruments and practices is helpful here. By the way, common attacks on Aave/Compound forks are still an issue here, as we have the same attack vectors possible here. So it is a great practice trying to prove a project is secure from these attacks.

Here are some examples of projects in this category:
- Projects with the factory allowing to build isolated markets. Imagine that the project can create a few smaller mini-Aaves and mini-Compounds. They have different lists of tokens, and their liquidity is separated. In isolated markets risks of assets in one market has no effect on other markets and the whole system.
(Fuse from Rari Capital)
- Projects working with isolated pairs. They are like isolated markets, but only with two tokens: one token is allowed for borrowing&lending, and the second token accepted as collateral 
(Fraxlend, Kashi from Sushi)
- Projects introducing fixed rates 
(Examples: Notional Finance)

and etc.

# Common attack vectors

The overall idea for all hacks is to borrow more, than was deposited. Every type of attack is a technique to achieve this.

## Oracle attacks

In this type of attacks the goal is the same - to borrow more than deposited. But in this category attackers try to make the protocol think that the value deposited is high, or that the value borrowed is low. It is a success if an attacker deposits 1000 USD, but oracle manipulations make a protocol think that 5000 USD was deposited. In will allow to borrow 3000 USD value, and LTV check will pass.

The most obvious issues happen when a protocol takes prices from Uniswap pairs either by getReserves() or by balanceOf(). This is a redflag in the majority of cases. Even beginner hackers know that it easy to take a flashloan and set any price in the pair - either very high or extremely low. Only very old projects did such mistakes, or scammy projects with low liquidity.

But, when analyzing the biggest Lending hacks you may find that the mispriced assets are **LP tokens** or shares in vaults. Lets take the Warp Finance as an example.
[https://rekt.news/warp-finance-rekt/](https://rekt.news/warp-finance-rekt/)

Warp Finance allowed LP tokens to be deposited as collateral. LP tokens usually are not so liquid, so protocol introduce some logic to price these tokens.

In Warp the team calculated LP token price as [Pair TVL] / [LP tokens minted]. Sounds quite reasonable, but this was the bad idea for a Uniswap pair. Uniswap pair keeps k constant, but TVL is not guaranteed to remain constant.

The TVL formula was = (reserve0 * price0) + (reserve1 * price1). The team took secure price feeds (TWAP). Also, k is always  constant, but the whole TVL return can go up and down dramatically when large swaps happen.

![](https://i.imgur.com/WKNsfVP.png)
Source: [https://cmichel.io/pricing-lp-tokens/](https://cmichel.io/pricing-lp-tokens/)

So that is what happened - the hacker took flashloan and manipulated the TVL calculation for the pair, effecting the LP token value.

This issue is perfectly explained here:
[https://cmichel.io/pricing-lp-tokens/](https://cmichel.io/pricing-lp-tokens/)

You can find the same idea but with more complex steps in lending projects that accepted shares of vaults at Yearn. Lets take CREAM. CREAM had multiple of attacks, and one of them is related to yUSD - vault share, an LP token with the simple stablecoin strategy on Curve.
[https://mudit.blog/cream-hack-analysis/](https://mudit.blog/cream-hack-analysis/)

CREAM used yUSD.pricePerShare() to receive the value of yUSD. Function logic is straightforward = [TotalUnderlyingInPool] / [TotalSupplyShares]. The only option to manipulate this formula is to increase TotalUnderlyingInPool. Is may seem that it is one way operation - anyone can transfer tokens to the pool, but there is no way to extract tokens from the pool, so the operation is complicated. But it is not. One can flashloan millions to deposit funds to Yearn and become the biggest Yearn vault investor, so that to withdraw the proportional share of token in anytime. So these prerequisites allow anyone to manipulate the return of pricePerShare(). 

Check some other hacks based on wrong token evaluation:

- Inverse Finance
[https://halborn.com/explained-the-inverse-finance-hack-june-2022/](https://halborn.com/explained-the-inverse-finance-hack-june-2022/)
- Cheese Bank
[https://peckshield.medium.com/cheese-bank-incident-root-cause-analysis-d076bf87a1e7](https://peckshield.medium.com/cheese-bank-incident-root-cause-analysis-d076bf87a1e7)

**Recommendations when auditing:**

1) strictly check the price source for all tokens - you should be confident that no element in the formula can be manipulated.
2) use Chainlink oracle
3) use TWAP price when Chainlink price is not available (but it is bad advice in some cases, check the following chapter)

### **On using TWAP as the price feed**

The price from TWAP is hardly manipulated in one transaction and block. But being atomic is not the requirement for an attacker. TWAP is just a formula using onchain sources, and it is the question of time and cost to attack TWAP.

Here is an article researching the cost of TWAP attacks.
[https://eprint.iacr.org/2022/445.pdf](https://eprint.iacr.org/2022/445.pdf)

To sum up, attack on TWAP for low liquidity tokens can be profitable.

Lets take a look on Inverse Finance attack example:
[https://twitter.com/FrankResearcher/status/1510239094777032713?s=20&t=RBNXo-6wEDCiBE5a9nO0-Q](https://twitter.com/FrankResearcher/status/1510239094777032713?s=20&t=RBNXo-6wEDCiBE5a9nO0-Q)
In this hack no flashloan is used, and the attacker had to use own 901 ETH. This attack is not available for everyone, but still an option for some DeFi users. It cost 500 ETH to change the value of the collateral and borrow 15M USD when only 0.65M USD in INV tokens was deposited.

The same hack happened with Moola.
[https://www.coindesk.com/markets/2022/10/19/celo-protocol-moola-market-loses-over-10m-in-market-manipulation-attack/](https://www.coindesk.com/markets/2022/10/19/celo-protocol-moola-market-loses-over-10m-in-market-manipulation-attack/)

Take a look at the price chart - that is a good representation how the TWAP manipulation happens in time.
![](https://i.imgur.com/ogqgPuT.png)

So be aware, that using TWAP is not always helpful. But sometimes it is necessary when no better price feed is available. For such a case the cost of attack must be taken into account. It is ok, when the cost of the attack is more than potential returns, so that any TWAP attack will be unprofitable.

Also, TWAP can work different in different context. For instance, the aforementioned Warp Finance used TWAP correctly, for a pair with much liquidity (ETH/DAI). But Warp Finance used the TWAP price to calculate the value of LP token. Reserves still still left manipulated, as well as the overall TVL calculation (based on reserves * price).

## Reentrancy with hookable tokens

This is one of the most common types of hacks.
It happens when one of the token on a protocol is hookable.

Imagine the protocol that accept USD as collateral and allows borrowing in hookUSD (with hooks).

Hookable tokens in the majority cases follow ERC-777 standard:
[https://eips.ethereum.org/EIPS/eip-777](https://eips.ethereum.org/EIPS/eip-777)

Its transfer functions include three steps:
- call token sender before balance change
- apply balance change
- call token receiver after balance change

These calls (hooks) are optional, and the call receiver must allow these calls. In our case - an attacker will definitely allow these calls to the token sender.

The flow without an attack will work this way:
![](https://i.imgur.com/IUhCx1z.png)


After the hook, an attacker can call any protocol function once again. The goal is to bypass the LTV check. So the attacker calls Borrow once again during the hook. The first Borrow call is still not complete, and token transfer still have not changed balances. So the LTV check will pass, because the protocol has not transferred any tokens yet, so the attacker still has not borrowed anything (if observing the balances).
![](https://i.imgur.com/ttaMBhJ.png)


So, any hook with call to Borrow allows to bypass multiple LTV checks. After all hooks the cascade of balance changes happen and the hacker will see the balance 700 * (Number of hooks).

This is the simplest example of using hookable tokens for hacks.

In practice, they can have different forms. Check the list of some selected examples with the detailed hack descriptions:

- CREAM hack
[https://blog.merklescience.com/hacktrack/hack-track-analysis-of-cream-finance-hack](https://blog.merklescience.com/hacktrack/hack-track-analysis-of-cream-finance-hack)
- Fei Rari (Hook on ETH sending)
[https://www.certik.com/resources/blog/6LiXVtPQ8q5AQfqOUPnTOS-revisiting-fei-protocol-incident](https://www.certik.com/resources/blog/6LiXVtPQ8q5AQfqOUPnTOS-revisiting-fei-protocol-incident)
- Ola Finance
[https://twitter.com/peckshield/status/1509431646818234369](https://twitter.com/peckshield/status/1509431646818234369)
- Aagave
[https://rekt.news/agave-hundred-rekt/](https://rekt.news/agave-hundred-rekt/)
- Hundred Finance
[https://rekt.news/agave-hundred-rekt/](https://rekt.news/agave-hundred-rekt/)
- Lendf.me
[https://slowmist.medium.com/slowmist-details-of-lendf-me-reentrancy-attack-3e168ab5f2b1](https://slowmist.medium.com/slowmist-details-of-lendf-me-reentrancy-attack-3e168ab5f2b1)

**Recommendations when auditing:**

1) observe the code as if all tokens transferred are potentially hookable (this will help to identify vulnerable spots)
2) recommend clients to avoid hookable tokens at all
3) take in mind that ETH transfer can be a hook in some cases
4) insist on following check-effect-interaction pattern (but it will not help in all cases)
5) reentrancy protection is likely a good choice

## Summary

In this article we categorized major security incidents that lending protocols experienced in last years. Two crucial spots to deep analysis are 1) oracles and 2) listed tokens. Having a special focus on these vectors is a perfect investment of efforts during audits.