Platform: Code4rena
Start Date: 11/11/2022
Pot Size: $90,500 USDC
Total HM: 52
Participants: 92
Period: 7 days
Judge: LSDan
Total Solo HM: 20
Id: 182
League: ETH
Rank: 43/92
Findings: 3
Award: $129.76
🌟 Selected for report: 0
🚀 Solo Findings: 0
55.3657 USDC - $55.37
Reentrancy attack may occur on withdrawETHForKnot()
Note: It wasn't clear to me whether this should be submitted as high severity or medium severity, so I thought it best to leave it up to the judges.
Lines of code:
Impact: A reentrancy attack can occur when the contract fails to update its state before the interaction, the attacker can make a recursive call back to the original function in an attempt to drain funds.
Proof of concept: The below scenario would be possible.
Since the node runner could be a smart contract, the contract could have a malicious code so that when withdrawETHForKnot()
get called, it goes in infinite loop in attempt to drain all the funds.
Manual Review
Use a reentrancy guard
#0 - c4-judge
2022-12-02T22:28:10Z
dmvt marked the issue as duplicate of #110
#1 - c4-judge
2022-12-02T22:28:47Z
dmvt marked the issue as partial-25
6.2548 USDC - $6.25
Since the function always revert Due to incorrect require statements, there is no way to add or remove a whitelisted node runner. Therefore, the functions registerBLSPublicKeys that require for a node runner to be whitelisted will also revert.
require(isNodeRunnerWhitelisted[_nodeRunner] != isNodeRunnerWhitelisted[_nodeRunner], "Unnecessary update to same status");
In this require statement you are basically saying that if a node runner is whitelisted then require that is not whitelisted and vice versa.
Manual review
Fix: // Replace the incorrect require statement with this one. require(isWhitelisted != isNodeRunnerWhitelisted[_nodeRunner], "Unnecessary update to same status");
#0 - c4-judge
2022-11-21T21:24:58Z
dmvt marked the issue as duplicate of #67
#1 - c4-judge
2022-11-30T11:43:55Z
dmvt marked the issue as satisfactory
#2 - C4-Staff
2022-12-21T00:11:17Z
JeeberC4 marked the issue as duplicate of #378
🌟 Selected for report: IllIllI
Also found by: 0xSmartContract, Awesome, Aymen0909, CloudX, Deivitto, ReyAdmirado, Saintcode_, bharg4v, brgltd, btk, c3phas, chrisdior4, ignacio, imare, lukris02, skyle, tnevler
68.1383 USDC - $68.14
Gas saving 1: State variables should be cached in memory variables rather than re-reading them from storage
Lines of code: https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/syndicate/Syndicate.sol#L177-L189 State variable: numberOfRegisteredKnots Deployment gas before: 3219394 Deployment gas used after: 3219178 Gas Saved: 216
Lines of code: https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/syndicate/Syndicate.sol#L551 State variable: totalFreeFloatingShares Deployment gas before: 3219394 Deployment gas used after: 3217654 Gas Saved: 1740
We can optimize the above functions by caching the state variables to a memory variables.
Gas saving 2: Add the constant attributes to state variables that never change
Lines of code: https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/liquid-staking/LiquidStakingManager.sol#L158 State variable: MODULO Deployment gas before: 5395557 Deployment gas used after: 5373903 Gas Saved: 21654
Gas saving 3: ++ Cost less gas then += 1
Lines of code: https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/liquid-staking/LiquidStakingManager.sol#L782 https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/liquid-staking/LiquidStakingManager.sol#L839 State variable: numberOfKnots Use ++numberOfKnots instead of numberOfKnots += 1 Deployment gas before: 5395557 Deployment gas used after: 5393181 Gas Saved: 2376
#0 - c4-judge
2022-12-02T00:07:02Z
dmvt marked the issue as grade-b