7🛡 #DeFi #Security lessons learned from Beanstalk Farms~$182m hack

Raul Riesco
Babylon.finance
Published in
6 min readApr 18, 2022

Babylon is a community-led asset management protocol that enables users to create investment clubs (we call them gardens) and invest in DeFi together. It’s built on the Ethereum network and it’s non-custodial, transparent, permission-less, and governed by the community. BABL is the governance token behind it.

Security intelligence series from Babylon

TL;DR:

  • Do not allow to vote retrospectively.
  • Flashloan resistance (DENY ALL unless allowed).
  • Every small change in the codebase matters.
  • Time lock delay as a standard for governance.
  • Reuse Governance SC de facto standards when possible.
  • 🚨 Be extremely careful with SC upgrades via governance.
  • Security audit market exploded, but the customer should be first.

🤝 Stronger together

In Babylon Finance, we believe in a stronger DeFi security community if we share best practices and lessons learned among all protocols.

In this post we provide some security recommendations based on current knowns but also unknowns of Beanstalk farm’s $180M hack which is still under investigation.

We hope that this post could contribute to the future setup of Beanstalk farms and their users.

🗳 Do not allow to vote retrospectively

The attacker was able to create, vote with super-power and execute a proposal as it instantly had super-majority voting power for it while doing a flashloan.

Governance should never allow to cast votes retrospectively or within the same block of the proposal creation using a different / new voting power from the one you had when the proposal was created. The reason is not only due to flashloans attacks but also to avoid people cheating with proposals during the voting period.

Always consider the voting power at least 1 block before it was created. For that, either the governance token or the governor should have checkpoints and get the voting power from an earlier block (block — 1) where “block” is the block of the BIP proposal creation.

Valid voting power must be prior to proposal creation (getPriorVotes used in Babylon Governor)

⚡️Flashloan resistance (DENY ALL unless allowed):

Security by design should consider flashloan resistance and other relevant attack vectors’ defenses.

We should always “deny all” type of flashloan behavior by default, unless it is explicitly allowed.

All operations that are calculated on chain and could depend on the same block state of play should be protected against them.

It probably sounds complex but it is very easy as explained by Igor Yalovoy 🧙 in this tweet.

After a quick look to the code, it seems that the team expected to have different actions as part of the same tx, for example the vote is cast by the proposer in the same tx while creating the proposal, which is not a good practice.

The proposer vote happens during the proposal creation

🕵️‍♀️ Every small change in the codebase matters

Invest in your own team security skills and processes, external audits are needed but they have limited scope and cannot follow dev team sprints’ pace as desired.

In this hack, Omniscia, explained in a post-mortem analysis that the vulnerability was not in the codebase when they audited the smart contract so we have to be careful to blame auditors before knowing what really happened.

On the other hand, we strongly recommend to evolve the current security audit ecosystem to deliver some kind of continuous security services, or at least to offer a lot more flexibility, more slots, better competitiveness and reduced prices, and better alignment with the high pace of development.

⏱ Time lock delay as a standard for governance

Compound Finance introduced in Governor Alpha and Bravo the timelock for governance proposals to introduce a delay on execution. It has been improved and replicated in OpenZeppelin Governor.

Compound Finance time lock for governance proposals

Privilege functions like ‘emergencyCommit’ for a governance proposal has demonstrated that de facto standards to queue and have a delayed execution are extremely important.

Pausing and halting are some “emergency” examples that cannot wait some days to be executed. But those are actually protecting the protocol not withdrawing from it. We should consider each function separately to see if roles are set accordingly to its associated risk.

Governance proposals anyway should have a delayed execution.

💻 Reuse Governance SC de facto standards when possible

They are risk minimized. They are not only audited and battle tested by several protocols but you can also expect some kind of versioning in the future with new tested improvements.

This is the best use case to reuse code, there should be an important reason for not doing it. However it is worth mentioning that governors are necessary but not enough.

Actually your governance token should use checkpoints to be able to handle specific voting power for specific users along the time. Probably this is an oversight, after a quick look to the BEAN token code I see no checkpoints.

As an example from Babylon Finance, the governance token BABL uses checkpoints and uses getPriorVotes from the governor to check specific position in specific (past) block:

Governance token checkpoints

We are not 100% sure yet although the emergencyCommit was probably introduced after the audit. If the governance token does not have checkpoints, it is an oversight.

🚨 Be extremely careful with SC upgrades via governance

Upgrading SC via governance is a great option however a bug like this brings the famous RCE (Remote Code Execution) into the scene.

RCE is probably the most dangerous vulnerability as if the attacker manages to replace the code by introducing its own malicious code, it can execute whatever he wants unfortunately.

⚔️ Security audit market exploded, but the customer should be first

We understand that audit firms do not want to be exposed by an unnoticed bug causing a hack like this, but neither do customers which are actually spending tons of dollars from their runway budget in security audits.

Customer should be first.

In Babylon we believe that 100% security does not exist however the team should have security skills as well as internal security processes to be completed by external security audits.

So the team should at least have the possibility to run continuous security audits for free (internal security audits).

Conclusion

As a conclusion, we should never underestimate our enemies as they will always find the weaknesses. We should definitively know our infrastructure better than our enemies.

“If you know the enemy and know yourself, you need not fear the result of a hundred battles. If you know yourself but not the enemy, for every victory gained you will also suffer a defeat. If you know neither the enemy nor yourself, you will succumb in every battle”

— - “Sun Tzu said in The Art of War” — -

We wish to all users, team and all partners involved in the incident the best of luck. We believe that there are still some opportunities to recover some funds.

If you are interested to build together a stronger security community, please reach out 👋, and let’s chat about it on our own Discord

🛡🛡🛡🛡

If you haven’t had a chance to use Babylon yet, please head to the website and take a look. We already launched publicly!.

You can join our discord community here.

--

--

Raul Riesco
Babylon.finance

Disclaimer: Opinions or messages expressed here are solely my own and do not express the views or opinions of my employer