Platform: Code4rena
Start Date: 11/11/2022
Pot Size: $36,500 USDC
Total HM: 5
Participants: 62
Period: 3 days
Judge: berndartmueller
Id: 181
League: ETH
Rank: 43/62
Findings: 2
Award: $55.62
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: rotcivegaf
Also found by: 0x4non, 0xDecorativePineapple, 9svR6w, Trust, V_B, adriro, ajtra, aviggiano, brgltd, carlitox477, chaduke, codexploder, corerouter, joestakey, ladboy233, s3cunda, saian, wait
33.4034 USDC - $33.40
_returnDust doesn't check that the call has been sucesfully. For example, if the buyer is a contract could fail during the reception but due to _returnDust doesn't check the return value to revert the transaction in case of failure the tokens could be missed.
Manual reviewed
Check the return value callStatus
#0 - trust1995
2022-11-14T22:07:22Z
Dup of #185
#1 - c4-judge
2022-11-16T11:57:32Z
berndartmueller marked the issue as duplicate of #90
#2 - c4-judge
2022-11-16T11:58:19Z
berndartmueller marked the issue as partial-50
#3 - c4-judge
2022-12-06T14:17:26Z
berndartmueller changed the severity to 2 (Med Risk)
🌟 Selected for report: ReyAdmirado
Also found by: 0x4non, 0xRoxas, 0xab00, Awesome, Aymen0909, Bnke0x0, Deivitto, Diana, IllIllI, Rahoz, RaymondFam, Rolezn, Sathish9098, ajtra, aphak5010, aviggiano, c3phas, carlitox477, ch0bu, cryptostellar5, erictee, lukris02, martin, rotcivegaf, saian, shark, trustindistrust, zaskoh
22.2155 USDC - $22.22
Each extra memory word of bytes past the original 32 incurs an MSTORE which costs 3 gas
Exchange.sol#L49 Exchange.sol#L295 Exchange.sol#L604 Pool.sol#L63
In the following example (optimizer = 10000) it's possible to demostrate that I = I + X cost less gas than I += X in state variable.
contract Test_Optimization { uint256 a = 1; function Add () external returns (uint256) { a = a + 1; return a; } } contract Test_Without_Optimization { uint256 a = 1; function Add () external returns (uint256) { a += 1; return a; } }
With this optimization it's possible to save 116 gas
Exchange.sol#L316 Exchange.sol#L574 Exchange.sol#L601 Pool.sol#L36 Pool.sol#L46 Pool.sol#L73 Pool.sol#L74
Use unchecked { i++; } or unchecked{ ++i; } when it's not possible to overflow to save gas.
Exchange.sol#L177 Exchange.sol#L184 Exchange.sol#L307 Exchange.sol#L598
It's possible to save gas (due to JUMP operation) removing the modifier that are used just once in the code and inlined the code.
Operations that could not be overflow/underflow due to an if or require could be unchecked to save gas.
Exchange.sol#L574 Exchange.sol#L607 Pool.sol#L46 Pool.sol#L73
Local variables that are used once could be removed.
- uint256 receiveAmount = price - totalFee; - return (receiveAmount); + return (price - totalFee);
- bool success = IPool(POOL).transferFrom(from, to, amount); - require(success, "Pool transfer failed"); + require(IPool(POOL).transferFrom(from, to, amount), "Pool transfer failed");
Public functions needs to write all of the arguments to memory is that public functions may be called internally, which is an entirely different process than external calls. Internal calls are executed via jumps in the code and when the compiler generates the code for an internal function is expected to have its arguments located in memory.
For external functions, the compiler doesn't need to allow internal calls, and so it allows arguments to be read directly from calldata, saving the copying step.
#0 - c4-judge
2022-11-17T14:06:26Z
berndartmueller marked the issue as grade-b