Decoding Sentiment Protocol’s $1 Million Exploit | QuillAudits
What a great time to be in the DeFi space! Another day, another million-dollar exploit.
On April 4th, the Sentiment Protocol on the Arbitrum Chain experienced an attack due to a read-only reentrancy vulnerability. The attackers exploited this vulnerability, stealing approximately $1 million. Fortunately, the attacker returned around 90% of the stolen funds.
Sentiment is a liquidity protocol on the Arbitrum Chain that allows for on-chain, permissionless, undercollateralized borrowing. Similar to existing DeFi lending markets, Sentiment lenders supply capital, which is then loaned to borrowers as debt.
To learn more about the sentiment, check out the official documentation.
Vulnerability Analysis & Impact:
Attacker Address: 0xdd0cdb4c3b887bc533957bc32463977e432e49c3
Attacker Contract: 0x9f626f5941fafe0a5b839907d77fbbd5d0dea9d0
Victim Contract: 62c5aa8277e49b3ead43dc67453ec91dc6826403
Attack Transaction: 0xa9ff2b587e2741575daf893864710a5cbb44bb64ccdc487a100fa20741e0f74d
The Root Cause:
The root cause is a view-only reentrancy bug exposed in balancer pools when removing liquidity with one of the return tokens being ETH. Since the entry point is a non-mutating
view call it cannot be protected by a reentrancy guard, allowing the caller to take control of execution and run arbitrary code. The attacker was able to execute a malicious contract before updating the pool balances. This allowed them to steal funds by using overpriced collateral.
Check out this blog for more information on the balancer's vulnerability.
- The attacker began by taking out a flash loan of 606 WBTC, 10,130 WETH, and 18 million USDC tokens from the sentiment lending pool.
- The attacker initiates the attack by calling the
joinPool()function of the Balancer Vault to make a deposit. After this, they call
exitPool()to withdraw their funds. During the withdrawal process, the Balancer Vault triggers the fallback function of the attack contract.
- In the fallback function, the attacker calls the borrow function of the 0x62c5 Proxy contract. This function calculates the price based on the return data from Balancer Vault.getPoolTokens(). As a result, the total supply of LP tokens decreases, but the recorded balances of the tokens in the pool are not updated. This causes the token prices to become imbalanced, allowing the attacker to borrow multiple assets at a lower price.
- Finally, the attacker returned the borrowed funds, along with premiums, and made a profit of approximately $1 million. The attacker bridged the funds from Arbitrum Chain to Ethereum. See here.
The flow of Funds:
The hacker returned $900,000 (90%) to the protocol and kept the rest as a bounty. They transferred the bounty to Tornado Cash.
05.04.2023: The sentiment team announced the hack through a tweet. The contract was paused to prevent further losses. They also announced that they are working with authorities and security firms to secure funds, recover stolen assets, and investigate the exploit.
05-04-2023: The team offered a $95K reward to the hacker if they returned the assets by 8 AM UTC on April 6. Otherwise, the reward will be given to anyone with relevant information about the hacker.
06-04-2023: The Sentiment team announced that they successfully negotiated with the exploiter to return 90% of the hacked funds. A few hours later, they released a statement saying that they had recovered $900,000 from the exploit.
07-04-2023: Sherlock paid out $50K, which is 75% of the remaining losses after the hacker returned 90% of the funds. They further stated that they would claim the last 25% of the loss with their partner, NexusMutual.
8–04–2023: The Sentiment team announced that they had recovered 100% of the funds from the exploit.
11–04–2023: They released a brief summary of the exploit and how they overcame it, restoring the protocol to 100% solvency and full capacity.
How they could have prevented the Exploit?
When developing smart contracts, it is crucial to consider integrations and security solutions that are relevant to the project. To mitigate this issue, it is recommended to use Balancer’s VaultReentrancyLib. By calling
ensureNotInVaultContext(vault), a noop call to the vault is performed, which will fail if an attacker attempts a read-only reentrancy attack.
For more details on mitigating this vulnerability, see here.
Reproducing the hack:
We will be using the Foundry framework for POC.
(Add the Arbitrum Mainnet RPC URL in
foundry.toml file and run the test using the command
forge test -vvv)
Similar projects secured by QuillAudits:
Web3 security- Need of the hour
Why QuillAudits for Web3 Security?
QuillAudits is well-equipped with tools and expertise to provide cybersecurity solutions, saving the loss of millions in funds.
Want more such security blogs and reports?
Connect with QuillAudits on:
Linkedin | Twitter | Website | Newsletter | Discord | Telegram