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: 45/92
Findings: 2
Award: $120.17
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0xSmartContract
Also found by: 0x4non, 0xNazgul, 0xRoxas, 0xdeadbeef0x, 0xmuxyz, 9svR6w, Awesome, Aymen0909, B2, Bnke0x0, CloudX, Deivitto, Diana, Franfran, IllIllI, Josiah, RaymondFam, ReyAdmirado, Rolezn, Sathish9098, Secureverse, SmartSek, Trust, Udsen, a12jmx, aphak5010, brgltd, bulej93, c3phas, ch0bu, chaduke, chrisdior4, clems4ever, cryptostellar5, datapunk, delfin454000, fs0c, gogo, gz627, hl_, immeas, joestakey, lukris02, martin, nogo, oyc_109, pashov, pavankv, peanuts, pedr02b2, rbserver, rotcivegaf, sahar, sakman, shark, tnevler, trustindistrust, zaskoh, zgo
52.0338 USDC - $52.03
Downcast operation in SavETHVault.burnLPToken
.
Downcasting in solidity can lead to overflow. For example, if the result of (dETHDetails.savETHBalance * _amount) / 24 ether
generate a value bigger than uint128, e.g. by a user input mistake and if the check on L128 passes, the resulting redemptionValue
will overflow, causing a silent failure/bad account/loss of funds when calling getSavETHRegistry().withdraw()
.
Use a safe cast library for downcasting operations. E.g. openzeppelin safe cast.
Consider adding a __gap[]
storage variable to allow for new storage variables in later versions.
See this link for a description of this storage variable issue. Please, refer to this example for an implementation reference.
https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/liquid-staking/LPToken.sol#L11
https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/syndicate/Syndicate.sol#L36
If a variable gets configured with address zero, failure to immediately reset the value can result in unexpected behavior for the project.
https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/liquid-staking/GiantLP.sol#L25
https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/liquid-staking/LPToken.sol#L33
The following contracts are not using fixed compiler versions.
contracts/liquid-staking/OptionalGatekeeperFactory.sol, contracts/liquid-staking/OptionalHouseGatekeeper.sol, contracts/liquid-staking/SavETHVaultDeployer.sol, contracts/liquid-staking/StakingFundsVaultDeployer.sol, contracts/smart-wallet/OwnableSmartWalletFactory.sol, contracts/liquid-staking/LPTokenFactory.sol, contracts/liquid-staking/GiantLP.sol, contracts/liquid-staking/LPToken.sol, contracts/liquid-staking/GiantPoolBase.sol, contracts/liquid-staking/LSDNFactory.sol, contracts/liquid-staking/GiantSavETHVaultPool.sol, contracts/smart-wallet/OwnableSmartWallet.sol, contracts/liquid-staking/SavETHVault.sol, contracts/liquid-staking/GiantMevAndFeesPool.sol, contracts/liquid-staking/StakingFundsVault.sol, contracts/liquid-staking/LiquidStakingManager.sol, contracts/liquid-staking/SyndicateRewardsProcessor.sol, contracts/liquid-staking/ETHPoolLPFactory.sol,
Locking the pragma helps to ensure that contracts do not accidentally get deployed using an outdated compiler version.
Note that pragma statements can be allowed to float when a contract is intended for consumption by other developers, as in the case with contracts in a library or a package.
@openzeppelin/contracts-upgradeable
The project is using the fixed version 4.5.0 for contracts-upgradeable. Consider using the latest version (4.8.0) to ensure the library contracts contains the latest security fixes.
Consider using only one approach for the same function.
Consider documenting all function to improve documentation.
The solidity documentation recommends the following order for functions:
constructor receive function (if exists) fallback function (if exists) external public internal private
The instances bellow shows public above external.
Each event should use three indexed fields if there are three or more fields
https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/liquid-staking/LPToken.sol#L6
OpenZeppelin contracts may be considered draft contracts if they have not received adequate security auditing or are liable to change with future development.
Ensure the development team is aware of the risks of using a draft contract or consider waiting until the contract is finalised.
Otherwise, make sure that development team are aware of the risks of using a draft OpenZeppelin contract and accept the risk-benefit trade-off.
The solidity documentation recommends a maximum of 120 characters.
Consider adding a limit of 120 characters or less to prevent large lines.
https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/liquid-staking/GiantLP.sol#L46
#0 - c4-judge
2022-12-02T19:57:45Z
dmvt marked the issue as grade-b
🌟 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
It can save 30-40 gas per loop.
Using the addition operator instead of plus-equals saves 113 gas.
Caching of a state variable replace each Gwarmaccess (100 gas) with a cheaper stack read. E.g. the state variable brand
can be cached on the instances bellow for LiquidStakingManager._joinLSDNStakehouse()
.
#0 - c4-judge
2022-12-02T19:58:34Z
dmvt marked the issue as grade-b