Open code423n4 opened 1 year ago
This is an expected behavior. It makes swaps calldata portable and Router-agnostic, which allows to seamlessly migrate to a new Router. This was initially introduced in Uniswap V3: https://github.com/Uniswap/v3-periphery/commit/a0e0e5817528f0b810583c04feea17b696a16755
It also gives a chance to withdraw tokens thanks to the public sweepTokens
function:
https://github.com/code-423n4/2022-12-Stealth-Project/blob/main/router-v1/contracts/Router.sol#L70
Otherwise, tokens would've been sent to the zero address and lost forever.
This is clearly a design feature to use recipient = address(0)
to have funds transferred to the Router
. I'm going to mark this as a QA.
kirk-baird changed the severity to QA (Quality Assurance)
kirk-baird marked the issue as grade-b
Lines of code
https://github.com/code-423n4/2022-12-Stealth-Project/blob/main/router-v1/contracts/Router.sol#L132-L140 https://github.com/code-423n4/2022-12-Stealth-Project/blob/main/router-v1/contracts/Router.sol#L122
Vulnerability details
Impact
If user calls Router.exactInputSingle swap with params.recipient == 0 by mistake, all swapping funds will be sent to Router and anyone can claim them to himself.
Proof of Concept
Router.exactInputSingle function calls exactInputInternal function and pases recipient param. https://github.com/code-423n4/2022-12-Stealth-Project/blob/main/router-v1/contracts/Router.sol#L121-L129
As you can see if recipient is 0, then it is set to address(this). That means that receiver of trade will be Router. Router contract has several methods that allow anyone to transfer controlled by Router tokens to himself, like refundETH, sweepToken, unwrapWETH9. https://github.com/code-423n4/2022-12-Stealth-Project/blob/main/router-v1/contracts/Router.sol#L70-L77
No restrictions here, so anyone can call.
This creates possiblity that after user will make exactInputSingle swap with recipient 0 address and in another tx will try to sweep those tokens, someone will frontrun user and will send tokens to himself. User will lost swapped funds.
This test will show that if recipient is 0 then after the swap Router controls swapped tokens. You can run it inside Router.ts.
Tools Used
VsCode
Recommended Mitigation Steps
Add check to exactInputSingle and exactOutputSingle that params.recipient is not 0.