How can we protect against smart contract exploits?

Tara Annison
5 min readJul 7, 2023

So far this year there’s been over $410m stolen from dApp exploits and bridge attacks alone ( https://web3isgoinggreat.com/) and the running total stands at more than $3billion. This represents dastardly hackers taking advantage at the protocol level and finding backdoors, unexpected contract behaviours and using tricks such as flash loan attacks to drain smart contract held funds. There are of course many other crypto crime typologies that illicit actors use but today we’re going to focus on those where the attacker acts at the smart contract level.

Let’s consider some recent examples:

  • Earlier this week the PolyNetwork was hit AGAIN by an exploit. Initially they lost $600m when an attacker found a vulnerability in how the various DeFi smart contracts communicated and after some dramatics returned the majority of the funds and were even offered a role as chief security officer. More recently an attacker found a flaw in PolyNetwork bridge functionality and managed to mint $4bn worth of tokens. Luckily there wasn’t sufficient liquidity for them to exit with all these funds, but they did manage to pocket ~10m.
  • In June this year, just 11 days after launching, the lending dApp Themis Protocol was exploited for ~$370,000. The attacker spotting a faulty price oracle and used a flash loan to manipulated the LP token price by exchanging tokens within the Balancer pool. The Sturdy Finance lending dApp saw a similar fate with $775,000 exploited through oracle manipulation.
  • In May, Deus Finance was hacked for not once, not twice but the third time! Attackers managed to syphon around $7m from the protocol using a basic implementation error in the DEI stablecoins token contract. Luckily the majority of funds were returned after white hat action but this illustrates another example of an attacker finding a flaw in the code and using it to run off with funds.

In the majority of cases the criminals drain the funds at lightning speed, and by the time the projects know that something is happening it’s already too late for them to act.

One potential solution to these exploits could be to simply write code which doesn’t have vulnerabilities in. However, as succinctly put by Tony Hoare, a British computer scientist

“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies.”

With the inherently complex nature of building dApps the former certainly seems to be ruled out. So instead we’re left with a situation where we need to try to mitigate the impact of bugs in the code.

One potential solution being discussed in the Ethereum community to help prevent the drainage of funds is ERC-7265, being referred to as a “circuit breaker” for DeFi projects. The standard allows configurable rate limits per asset to be set and, if hit, allows further conditions to be set on any subsequent outflow. This could be a temporary halt, sending funds to an emergency vault or a revert on the attempted flows. Therefore if an attack does happen, only a limited portion of assets can be moved out at once and teams then have sufficient time to react and respond.

Consider the scenario in which the circuit breaker standard might be integrated into a DEX:

Let’s say the DEX has two pools of assets a user can contribute liquidity to or swap assets via

Pool 1: WETH and USDC

Pool 2: USDC and BAT

Pool 1 has 100 WETH and 20,000 USDC

Pool 2 has 300 USDC and 2,000 BAT

Using the circuit breaker standard the DEX can register the 3 assets to be protected and set threshold metrics for when the rate limit will be triggered. This could be for a nominal amount e.g if more than 30 WETH is attempted to be transferred out of the pool, percentage based e.g if more than 75% of BAT is attempted to be transferred out of the pool or even more complex conditions e.g if more than 75% of WETH in a 4 hour period is attempted to be transferred then trigger the circuit breaker.

Once this circuit breaker is hit the funds can be temporarily locked and then be moved into a specified account using the `migrateFundsAfterExploit(` function — this is likely to be a multisig or DAO controlled account, or unlocked for active usage again using the `claimLockedFunds` function.

It’s also possible to override the rate limit and avoid the subsequent actions in the case that a false positive situation has been hit. This would be done by calling the function `overrideExpiredRateLimit()`. Another similar protection mechanism is the `startGracePeriod(uint256 _gracePeriodEndTimestamp)` function which allows a window of time to be set in which the rate limits are not active. This could be useful when the dApp is new and building up liquidity, and so where there’s more volatility in inflow and outflow.

A notable point here is that this configurability must be done by an `admin` as defined in the circuit breaker contract. So if an attacker is able to compromise the admin credentials or switch themselves into the admin role then they can withdraw locked funds, set grace periods, register asset parameters, update asset parameters, set new admin, override rate limit, add protected contracts, and remove protected contracts. Thereby bypassing all of the intended protections from the circuit breaker! The standard therefore suggested setting the admin/s as the governance contract for the dApp to avoid centralization points of failure but DAOs would still need to be wary of governance attacks that could seek to take over and make unilateral changes.

You can take a read of the full proposal here: https://github.com/ethereum/EIPs/pull/7265/commits/21efbbc92f973943fbe522f56d27fb2a8573c258

It’s worth noting that there’s nothing to stop dApps building in protections such as this into their smart contracts without explicitly making use of ERC-7265. In fact MakerDAO already has an “Emergency Shutdown” function which if activated will freeze all prices from oracles, allow all DAI to be redeemable for a fixed amount of collateral, allow all CDPs to be liquidated and halt any further loans from being originated.

Likewise Compound has an “emergency pause” feature which can be activated to halt protocol actions such as new loans, although notably it requires consensus from COMP governance holders to be activated.

However ERC-7265 is aiming to be a simple plug and play standard which existing dApps can upgrade to use (likely requiring a governance vote) and which can become the established and trusted way of preventing exploits which drain funds and harm users. Time will of course tell whether this gets adopted but it’s certainly a solid step forward to try to think about how users can be protected from the stream of exploits which are seeing billions of dollars being stolen and whole dApps being wiped out the market.

Originally published at https://www.linkedin.com.

--

--