---
# System prepended metadata

title: Autofarms article

---

# Autofarms article



In this article we will outline security issues met in yield aggregators - very common type of projects in DeFi. They exist since the very inception of the industry, so they lived the long journey and accumulated vast experience of security techniques and best practices. 

In this article aims to describe bugs that are specific exactly for yield aggregators. They have a unique context. So security audits can be more profound and deep if these specifics are taken into account. Additional frameworks of analysis can help to catch more sophisticated bugs.

# How do yield aggregators work


![](https://i.imgur.com/Lg4wYzy.png)
Source: [https://arxiv.org/pdf/2210.04194.pdf](https://arxiv.org/pdf/2210.04194.pdf)

DeFi projects usually require much liquidity for operating. Liquidity is limited in the industry and projects compete to attract liquidity. Thus DeFi projects are designed to incentivize liquidity providers - in form of fees or token minting. These rewards depend on the user activity in these DeFi projects, thus the return for a liquidity provider is volatile.

Yield aggregator projects “aggregate” some of the options for liquidity providers and offer some additional features and instruments:

1) They build “strategies” - special smart contracts responsible for:
- determining they way the yield will be generated (where, how, in which tokens)
- delivering liquidity to the final smart contracts where returns are generated
- withdrawing and conveying liquidity back to liquidity providers
- modifying risk/return profile (like take leverage for more risk/return by folding)
- maximizing returns by special transaction flows (to receive more rewards in additional tokens)
- optimizing return delivery (like selling reward tokens in pairs gradually)
- taking into account special situations (liquidation risk, emergency withdrawals)

2) They operate in growth-only manner. Yield aggregators prefer not to take impermanent loss risks and avoid situations of negative returns. Thus investments in usually accepted in LP tokens. In some cases yield aggregator can offer additional options for single-side depositing - sometimes it is available for stablecoin pools with large liquidity (like stable swap pools on Curve).

3) They do compounding - rewards are reinvested hourly/daily to boost further returns. For most users it is the main reason for using yield aggregators. It is far more effective to reinvest in one transaction for all liquidity providers simultaneously. In most of the projects its is called “Harvesting”. But it is not only the reinvestment but also the moment for some agents to collect fees on positive returns (strategy builder, the yield aggregator itself, harvest function caller).

Features described above are the backbone of any yield aggregator. But the promoted product may vary. Some of them show off yield aggregating as a core tool (like in Yearn Finance, Beefy Finance), others can promote another products to users leaving yield generation itself secondary (like OUSD offering their stablecoin or Idle offering fixed or leveraged rates in form of tranches). These special product pivots will be excluded from our analysis.

# Main security analysis principles

We see two principle components of yield aggregators that make security analysis special.

**1) Usually they have many vaults/strategies - their design and risk may vary significantly.** 

Yield aggregators prefer to take responsibility for security of their vaults/strategies. Thus yield aggregators design the processes of internal audits, testing, monitoring, so that strategies are well analyzed before going live. Also they invite external strategy builders and incentivize them to extend the marketplace of vaults/strategies.

It is different from most of the DEXes where pairs share the same smart contract but can have unpredictable tokens traded. DEX teams build only smart contract standards, but usually are not responsible for tokens traded in pairs.

In contrast, yield aggregator vaults/strategies are poorly standardized - they have different transaction flows, different DeFi projects connected, different tokens transferred. Thus, even more variety of bad scenarios possible. So it is a normal practice for yield aggregators to invite external auditors to analyze some of the vault (especially core ones).

**2) Unique set of Trust Assumptions.**

Vaults have strategy builders and managers. They have some privilege functions, designed to be in favor of liquidity providers. But these owners are potentially bad actors. So auditors must make a point of owners as attackers who wait for a moment to exploit their privileges. 




# Summary of common security pitfalls

### Manipulated conversion rate between shares and underlying

The conversion between shares and tokens accepted is a tender spot for many DeFi projects. Wrong calculations are easily exploited.

Yield aggregator are not far different here - they usually mint tokens, perfectly described by Beefy Finance as “interest-bearing tokenized proof of deposit”. Users’ balances do not rise with more rewards earned. But one share should represent more and more underlying tokens with more rewards accounted. This conversion rate is dynamic and can be exploited.

Rate calculation tend to use oracles or DEXes. To much usage of DEXes is the core point where vulnerabilities are hidden. This is the thing attackers exploited when hacking the most significant yield aggregators. The attacker’s goal is to decrease share conversion rate and increase later one.

The general advise for analysis is the same as for many projects using DEXes for accounting - to assume that the DEX can be set to any price within the same transaction. The red flag is detected if deposits and withdrawals in the same transaction are possible to be made using different conversion rates. 

Relying on DEXes may have different forms. Consider PancakeBunny hack ( [link to exploit analysis](https://medium.com/amber-group/bsc-flash-loan-attack-pancakebunny-3361b6d814fd) ) that rewarded depositors with 3 BUNNY tokens for every 1 BNB in fees collected. But the return is calculated in LP tokens and required conversion to BNB nomination. And PancakeBunny made a mistake to use DEX for this conversion, resulted in recursive manipulated BUNNY minting for attacker.

### Swaps not protected from sandwich attacks

Strategies widely use swaps. They often try not to earn just protocol fees, they tend to maximize additional incentives in additional tokens. Like PancakeSwap mints additional CAKE swaps for liquidity provision in relevant pools. These additional rewards are never accumulated for a long time - a strategy swaps them in DEXs immediately on every harvest. 

Attackers can exploit these predictable transactions that sell tokens on the constant manner. They make sandwich attacks to increase slippage for the vault and receive risk free tokens as their returns.

The second spot with the same problem can be found in vaults that receive investments in different tokens. Vaults swap these tokens in the very beginning to receive LP for yield generation.

The recommendation here is straightforward - to control risk tolerance in swaps, include invariants of minimal token to receive after swaps.

### Attacks from the owner

As we stated previously, it is the best practice to assume vault owners/managers as bad actors. They usually are not related to the yield aggregator’s team.

Here are some vectors usually available for owners/managers:
- when current vault/strategy functions allow arbitrary calls
- when a vault allows changing a strategy. It is the case when the previous one turns ineffective and requires update. Many yield aggregators has this feature. It is very convenient for all parties, otherwise updating would require withdrawals from every single liquidity provider. As the result, new version can introduce additional hidden privileges for owners.
- tricks to boost rewards/fees for managers artificially

### Token-specific risks

For many yield aggregators the number of active strategies covered can be dozens or hundreds - with unique set of projects touched and tokens transferred. 

The variety of tokens deviating from the predictable ERC-20 standard can introduce additional exploit vectors. It is the case for many DeFi projects, but here the situation is less under control as the nature of yield aggregators itself imply the large diversity of scenarios. That is why the appearance of unusual tokens is considered likely.

All types of unusual tokens are risky for strategies - inflationary/deflationary, rebasing, interest-bearing, hookable, having weird decimals, returning nothing on function calls. That is why tokens are in special focus when analyzing strategies.

That is also the reason why auditors recommend to put nonReentrant modifiers for all key functions. To get rid of the risk of unexpected hooks. Very simple but very effective.

### Bad balance management

Sometimes rewards are calculated wrong. Some reward tokens can be ignored, or stuck on some smart contracts. Rewards deserve strong testing, as there are so many spots to have an error.

### Poor vault lifecycle design

Bad vault design can underestimate bad scenarios happened with vaults. Some of them imply that only deposits and withdrawals demonstrate the full lifecycle. That is obviously not true. Vaults must work with the wider risk profile and must design risk mitigation procedures. Pools that generate yield can be hacked, positions on lending protocols can be liquidated, and etc.

Team must check that special functions are embedded for owners/managers to manage such situations (to pause, to emergency withdrawal, to manage liquidity position and leverage/folding. 

It must be noted, that this is one of the hardest topics to analyze, because it requires not only understanding the code, but also the variaty of scenarios of what can go wrong.

----

In the following case study we will take a simple vault and try to analyze it from the perspective of these attack vectors.

# Case study: eveluating Beefy Finance

Here we will describe Beefy Finance vaults and how they deal with attack vectors.
Our example is CAKE-BNB LP Vault. 
https://app.beefy.finance/vault/cakev2-cake-bnb

Here is the illustration of smart contract system for this vault, inculding the money flow.
![](https://i.imgur.com/MFbOIPT.png)


This Beefy vault touches five contract, three of them are written by Beefy - Vault, Strategy, BoostStaker. Every contract has its own role.
**Vault** - is responsible for interaction with users (receiving LPs and sending LPs grown). Every deposit mints shares, every withdrawal burns shares. The contract is ERC20, thus shares are transferable as usual tokens. Vault is a key spot for conversion logic between LPs and shares.
https://bscscan.com/address/0xb26642B6690E4c4c9A6dAd6115ac149c700C7dfE
**Strategy** - manages the whole logic of token transfers. Harvesting happens here - it should 1) reinvest grown LP and 2) sale additional rewards in another tokens, sell them on DEX to receive token0 and token1, deposit them into the DEX pair to convert them to more LP.
https://bscscan.com/address/0xDE238C509bcCBCd91B90dE40dF3e25B43A131311
**BoostStaker** - this is the intermidiate aiming to boost received token rewards via sending the portion of them to a veContract, if it exists for a reward token and if it is included in the strategy. This Beefy strategy uses this BoostStaker but do not send tokens to veContract - so additional rewards not farming in fact.
https://bscscan.com/address/0xd7c0c12c91750a6ef37580d44b0fd6af1068e615#code
**MasterChef** - contract from PancakeSwap receiving LPs, LPs must be from the whitelist, usually from pairs with CAKE token from one side. MasterChef holds ~1M dollar balance in CAKES and distributes them to depositors of LPs. That is the well-known instrument for projects to incentivise liquidity provision. This is the source of CAKES in the strategy.
https://bscscan.com/address/0xa5f8c5dbd5f286960b9d90548680ae5ebff07652#code
**DEX** - the strategy does not evaluate the return in CAKE tokens. In order not to deal with them, every CAKE on balance is sold on DEXes to receive more LPs.
https://bscscan.com/address/0x10ed43c718714eb63d5aa57b78b54704e256024e

Sometimes earned minted tokens (like CAKE in out example) can be staked into veContract with the timelock to receive additional mint distribution (BoostStaker module). But it is not the case for this CAKE-BNB LP Vault.

Let's go through some common attack vectors, one by one, and find some arguments that this vault is secure from attackes.

## Vector one: Manipulated conversion rate between shares and underlying

We will illustrate a simple framework to analyze conversion rates. We check that an attacker cannot withdraw more than deposited.
Steps are:
1) to take functions where conversions happen
2) to decompose conversions to understandable formulas
3) analyze every element in formulas, to check whether an attacker has options manipulate these elements. Manipulating any of elements means manipulating the whole formula return, thus the whole conversion rate.

The main contract dealing with this issue is Vault.
This is the code of deposit/withraw function.
![](https://i.imgur.com/qOFQsCj.png)

Let's decompose it to simpler formulas.
![](https://i.imgur.com/8ibjv02.png)
![](https://i.imgur.com/ctG9thp.png)

These formulas are derived from the code and aim to illustrate all components separately. Some lines deal with risk of deflationary tokens (where tokens can be lost during transfers). We leave this in formulas.

Also, you may notice from the code that the function  `withdraw()` additionally checks for `b` - LP balance on Vault contract. We ignore it for now, but will get back to it later when analyzing other vectors. We found interesting math errors.

We will focus on each formula element and try to estimate possibilities for an attacker to manipulate an element number. Also, we assume that an attacker has unlimited fund and can flashloan at anytime. An attacker's goal is to boost [shares per LP] when depositing and lower [share per LP] when withdrawing - potentially it will allow to withdraw more funds than deposited (but not necessary).

Now, let's analyze all of the elements:
1) **Total shares minted** 
This parameter is calculated before any token movements, and there is no way for an attacker to mint/burn shares using other functions. Additionally, this parameter is stored as a contract variable, and no calls are required to calculate it. 
Therefore, this element is protected.
2) **LP balance on Vault + LP balance on Strategy + LP accrued on MasterChef**
These parametres are easily boosted - an attacker can send tokens on these contracts. But it not always mean anything dangerous. First of all, an attacker cannot revoke these sent tokens. Secondly, in our case an attacker boosts [shares per LP], but the return from these manipulation is less, than cost of balance boost. Imagine 100 shares of supply and 200 LP tokens in balances, the conversion rate is 0.5. First an attacker deposits on the current rate with 100 LP tokens. Now we have 150 shares and 300 LP tokens. Now the attacker sends directly 150 tokens on balances. The converison rate turns 150`/`450 = 0.25. Yes, the attacker managed to lower the [shares per LP]. But there will be no profit from such an attack. The attacker withdraws 50 shares, but receives 450`*`50`/`150 = 150 LP tokens. But cost were 100 LP tokens (for deposit) and 150 tokens (for direct balance boost).
Therefore, this element is not protected, but it is not vulnurable.
3) **Percentage of LPs lost during transfers**
Here the vault tries to deal with deflationary tokens.
This element is protected, and an attacker usually cannot effect on this parameter in one transaction. But some manipulations are possible for rebase tokens. An attacker can frontrun balance update transaction and have a sequence of transaction with different converison rates. But it must be noted that yield aggregators prefer not to deal with rebase tokens (like many DeFi project).

As the result, the formula is protected from attacks. What lessons we can derive here?
1) most of numbers are taken **before** any token movements
2) it is **simple**
3) it **does not fetch price feed** and does not read external contracts much
4) deposit and withdrawal **formulas are the same**

Final words here, you could notice that the formulas are not quite the same. The trick is in the Percentage of LPs lost during transfers. We have multiplication in deposit, and division in withdrawal. But that is ok in the context of deflationary tokens. It is always the losses for users: receive less shares when depositing, require more shares when withdrawing. Thus deviasion in formulas here is neccessary.

## Vector two: Swaps not protected from sandwich attacks

For yield aggregators there are two common spots where unprotected swaps may exist:
1) Vault externals: Token conversions when depositing and withdrawing
2) Vault internals: Token conversions when harvesting or other actions

Let's take a look on both area for out chosen CAKE-BNB Vault.

**Token conversions when depositing and withdrawing**

As you can see from the interface page, this Vault allows multiple tokens for deposits and multiple tokens for withdrawals.
https://app.beefy.finance/vault/cakev2-cake-bnb
![](https://i.imgur.com/NyDYNXz.png)

But the Vault contract accepts only one token type - LP.
Thus the conversion happens somewhere on external contracts.
This is the transaction flow described by Beefy.
![](https://i.imgur.com/NCPb7uY.png)
This is an example of such a transaction.
https://dashboard.tenderly.co/tx/bsc/0x68d7210daadbf31c06a84fb9fe5d1b5ad15c8d9a00cc8b9de52119510119d5c0/debugger

From the transaction we derive the contract dealing with swaps.
https://bscscan.com/address/0x10ab57c5889a00c497ce6be7ce142bb9a613e362#code

Swaps here go through the DEX router an implement AmountOutMin everywhere - the parameter is inputed as data within transaction initiation, thus calculated offchain. The transaction example proves, that this amount is not set zero by default. This is enough to mitigate sandwich attacks.

**Token conversions when harvesting or other actions**

The Strategy contract is the one to deal with these swaps. In our strategy swaps are used to exchange CAKEs received from the MasterChef as rewards.
![](https://i.imgur.com/bPsTWQG.png)
As you can see, AmountOutMin is set zero here. Thus, it is vulnurable for frontrun in case of significant slippage swaps. But the context is that high slippage swaps here are unlikely to happen - the pool is much larger than the average CAKE harvest amount. Moreover, harvesting can happen frequently, as the Vault operates on Binance Smart Chain - it lowers the likelyhood of large CAKE harvesting to happen in one transaction.


## Vector three: Attacks from the owner

Our CAKE-BNB Vault use Beefy standards to set role privelleges - all vaults are the same and quite secure.
[💡 На самом деле эту зону я происследовал меньше всего, т.к. вижу её самой маловероятной по нахождению дыр. Набью сюда текст в самую последнюю очередь, чтобы чисто пустоты избежать.]


## Vector four: Token-specific risks

In our Vault tokens are quite common and do not have additional risks.

## Vector five: Bad balance management (+our finding)

The Vault deals with simple tokens, but leaves some code to mitigate surprises if deflationary tokens are transfered. It is not the case in our Vault, but it exist as a standard, as the code migrates from strategy to strategy. The code applies balance checking, thus only tokens received in fact are accounted.

We found one minor mistake, that can lead to wrong withdrawal calculation for shareholder. This case look not so critical, but it is interesting how it is possible by design.

The problems lies in this Vault function and how it is used.
![](https://i.imgur.com/f4f4BV3.png)
This function calculates "assets under management" and is used to calculate [share per LP]. It summurize LP balance on Vault, Strategy and accrued LP tokens on MasterChef.

Two conditions must be met:
1) significant amount of tokens on Vault and Strategy contracts
2) LP is a deflationary token (the code tries to manage these situations)

In this case withdrawals will go wrong for shareholders.
Recall the function.
![](https://i.imgur.com/axZEHok.png)

Let's take a simple situation.
We have 100 shares minted, two shareholder 50/50.

And we have 200 LP tokens returning from `balance()` function, with the distribution between contracts:
1) 50 on Vault
2) 50 on Strategy
3) 100 on MasterChef

And let's apply 1% burning for deflationary token when it is transfered.

Imagine the first shareholder to withdraw 50 shares.
According to the `withdraw()` function, this shareholder will withdraw 98.5 tokens.
When the second shareholder withdraws 50 shares, he/she will receive 96.05 tokens.
As the result, the had the same shares, but withdrew different LP tokens.

How did it happen?

Every contract withdraws funds from the next contract in the chain. 
![](https://i.imgur.com/TRIyaCG.png)
If the Vault contract has some LP tokens on balance, it will not withdraw them from the Strategy. The same is for Strategy - it tries to pay with own funds before withdrawing from BoostStaker. And so on.
LP tokens on balances of "deeper" contracts **are more expensive** in case of deflationary tokens.
Applying 1% of burnrate on transfer, 100 LP tokens on MasterChef will take 4 transfer to appear on the user's wallet, only 96.05 will remain.

Thus, the first shareholder could withdraw "less expensive" tokens, with minimum transfers.
While the second shareholder is left with "more expensive" tokens, that will experience 4 transfers when withdrawing.
![](https://i.imgur.com/3qPCH8L.png)

In the `withdraw()` function the key parameter is `r` which leans on the `balance()` function. This function adds up three components of the balance, each with the different effective value.
For deflationary tokens it is not correct to summarize token balance on different contracts if they will require different number of transfers.

## Vector six: Poor vault lifecycle design

This vector is more applied for more sophisticated strategies. In our CAKE-BNB Vaults everything is straight-forward. Nevertheless, the Vault follows the internal standards and has emergency functions.

# Examples: Famous hacks and what went wrong


## Harvest Finance
1) Hacker flashborrows 18M USDT and 50M USDC
2) Sell 18M USDT on Curve. USDT turns cheap, USDC turns expensive
3) Deposit 50M USDC on Harvest. Harvest checks Curve to receive the value of USDC. And mints 51.5M shares. More shares for more expensive tokens.
4) Setting Curve price back to normal
5) Withdraw 51.5M shares from Harvest. Harvest checks Curve to receive the value of USDC. Now USDC is cheaper, USDC/shares conversion rate is back ~1:1. The attacker receives 50.6 USDC.
6) Profit 0.6M USDC per transaction -> iterate many times
**Summary:** do not use DEX prices to calculate Vault conversion rates


## Yearn Finance (simplified)
1) Attacker flashborrows USDC and DAI
2) Curve 3Pool: deposit 36M DAI, withdraw 165M USDT
USDT turns expensive, DAI turns cheap.
Attacker mints many 3pool shares.
3) Deposit 93M DAI to yDAI Vault on Yearn. Yearn deposits cheap tokens on Curve, Yearn receives little 3pool shares for this.
4) Attacker sets prices back to normal
5) Attacker withdraws DAI deposited in step 3 on Yearn. Yearn returns only 92.3M DAI from its 3pool shares. Thus attacker receives 92.3M DAI.
0.7M DAI are left on 3pool, as a profit for Curve liquidity providers.
6) But the attacker is the main liquidity provider (with minted 3pool shares on step 2), so the attacker can withdraw profits.
**Summary:** Bad balance management, it did not expect receiving less 3pool tokens



# Internal processes to control risks

Some yield aggregators apply internal procedures to assess vaults and strategies.

Yearn onboards strategies with many steps and has a strong risk scoring:
https://docs.yearn.finance/resources/risks/risk-score#strategy-risk-score

The same thing is for Beefy Finance:
https://docs.beefy.finance/safu-protocol/beefy-safety-score


# OUTRO

Yield aggregators deal with the whole set of situations possible in DeFi. That is why auditors must pay special attention to vault security analysis with its special vectors.

We described only most distinguished security issues, those distinguishable for yield aggregators. Obviously, all of the smart contract vulnerabilities can be met there and be destructive.

