Hey there, blockchain builders! I am Davi Bauer, an On-Chain Security Researcher with extensive experience in software development and a strong background in Solidity programming and EVM networks. Today, I want to discuss the KyberSwap Hack and how Extractor’s upgraded Attack Prevention mechanism could have prevented it.
The November 2023 KyberSwap crypto hack resulted in a loss of approximately $48 million across all chains. The attacker deposited funds into wallets from mixers (such as tornado cash and fixed float).
The attack in question involved intricate asset price manipulation targeting a specific area of the liquidity curve, making it exceedingly challenging to track manually. Yet, thanks to advancements in post-deployment security research and development, Hacken Extractor can now automatically detect and prevent such sophisticated hacks.
At the core of the KyberSwap hack lies an exploit involving price tick manipulation and double liquidity counting. Here’s a simplified explanation of how the attacker executed the exploit:
The attacker planned the attack, ensuring that the funds’ source was obfuscated through mixers and decentralized exchanges. Here’s a breakdown of the flow of funds on the Ethereum Network.
The KyberSwap hack led to significant financial losses across six different chains, totaling over $48 million in stolen assets. Additionally, the platform’s Total Value Locked (TVL) dropped by 68% within a few hours, indicating a severe loss of user trust and liquidity.
To illustrate how Extractor can prevent such incidents, I’ll walk you through a detailed setup process.
Based on the flow of funds, I will approach the setup in two ways
To achieve that, I will fake the KyberSwap pool contract but with additional methods, including pause() and addToDenyList(account), so that the Extractor can pause these contracts as soon as a critical balance drop alert is detected on the Ethereum network or add an account to the deny list as soon as a suspicious account alert is detected on the monitored contract.
The first step is to focus on one of the actual KyberSwap pool contracts. For this setup, I’m going to use the KyberSwap (WETH) pool contract so that we can monitor this contract on the Ethereum network. So, let’s add it to Extractor for monitoring.
Next, I will add three more contracts that will be monitored. These contracts can exist on the same or in a different network. In this scenario, I’m adding contracts deployed on the Anvil network for the sake of the simulation.
Figure: Adding the first copy of the KyberSwap contract on Anvil.
Once the first one was added, I followed the same steps for the other two, but with different contract addresses. After all contracts are added, it’s time to configure the Actions.
For configuring the actions, I will select each of the KyberSwap fake contracts I added earlier on the Anvil network to create an action based on a critical event triggered by the KyberSwap contract on the Ethereum network. Here, I will set up a pause() method to be executed in response to this critical event, simulating an immediate response action to an attack that happened in the real contract.
Here is the final configuration:
The same configuration was done on the two additional contracts because we aim to pause all the tree contracts at the same time when the Balance Monitor on the KyberSwap (ETH) contract triggers a critical alert.
For that scenario, I will create an action on each of the contracts that will get the suspicious address information from the alert triggered and then pass this data as a parameter to the addToDenyList method of the smart contract pool.
Again, the same configuration was done in all the other contracts that are being monitored so that we can protect each of them independently of the network.
For prevention to work, all actions must be created, and now we need to replay the same transactions that occurred on the day of the attack on KyberSwap contracts.
So that transactions could be executed, we used an internal tool to replay the transactions, simulating precisely what happened on the day of the attack.
After that, it’s time to see if the attack was detected on the Ethereum contract. This information is under the “Alerts” tab. As we can see in the following image, the detector triggered the alert correctly, with the critical severity level.
Clicking on the details of the Balance Monitor alert reveals additional information about the detection, including the transaction hash, drop percentage, token address (in this case, WETH), previous and current balance, and the event description.
Now, clicking on the details of the Suspicious account alert, we will have additional information, including the most important one, the suspicious address.
Based on everything we’ve done, we can now check to see if the action was triggered once the criteria for triggering them have already been met. If everything went well, a pause action on the contract should have been triggered for each of the three contracts that were added to the Anvil network.
When we check the first one, we can see that a pause action was executed, as we can see on the “Executions” tab.
The AddToDenyList method was also executed because the suspicious account detector triggered a high alert, indicating that this account sent a transaction against the monitored contract. The same happens for the second and the third contracts, according to our actions configuration.
We used three different detectors to spot this attack.
In the initial phase of the attack, the Suspicious Address Detector identified the first suspicious account. This account was flagged due to its funding source, which was a known mixer (Tornado Cash). The involvement of crypto mixers often indicates attempts to obscure the origin of funds, making these accounts suspects for further attack.
Next, Extractor identified a second suspicious account. This account was flagged because its funds originated from the first suspicious wallet. This chain of transactions indicated a deliberate attempt to launder the funds further before deploying them for the attack.
Extractor also flagged a suspicious contract deployed by the second suspicious account. This contract, being deployed by a wallet already marked as suspicious, was automatically flagged.
And finally, the drop in the balance is identified. Here, we can see several things happening together. We can see the wallet used to execute the contract and launch the attack, the suspicious contract, the monitored contract (the KyberSwap pool), and the monitored token (WETH). Next, the information on the current balance and the previous balance (of the prior block) shows a difference of almost 3,000 WETH, which, at the time, in November last year, was equivalent to approximately 7.5 million dollars. Finally, the drop in percentage reached a 99 percent decrease in balance for this pool.
Finally, how could Extractor help save funds or prevent a bigger loss?
In the case of the KyberSwap hack, Extractor could have identified the attack through its Suspicious Account, Suspicious Contract, and Balance Monitor Detectors, acting with a:
Given that the total loss was $48 million, with nearly $8 million lost on the Ethereum network alone, an estimated $40 million could have been saved if immediate pause action had been taken based on the attack identification through our detectors and potentially all funds could have been saved if a deny list action had been applied.
I invite every smart contract developer to learn more about post-deployment security. Check out our documentation or test Extractor with our one-month free trial at – https://extractor.live/
Be the first to receive our latest company updates, Web3 security insights, and exclusive content curated for the blockchain enthusiasts.
Tell us about your project
3 min read
Case Studies
6 min read
Case Studies
7 min read
Case Studies