Platform: Code4rena
Start Date: 18/10/2022
Pot Size: $75,000 USDC
Total HM: 27
Participants: 144
Period: 7 days
Judge: gzeon
Total Solo HM: 13
Id: 170
League: ETH
Rank: 24/144
Findings: 3
Award: $377.87
🌟 Selected for report: 0
🚀 Solo Findings: 0
By passing a tiny gas price and a gigantic gas limit when bridging out, the choosen operator will either have to call executeJob
but it'd be to expensive, or will get slashed.
bridgeOutRequest(toChain, holographableContract, 1e12, 1)
in HolographBridge
messagingModule.getHlgFee(toChain, gasLimit, gasPrice)
which would be in the order of magnitude of gasLimit * gasPrice ~ 1e12
so not expensivemsg.value
is sufficient, the messaging module will pass the message to the destination chaincrossChainMessage
in HolographOperator
is called, eventually selecting an operator and removing it from its pod, doing _bondedOperators[operator] = 0;
here._bondedOperators[operator] = 0;
, the operator is frozen and cannot unbound its funds. To undo this the job needs to be executed, but this would be expensive because of this line. The only choice for the operator is either to loose access to its funds, either to pay 1e12 gas
or whatever the gasLimit
set by Alice was to execute the job.In crossChainMessage
, the gasPrice
needs to be checked to ensure it is not too small.
#0 - gzeoneth
2022-10-30T16:32:05Z
Duplicate of #364
🌟 Selected for report: Rolezn
Also found by: 0x1f8b, 0x52, 0x5rings, 0xNazgul, 0xSmartContract, 0xZaharina, 0xhunter, 0xzh, 8olidity, Amithuddar, Aymen0909, B2, Bnke0x0, Chom, Deivitto, Diana, Diraco, Dravee, Franfran, JC, Jeiwan, Josiah, JrNet, Jujic, KingNFT, KoKo, Lambda, Margaret, Migue, Ocean_Sky, PaludoX0, Picodes, Rahoz, RaoulSchaffranek, RaymondFam, RedOneN, ReyAdmirado, Shinchan, Tagir2003, Trust, Waze, Yiko, __141345__, a12jmx, adriro, ajtra, arcoun, aysha, ballx, bin2chen, bobirichman, brgltd, bulej93, catchup, catwhiskeys, caventa, cccz, cdahlheimer, ch0bu, chaduke, chrisdior4, cloudjunky, cryptostellar5, cryptphi, csanuragjain, cylzxje, d3e4, delfin454000, djxploit, durianSausage, erictee, fatherOfBlocks, francoHacker, gianganhnguyen, gogo, hansfriese, i_got_hacked, ignacio, imare, karanctf, kv, leosathya, louhk, lukris02, lyncurion, m_Rassska, malinariy, martin, mcwildy, mics, minhtrng, nicobevi, oyc_109, pashov, peanuts, pedr02b2, peiw, rbserver, ret2basic, rotcivegaf, rvierdiiev, ryshaw, sakman, sakshamguruji, saneryee, securerodd, seyni, sikorico, svskaushik, teawaterwire, tnevler, w0Lfrum
0 USDC - $0.00
Here: destiantion -> destination Here: destiantion -> destination
Here it states "NOT PART OF FINAL CODE !!!". However the function is in this version for the audit, which is a bit confusing.
Here has -> gas
Here give - given
🌟 Selected for report: oyc_109
Also found by: 0x040, 0x1f8b, 0x5rings, 0xNazgul, 0xSmartContract, 0xZaharina, 0xsam, 0xzh, 2997ms, Amithuddar, Aymen0909, B2, Bnke0x0, Deivitto, Diana, Dinesh11G, Franfran, JC, JrNet, Jujic, KingNFT, KoKo, Mathieu, Metatron, Mukund, Olivierdem, PaludoX0, Pheonix, Picodes, RaymondFam, RedOneN, ReyAdmirado, Rolezn, Saintcode_, Satyam_Sharma, Shinchan, Tagir2003, Tomio, Waze, Yiko, __141345__, adriro, ajtra, aysha, ballx, beardofginger, bobirichman, brgltd, bulej93, catchup, catwhiskeys, cdahlheimer, ch0bu, chaduke, chrisdior4, cryptostellar5, cylzxje, d3e4, delfin454000, dharma09, djxploit, durianSausage, emrekocak, erictee, exolorkistis, fatherOfBlocks, gianganhnguyen, gogo, halden, hxzy, i_got_hacked, iepathos, karanctf, leosathya, lucacez, lukris02, lyncurion, m_Rassska, martin, mcwildy, mics, nicobevi, peanuts, peiw, rbserver, ret2basic, rotcivegaf, ryshaw, sakman, sakshamguruji, saneryee, sikorico, skyle, svskaushik, tnevler, vv7, w0Lfrum, zishansami
26.3525 USDC - $26.35
delete
operation could be avoidedHere the array is pop()
anyway so there is no need to manually delete the storage
_operatorPods
In HolographOperator
, _operatorPods
is a Multi-dimensional array. But it is used as a stack, and successful length modifications (pop
then push
) will set the storage back to 0, and then to non 0, which costs overall ~20k gas.
Instead, you could use a mapping
to represent the array and store the length of the array separately. This way, when popping an element you don't need to clear the storage and every sequence of pop
then push
will save you 10k gas.
What are the utility of all getters like getOperator
? If it's only for off-chain use, you could read from the storage slot directly and save deployment costs.
Assuming resetOperator
is not part of the final code at it seems to be the intent of the dev team, some private variables could be switch to constants to save numerous cold SLOAD
(2100 gas).
At least the following ones in HolographOperator
: _blockTime
, _baseBondAmount
, _podMultiplier
, _operatorThreshold
, _operatorThresholdStep
, _operatorThresholdDivisor
.
blockTimes
from OperatorJob
.In HolographOperator
, job.blockTimes
is always equal to _blockTime
so the entry could be removed from the struct. This could be combined with the previous gas optimization for even more savings.
require(!_isContract(holographerAddress), "HOLOGRAPH: already deployed");
.In HolographFactory
, at this line there is no need to check if the contract has already been deployed per EIP-684. See here.
Quoting it: "If a contract creation is attempted, due to either a creation transaction or the CREATE (or future CREATE2) opcode, and the destination address already has either nonzero nonce, or nonempty code, then the creation throws immediately, with exactly the same behavior as would arise if the first byte in the init code were an invalid opcode. This applies retroactively starting from genesis."