Author Piyush shukla
Date of Incident: January 14, 2025
Loss: Approximately $340,000 in stETH
The Idols NFT project on Ethereum was exploited due to a flaw in its smart contract. This vulnerability allowed an attacker to repeatedly claim staking rewards (stETH) by transferring an NFT to themselves multiple times. Here’s a detailed breakdown of the Idols NFT 340k Exploit:
The Root Cause
The exploit stemmed from flawed logic in the _beforeTokenTransfer function. This function mishandled reward claims during NFT transfers, particularly when the sender (_from) and receiver (_to) were the same address.
How the Vulnerability Worked
Claim Rewards for the Sender:
When _beforeTokenTransfer was called, it first triggered _claimEthRewards(_from) to claim the sender’s pending rewards. The rewards were calculated using the formula:Rewards = (Sender’s NFT Balance) * (Reward Per NFT - Previously Claimed Rewards)
Reset Reward History:
If the sender’s NFT balance became zero after the transfer (balanceOf(_from) == 1), their reward history (claimedSnapshots[_from]) was deleted.
- Claim Rewards Again for the Receiver:
Since _from and _to were the same address during a self-transfer, _claimEthRewards(_to) was triggered next. With the reward history for _to reset, the contract recalculated rewards as though they had never been claimed, allowing the attacker to claim rewards again. - Repeat the Process:
By transferring an NFT to themselves repeatedly, the attacker was able to reset their reward history and claim rewards multiple times.
Attack Flow
- The attacker initiated an NFT transfer where _from == _to, triggering _beforeTokenTransfer.
- _claimEthRewards was called for the sender (_from), and rewards were claimed based on the pending stETH balance.
- claimedSnapshots[_from] was deleted due to the if(balanceOf(_from) == 1) check.
- _claimEthRewards was called again for the receiver (_to), which was the same address as _from.
- The attacker repeated this process 87 times, draining stETH rewards.
- Each transaction drained approximately 1.11 stETH from the treasury.
Total Loss: Approximately 97 stETH (~$340,000).
The Idols NFT Team’s Response
The team identified suspicious transactions on the Idols Main contract and is thoroughly exploring all available options to resolve the situation as quickly as possible while ensuring the project’s security.
Key Vulnerable Code
Here’s a simplified version of the problematic code:
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override {
// Step 1: Delete reward history for the sender and receiver
delete claimedSnapshots[from];
delete claimedSnapshots[to]; // Step 2: Claim rewards for sender and receiver
_claimRewards(from);
_claimRewards(to);}
The Flaw
When from == to (self-transfer), the reward history was deleted twice. This caused the contract to “forget” previously claimed rewards, enabling the attacker to claim them repeatedly.
Mitigation and Best Practices
- Add a check to block or skip reward calculations during self-transfers (_from == _to).
- Ensure the sender’s reward history is only reset if the NFT is actually being transferred out (i.e., balanceOf(_from) == 0).
- Always test unusual scenarios, like self-transfers, during smart contract development and audits.
- Attack Transactions: 0xd9870, 0x5e989, 0x2bda7, 0x45bf5, 0x14ae4, 0x1a595, 0x45d93, 0xa8289, 0xa194e, 0xa64b6, 0x1aaa3, 0x61092, 0xbffcf, 0x9ac08
- Attacker’s Address: 0xE5464
- IDOL Contract Address: 0x439ca
Protocol Actions
- The Idols NFT team paused all transactions immediately.
- Users were warned not to interact with the contract until further notice.
- The team pledged to fix the bug and refund affected users.
Streamline your smart contract audits with Bunzz Audit! Combining cutting-edge AI with expert human review, we deliver faster, more affordable audits than traditional methods. Ready to secure your contracts? Request a free quote today!