Platform: Code4rena
Start Date: 05/05/2022
Pot Size: $125,000 DAI
Total HM: 17
Participants: 62
Period: 14 days
Judge: leastwood
Total Solo HM: 15
Id: 120
League: ETH
Rank: 35/62
Findings: 2
Award: $270.28
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0x4non, 0xDjango, 0xNazgul, 0xkatana, 0xsomeone, AuditsAreUS, BouSalman, BowTiedWardens, Cityscape, Funen, GimelSec, Hawkeye, JC, MaratCerby, MiloTruck, Picodes, Ruhum, TerrierLover, WatchPug, Waze, bobirichman, catchup, cccz, cryptphi, csanuragjain, delfin454000, ellahi, fatherOfBlocks, hake, horsefacts, hyh, jayjonah8, joestakey, kebabsec, kenta, mics, oyc_109, robee, samruna, shenwilly, sikorico, simon135, throttle, tintin
178.438 DAI - $178.44
The contracts was used floating pragma ^0.8.11. It can be consider using locking the pragma version whenever possible and avoid using a floating pragma in the final deployment. Since it can be problematic, if there are publicly disclosed bugs and issues that affect the current compiler version used.
Manual Review
Use these compiler versions are to compile your code: 0.8.11, 0.8.12, 0.8.13
Since AlchemistV2
, TransmuterBuffer
& TransmuterV2
was used constructor() initializer {}
. Implementation below will tell the upgrade plugins that you know what you're doing, and let you keep the constructor. The latest version generates upgradeable contracts using this pattern and it will not receive the following error later.
Manual Review
##POC https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable https://forum.openzeppelin.com/t/constructor-initializer-inclusion/17412
It's necessary to also include the comment above that says
/// @custom:oz-upgrades-unsafe-allow constructor
@return was not used in actual code, since it just using emit. comment can be changed or can be deleted instead/
##Tool Used Manual Review
🌟 Selected for report: IllIllI
Also found by: 0v3rf10w, 0x1f8b, 0x4non, 0xDjango, 0xNazgul, 0xf15ers, 0xkatana, 0xsomeone, AlleyCat, BowTiedWardens, Cityscape, Fitraldys, Funen, GimelSec, Hawkeye, JC, MaratCerby, MiloTruck, Randyyy, TerrierLover, Tomio, UnusualTurtle, WatchPug, Waze, _Adam, augustg, bobirichman, catchup, csanuragjain, ellahi, fatherOfBlocks, hake, hansfriese, horsefacts, ignacio, joestakey, kenta, mics, oyc_109, robee, samruna, sashik_eth, sikorico, simon135, throttle
91.8428 DAI - $91.84
Since this can be set as constant, cause of values assigned at compile time and will not allow for any modifications at runtime.
Manual Review, VSC
Using i++ instead ++i for all the loops, the variable i is incremented using i++. It is known that implementation by using ++i costs less gas per iteration than i++.
Manual Review
AlchemistV2.sol#L990 AlchemistV2.sol#L1282 AlchemistV2.sol#L1355 AlchemistV2.sol#L1461 AlchemistV2.sol#L1524 CrossChainCanonicalBase.sol#L57 CrossChainCanonicalBase.sol#L141 TransmuterBuffer.sol#L172 TransmuterBuffer.sol#L186 TransmuterBuffer.sol#L235 TransmuterBuffer.sol#L242 TransmuterBuffer.sol#L272 TransmuterBuffer.sol#L387 ThreePoolAssetManager.sol#L250 ThreePoolAssetManager.sol#L254 ThreePoolAssetManager.sol#L353 ThreePoolAssetManager.sol#L773 ThreePoolAssetManager.sol#L902 Multicall.sol#L14
uint256 i = 0
into uint256 i
for saving more gasusing this implementation can saving more gas for each loops.
Manual Review
##Recommended Mitigation Change it
##Occurances
AlchemistV2.sol#L990 AlchemistV2.sol#L1282 AlchemistV2.sol#L1355 AlchemistV2.sol#L1461 AlchemistV2.sol#L1524 CrossChainCanonicalBase.sol#L57 CrossChainCanonicalBase.sol#L141 TransmuterBuffer.sol#L172 TransmuterBuffer.sol#L186 TransmuterBuffer.sol#L235 TransmuterBuffer.sol#L242 TransmuterBuffer.sol#L272 TransmuterBuffer.sol#L387 ThreePoolAssetManager.sol#L250 ThreePoolAssetManager.sol#L254 ThreePoolAssetManager.sol#L353 ThreePoolAssetManager.sol#L773 ThreePoolAssetManager.sol#L902 Multicall.sol#L14
This implementation can be saving more gas, since if caching the array length is more gas efficient. just because access to a local variable in solidity is more efficient.
##Tool Used Manual Review
##Occurances
AlchemistV2.sol#L990 AlchemistV2.sol#L1282 AlchemistV2.sol#L1355 AlchemistV2.sol#L1461 AlchemistV2.sol#L1524 CrossChainCanonicalBase.sol#L57 CrossChainCanonicalBase.sol#L141 TransmuterBuffer.sol#L172 TransmuterBuffer.sol#L186 TransmuterBuffer.sol#L235 TransmuterBuffer.sol#L242 TransmuterBuffer.sol#L272 TransmuterBuffer.sol#L387 ThreePoolAssetManager.sol#L250 ThreePoolAssetManager.sol#L254 ThreePoolAssetManager.sol#L353 ThreePoolAssetManager.sol#L773 ThreePoolAssetManager.sol#L902 Multicall.sol#L14
unlockedCredit
in memory can save gasunlockedCredit
is called multiple times (2 times to be exact) in the _wrap()
function. i recommend to cache unlockedCredit
Manual Review
++self.position
instead of self.position++
for cost less gasUsing prefix was common for saving more gas, since this implementation can be saving more gas
Manual Review
= 0
This code can be saving more gas by removing = 0, it because If a variable was not set/initialized, it is assumed to have default value to 0
Manual Review
Remove = 0
memory
can be saving more gas@Param _self
can be caching in memory, since function getUpdatedTotalUnclaimed()
was used to be internal view and you can saving gas by caching memory cause _self
was read-only
Manual Review