#44035 [SC-Low] Lack of validation in native transfer allows attacker to steal user funds
Submitted on Apr 16th 2025 at 08:37:05 UTC by @TECHFUND_inc for Audit Comp | Spectra Finance
Report ID: #44035
Report Type: Smart Contract
Report severity: Low
Target: https://github.com/immunefi-team/Spectra-Audit-Competition/blob/main/src/router/Dispatcher.sol
Impacts:
Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
Description
Brief/Intro
There is no require(success) or conditional check in Dispatcher.sol contract. This means failed transfers will go unnoticed.
When a native transfer fails (e.g., receiver contract has no receive() or fallback() function), the dispatcher does not check the result of the low-level call. This causes the ETH to remain stuck inside the protocol.
Because the protocol does not associate the ETH with the original sender or restrict who can call TRANSFER_NATIVE, any attacker can later call execute() and withdraw the stuck funds to their own address. This results in permanent loss of funds for the original user.
Vulnerability Details
Here is the code snippet taken from Dispatcher.sol contract where we have an issue
Attack flow
User sends ETH via dispatcher to a receiver contract but the receiver contract reverts due to some reasons.
Transfer fails and dispatcher transaction is successful, but dispatcher contract doesnt return funds.
ETH remains in the Spectra protocol.
Attacker later calls
execute()withTRANSFER_NATIVE, using their own address.Spectra Protocol sends the stuck ETH to the attacker through dispatch
Impact Details
Loss of funds for the user. Attacker can steal them
References
https://github.com/immunefi-team/Spectra-Audit-Competition/blob/1cebdc67a9276fd87105d13f302fd77d000d0c0b/src/router/Dispatcher.sol#L483
Proof of Concept
Proof of Concept
Filename: RouterTest1.t.sol
Function: testEtherTransfer()
Run this command forge test --match-contract RouterTest1 --mt testEtherTransfer -vvv
Here are the logs:
Was this helpful?