Closed code423n4 closed 1 year ago
The refundETH()
is exposed with that case in mind, isn't it? If a user sends ETH by mistake, he can call refundETH()
to get it back.
There are a few issues raised here:
1) There are unnecessary payable
s. This is a gas optimization. https://medium.com/coinmonks/deciphering-solidity-does-adding-a-payable-keyword-actually-save-gas-89d1d8298d3f
2) "Anyone can call refundETH to sweep ETH for free". This is the intended behavior and is a dup of https://github.com/code-423n4/2022-12-Stealth-Project-findings/issues/30
gte620v marked the issue as sponsor disputed
gte620v marked the issue as disagree with severity
I disagree with the severity as these are deliberate gas optimisations and require significant user error to exploit.
However, I do agree with the warden that the gas optimisation is not worth the security risk of users accidentally sending funds. I will therefore consider this QA.
Lines of code
https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/router-v1/contracts/libraries/SelfPermit.sol#L16 https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/router-v1/contracts/libraries/SelfPermit.sol#L21 https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/router-v1/contracts/libraries/SelfPermit.sol#L26 https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/router-v1/contracts/libraries/SelfPermit.sol#L31 https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/router-v1/contracts/Router.sol#L59 https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/router-v1/contracts/Router.sol#L70 https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/router-v1/contracts/Router.sol#L80
Vulnerability details
Impact
Certain function should not be marked as payable, otherwise if user accidentally attach ETH in the function call, the ETH is lost.
Proof of Concept
There are a few function that should not be marked payable
The Router contract inherits from SelfPermit.
all function is SelfPermit should not be payable:
the function in the SelfPermit contract let user sign a signature offchain and use the signature to take allowance, the only purpose is to set allowance, so these functions should not be marked as payable.
In Router.sol, the function unwrapWETH9 and sweepToken and refundETH should not be marked as payable because these function are only desigend to resuce token stucked in the router.
for addLiqudity related function in Router, the function should wrap the ETH to WETH for msg.sender, it is just two ERC20 token pair, the function should not be marked as payable.
given that the code does not refund any excessive ETH sent to the contract,
Anyone can call refundETH to sweep ETH for free.
Then if user accidentally attach ETH in the function call to payable function that should not be marked as payable, the ETH is lost.
Tools Used
Manual Review
Recommended Mitigation Steps
We recommend the project remove payable keywords for functions that do not need the payable keywords and refund excessive ETH.