Platform: Code4rena
Start Date: 16/11/2021
Pot Size: $50,000 ETH
Total HM: 11
Participants: 17
Period: 7 days
Judge: LSDan
Total Solo HM: 8
Id: 49
League: ETH
Rank: 13/17
Findings: 2
Award: $350.59
🌟 Selected for report: 4
🚀 Solo Findings: 0
🌟 Selected for report: 0x0x0x
0.0161 ETH - $74.28
0x0x0x
_roller.time
is cached, to use at roll function call. To save gas _roller.time
can be cached after roll function call and avoid caching to save gas.
Manual
#0 - commercium-sys
2021-12-08T22:19:23Z
There seems to be an optimization related to the roll function call in brrrr() but this is not it. The nature of the optimization is that should the conditions for roll were ever hit in the brrrr() function, the last moment will not be the same, therefore we can directly pass the number 0 as the "last moment" into our roll function. This will have the effect of writing into the next roller slot.
🌟 Selected for report: 0x0x0x
0.0161 ETH - $74.28
0x0x0x
Current function is (L205-217):
oiLong_ = __oiLong__; oiShort_ = __oiShort__; oiLongShares_ = oiLongShares; oiShortShares_ = oiShortShares; if (0 < _compoundings) { ( oiLong_, oiShort_, ) = computeFunding( oiLong_, oiShort_, _compoundings, k );
We cache oiLong and used the cached one, but this is an extra not required step. The same logic can be implemented costing less gas as follows:
oiLongShares_ = oiLongShares; oiShortShares_ = oiShortShares; if (0 < _compoundings) { ( oiLong_, oiShort_, ) = computeFunding( __oiLong__, __oiShort__, _compoundings, k );
Manual analysis
#0 - mikeyrf
2021-12-07T20:24:43Z
sponsor acknowledged reason - POC test shows we save around 64 gas with this change, so minimal savings
🌟 Selected for report: 0x0x0x
0.0161 ETH - $74.28
0x0x0x
OverlayV1Ol
L91-L93 is as follows:
uint _fundingFactor = ONE.sub(_k.mulUp(ONE*2)); _fundingFactor = _fundingFactor.powUp(ONE*_epochs);
This can be replaced by:
uint _fundingFactor = ONE.sub(_k.mulUp(ONE*2)).powUp(ONE*_epochs);
and save gas since we use one less saving operation.
Manual analysis
#0 - mikeyrf
2021-12-07T20:29:44Z
sponsor acknowledge reason - makes the code less readable and only produces gas savings of 37 gas
🌟 Selected for report: 0x0x0x
0.0161 ETH - $74.28
0x0x0x
Current code block between L77-89 is as follows:
require(_pricePointIndex < _len || (_pricePointIndex == _len && updated != block.timestamp), "OVLV1:!price"); if (_pricePointIndex == _len) { ( bid_, ask_, depth_ ) = readPricePoint(fetchPricePoint()); } else { ( bid_, ask_, depth_ ) = readPricePoint(_pricePointIndex); }
Here in the beginning we have a long require statement. The logic of this statement can be calculated inside if-else to save gas as follows:
if (_pricePointIndex == _len) { require(updated != block.timestamp), "OVLV1:!price"); ( bid_, ask_, depth_ ) = readPricePoint(fetchPricePoint()); } else { require(_pricePointIndex < _len, "OVLV1:!price"); ( bid_, ask_, depth_ ) = readPricePoint(_pricePointIndex); }
#0 - mikeyrf
2021-12-07T20:35:10Z
sponsor acknowledged reason - definitely makes the code block more readable, but gas savings is minimal and some more of the original require statement needs to be included in your if/else code to accomplish the desired logic
0x0x0x
roll
function can be implemented more readable and gas efficient. L361-L381 is as follows:
if (_roller.time != _lastMoment) { _cycloid += 1; if (_cycloid < CHORD) { rollers[_cycloid] = _roller; } else { _cycloid = 0; rollers[_cycloid] = _roller; } } else { rollers[_cycloid] = _roller; }
The same logic can be provided with:
if (_roller.time != _lastMoment) { _cycloid += 1; if (_cycloid >= CHORD) { _cycloid = 0; } } rollers[_cycloid] = _roller;
By doing a shorter and more efficient byte code will be produced.
Manual analysis
#0 - mikeyrf
2021-12-07T00:21:09Z
duplicate #68
🌟 Selected for report: harleythedog
0x0x0x
FixedPoint.sol
implements underflow/overflow, division by 0, which are already included in Solidity 0.8.*. Therefore those checks waste gas no reason
Manual analysis
#0 - mikeyrf
2021-12-07T00:11:39Z
duplicate #48