depositAndTrade function seems to be incomplete - the tokenOutput from _swapRouter is currently owned by DepositTradeHelper account and needs to be transferred back to msg.sender who initiated this transaction. Since this contract doesn't seem to be part of core contracts of protocol (although listed in audit scope), I've marked it as MEDIUM risk.
Current implementation does not use return value of _swapRouter.exactInputSingle() in line 33. As per UniswapV3 docs, exactInputSingle function returns a token output value amountOutput as below
function exactInputSingle(
struct ISwapRouter.ExactInputSingleParams params
) external returns (uint256 amountOut)
Since such tokens rightfully belong to msg.sender, a transfer of the said token needs to be implemented to complete the loop (with a nonReentrant) modifier
Proof of Concept
Bob signs a offchain message to approve USDC in his wallet to be spent by DepositTradeHelper. Contract executes depositAndTrade function to swap out USDC for long/short tokens of say SpaceX prePO. Bob does not see the tokens in his wallet even after successful execution of the transaction
Tools Used
Recommended Mitigation Steps
Helper should complete the loop -> by transferring tokens returned by Uniswap V3 router to msg.sender. Consider code below as a suggested replacement for Line 33 in existing code base
uint256 tokenOutput = _swapRouter.exactInputSingle(exactInputSingleParams); // amountOut output is not used
if (tokenOutput > 0) {
bool success = IERC20(tradeParams.tokenOut).transfer(msg.sender, tokenOutput);
require(success, "swapped token transfer failed");
}
Not to forget, this function needs to use the nonReentrant modifier
Lines of code
https://github.com/prepo-io/prepo-monorepo/blob/3541bc704ab185a969f300e96e2f744a572a3640/apps/smart-contracts/core/contracts/DepositTradeHelper.sol#L33
Vulnerability details
Impact
depositAndTrade
function seems to be incomplete - the tokenOutput from_swapRouter
is currently owned byDepositTradeHelper
account and needs to be transferred back tomsg.sender
who initiated this transaction. Since this contract doesn't seem to be part of core contracts of protocol (although listed in audit scope), I've marked it asMEDIUM
risk.Current implementation does not use return value of
_swapRouter.exactInputSingle()
in line 33. As per UniswapV3 docs,exactInputSingle
function returns a token output valueamountOutput
as belowSince such tokens rightfully belong to
msg.sender
, a transfer of the said token needs to be implemented to complete the loop (with a nonReentrant) modifierProof of Concept
Bob signs a offchain message to approve USDC in his wallet to be spent by
DepositTradeHelper
. Contract executesdepositAndTrade
function to swap out USDC for long/short tokens of saySpaceX prePO
. Bob does not see the tokens in his wallet even after successful execution of the transactionTools Used
Recommended Mitigation Steps
Helper should complete the loop -> by transferring tokens returned by Uniswap V3 router to msg.sender. Consider code below as a suggested replacement for Line 33 in existing code base
Not to forget, this function needs to use the
nonReentrant
modifier