Platform: Code4rena
Start Date: 05/07/2023
Pot Size: $390,000 USDC
Total HM: 136
Participants: 132
Period: about 1 month
Judge: LSDan
Total Solo HM: 56
Id: 261
League: ETH
Rank: 73/132
Findings: 4
Award: $172.99
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: GalloDaSballo
Also found by: 0xfuje, KIntern_NA, SaeedAlipoor01988, gizzy
101.7807 USDC - $101.78
https://github.com/Tapioca-DAO/tapioca-periph-audit/blob/023751a4e987cf7c203ab25d3abba58f7344f213/contracts/Swapper/UniswapV3Swapper.sol#L38 https://github.com/Tapioca-DAO/tapioca-periph-audit/blob/023751a4e987cf7c203ab25d3abba58f7344f213/contracts/Swapper/UniswapV3Swapper.sol#L184
Uniswapv3swapper uses hardcoded poolFee to make a swap. though it can be changed but is not reliable as swap can happen most often. This can result to a swap being conducted in a pool with little liquidty and with a high price impact.
The swap always uses the state varible poolfee. pool like stable pairs with most liquid pool is 100 fee will excuted at a high price impact rate.
manuel review
using uniswapv3 should provide poolfee as data or make calculation for most profitable rate.
Uniswap
#0 - c4-pre-sort
2023-08-06T16:27:31Z
minhquanym marked the issue as duplicate of #270
#1 - c4-judge
2023-09-19T18:14:07Z
dmvt marked the issue as satisfactory
🌟 Selected for report: Madalad
Also found by: 0xStalin, 0xTheC0der, 0xfuje, Topmark, Vagner, cryptonue, gizzy, peakbolt, rvierdiiev
30.0503 USDC - $30.05
In magneter v2 the burst loops and calls all specified calls . when one calls TOFT_WRAP with an msg.value greater than 0 . the burst doubles charges them that amount or will fail if not sent
function burst( Call[] calldata calls ) external payable returns (Result[] memory returnData) { uint256 valAccumulator; uint256 length = calls.length; returnData = new Result[](length); for (uint256 i = 0; i < length; i++) { Call calldata _action = calls[i]; if (!_action.allowFailure) { require( _action.call.length > 0, string.concat( "MagnetarV2: Missing call for action with index", string(abi.encode(i)) ) ); } unchecked { valAccumulator += _action.value; } if (_action.id == PERMIT_ALL) { _permit( _action.target, _action.call, true, _action.allowFailure ); } else if (_action.id == PERMIT) { _permit( _action.target, _action.call, false, _action.allowFailure ); } else if (_action.id == TOFT_WRAP) { WrapData memory data = abi.decode(_action.call[4:], (WrapData)); _checkSender(data.from); if (_action.value > 0) { //@audit adds msg.value twice. unchecked { valAccumulator += _action.value; } ITapiocaOFT(_action.target).wrapNative{ value: _action.value }(data.to); } else { ITapiocaOFT(_action.target).wrap( msg.sender, data.to, data.amount ); }
The burst funcntion loops and adds each _action.value to valAccumulator at the begining before any call. when TOFT_WRAP if amoung the calls is trigger from if else with _action.value >0 it adds _action.value again to valAccumulator making it bigger and expects at the very end that both eth where sent to call. if not sent it fails. https://github.com/Tapioca-DAO/tapioca-periph-audit/blob/023751a4e987cf7c203ab25d3abba58f7344f213/contracts/Magnetar/MagnetarV2.sol#L194C1-L715C6
MagnetarV2 sendFrom() should test toft wrap.: Error: VM Exception while processing transaction: reverted with reason string 'MagnetarV2: value mismatch'
Manuel review
remove unchecked { valAccumulator += _action.value; }
as it already added it before the call
Error
#0 - c4-pre-sort
2023-08-06T01:54:08Z
minhquanym marked the issue as duplicate of #207
#1 - c4-judge
2023-09-21T12:54:52Z
dmvt changed the severity to 2 (Med Risk)
#2 - c4-judge
2023-09-21T13:06:09Z
dmvt marked the issue as satisfactory