The simpleSwap() function take the SimpleData type as a paramter. However, incorrect validation of the SimpleData type in the swap() and _validateCallData() functions in the ParaSwapUtils will make all swaps failed.
The ParaSwapUtils library intends to perform swapping operations via Paraswap.
If we check the contract 0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57 in Arbitrum and Avalanche, the swapSimple() functions of the swapper takes a single SimpleData struct parameter.
Therefore, the callData in the ParaSwapUtils::swap() function should match with the abi.encodeWithSelector(<Swapper.simpleSwap.selector>, <SimpleData type variable>).
However, callData doesn't match with the SimpleData type at all.
fromToken is being taken from offset 68 which should be from 4.
fromAmount is being taken from offset 100 which should be from 68.
receiver(beneficiary in SimpleData type) is being taken from offset 196, but it's calculation is more complex to calculate.
DEX swapping won't work at all.
Manual Review
Update parsing the callData parameter to match with SimpleData type.
Keepers use megaSwap with this struct: struct MegaSwapSellData { address fromToken; uint256 fromAmount; uint256 toAmount; uint256 expectedAmount; address payable beneficiary; Utils.MegaSwapPath[] path; address payable partner; uint256 feePercent; bytes permit; uint256 deadline; bytes16 uuid; } 32 first bytes of callData bytes array → length of the bytes array. 4 bytes selector, 32 bytes → offset of the struct → 68 bytes before the fromToken.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.