XLinkedInTelegram
Hack Analysis

Sorra Finance Staking Exploit: How a $41K Hack Drained 3M SOR Tokens

A critical flaw in the Sorra staking contract allowed an attacker to repeatedly withdraw the same rewards, draining 3M SOR tokens. Here’s how it happened.

Author
QuillAudits Team
June 20, 2025
Sorra Finance Staking Exploit: How a $41K Hack Drained 3M SOR Tokens
XLinkedInTelegram

What Went Wrong? The Sorra Staking Exploit Story

On January 4, 2025, the Sorra Staking contract was exploited due to flawed logic in the getPendingRewards() function, which failed to track and deduct previously distributed rewards, enabling repeated withdrawals of the same rewards. The attacker, who had deposited 122,868 SOR tokens on December 21, 2024, exploited this flaw to drain 3,071,721 SOR tokens and profit approximately $41,000.

In a Nutshell: The Attack in Brief

On January 4, 2025, the Sorra staking contract was exploited due to flawed logic that did not account for whether the user had already withdrawn their rewards. This highlights how even seemingly straightforward mechanisms, like those in a prime number staking contract—can become vulnerable without proper validation checks.

The attacker prepared for this attack by depositing 122,868 SOR tokens into the staking contract 14 days earlier, on December 21, 2024, and selecting a lockup period of 14 days.

The attacker took advantage of the getPendingRewards() function, which failed to properly track and deduct previously distributed rewards, allowing repeated withdrawals of the same rewards.

As a result, the attacker repeatedly called the withdraw()function, ultimately draining 3,071,721 SOR tokens and profiting approximately $41,000.

How Did This Go Down?

Attacker Address: 0xdc8076

Attack Transaction: 0x6439d

Vulnerable Contract: 0x5d16b

Attacker Contract Address: 0xFa3925, 0xB575b

Step-by-Step Breakdown:

The attacker prepared for the exploit on December 21, 2024, by depositing 122,868 SOR tokens into the staking contract.

image.png

According to the contract logic, the lockup periods vary by tier: tier 0 requires a 14-day wait, tier 1 requires 30 days, and tier 2 requires 60 days. The attacker chose tier 0, resulting in a 14-day lockup period.

image.png

On January 4, 2025 (exactly 14 days after the deposit), the attacker initiated the exploit by calling the withdraw()function.

The withdraw() function allows users to withdraw a specified _amount of their staked tokens, calculates and distributes any pending rewards, updates the user's position, and transfers both the staked tokens and rewards (if applicable) to the user.

image.png

The getPendingRewards() function calculates the pending rewards for the msg.sender. In this case, it returned 6,143 SOR tokens.

image.png

When rewardAmount > 0, the contract updates userRewardsDistributed[_msgSender()] with the rewardAmount. However, due to a flaw in the logic, the calculation of the user's pending rewards does not properly account for the userRewardsDistributed[_msgSender()].

This oversight means there is no record or proof that the user has already withdrawn their rewards. As a result, the attacker was able to repeatedly call the withdraw() function with 1 Wei token.

image.png

The attacker ultimately withdrew 3,071,721 SOR tokens through repeated calls and swapped them on UniswapV2, profiting approximately $41,000.

What Was the Root Cause?

The root cause of the exploit lies in the flawed reward distribution logic in the withdraw() function. Specifically, the calculation of pending rewards in getPendingRewards() did not properly account for userRewardsDistributed[_msgSender()], allowing the same rewards to be withdrawn repeatedly. This oversight enabled the attacker to exploit the contract by repeatedly calling withdraw() to claim excessive rewards and profit significantly.

Funds on the Move: Where Did the Money Go?

Take a look at the funds flow and track how the stolen tokens were moved across the blockchain.

image.png

How Do We Stop This From Happening Again?

  1. The getPendingRewards() function should have accounted for the userRewardsDistributed[_msgSender()] value when calculating pending rewards to ensure rewards are not double-counted.
  2. Comprehensive unit tests and simulations should have been conducted to verify that rewards and staking logic behave correctly under various scenarios.
  3. Collaborate with reputable audit firms like QuillAudits to analyse smart contracts and identify these type of vulnerabilities.
QuillAudits Team

QuillAudits Team

The QuillAudits team, comprises of expert security researchers & auditors in Web3 security, has completed 1,400+ audits across Ethereum, Polygon, Solana, Arbitrum, BSC, and more, securing $30B+ with 0 exploits, advancing the blockchain ecosystem.

TwitterLinkedInTelegram

Contents

Tell Us About Your Project
Request An Audit
Subscribe to Newsletter
hashing bits image
Loading...

STAY IN THE LOOP

Get updates on our community, partners, events, and everything happening across the ecosystem — delivered straight to your inbox.

Subscribe Now!

newsletter
DeFi SecurityplumeUniswap FoundationAethiropt-collectivePolygon SPNBNB Chain Kickstart

Office 104/105 Level 1, Emaar Square, Building 4 Sheikh Mohammed Bin Rashid Boulevard Downtown Dubai, United Arab Emirates P.O box: 416654

audits@quillaudits.com

All Rights Reserved. © 2025. QuillAudits - LLC

Privacy Policy