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: 71/92
Findings: 1
Award: $52.03
🌟 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
_safeMint()
should be used rather than _mint()
wherever possible_mint()
is discouraged in favor of _safeMint()
which ensures that the recipient is either an EOA or implements IERC721Receiver
. Both OpenZeppelin and solmate have versions of this function so that NFTs aren’t lost if they’re minted to contracts that cannot transfer them back out.
31 _mint(_recipient, _amount);
https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/liquid-staking/GiantLP.sol
47 _mint(_recipient, _amount);
https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/liquid-staking/LPToken.sol
If the intention is for the Ether to be used, the function should call another function, otherwise it should revert (e.g. require(msg.sender == address(weth))
). Having no access control on the function means that someone may send Ether to the contract, and have no way to get anything back out, which is a loss of funds
629 receive() external payable {}
98 receive() external payable {}
In the contracts, floating pragmas should not be used. Contracts should be deployed with the same compiler version and flags that they have been tested with thoroughly. Locking the pragma helps to ensure that contracts do not accidentally get deployed using, for example, an outdated compiler version that might introduce bugs that affect the contract system negatively.
Amost all contracts use floating Solidity version
Code architecture, incentives, and error handling/reporting questions/issues should be resolved before deployment
195 // todo - check else case for any ETH lost
https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/syndicate/Syndicate.sol
public
functions not called by the contract should be declared external
insteadContracts are allowed to override their parents’ functions and change the visibility from external
to public
and can save gas by doing so
73 function deployNewLiquidStakingDerivativeNetwork(
https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/liquid-staking/LSDNFactory.sol
29 function batchDepositETHForStaking(
200 function withdrawETHForStaking( 218 function isBLSPublicKeyPartOfLSDNetwork(bytes calldata _blsPublicKeyOfKnot) public virtual view returns (bool) {
https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/liquid-staking/SavETHVault.sol
176 function totalRewardsReceived() public view override returns (uint256) {
239 function withdrawETH(address _wallet, uint256 _amount) public onlyManager nonReentrant returns (uint256) {
458 function calculateNewAccumulatedETHPerCollateralizedSharePerKnot() public view returns (uint256) {
https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/syndicate/Syndicate.sol
514 function isKnotDeregistered(bytes calldata _blsPublicKey) public view returns (bool) {
nonReentrant modifier
should occur before all other modifiersThis is a best-practice to protect against reentrancy in other modifiers
203 ) public onlyManager nonReentrant returns (uint256) {
https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/liquid-staking/SavETHVault.sol
239 function withdrawETH(address _wallet, uint256 _amount) public onlyManager nonReentrant returns (uint256) { 259 ) external onlyManager nonReentrant {
indexed
fieldsIndex event fields make the field more quickly accessible to off-chain tools that parse events. Each event
should use three indexed
fields if there are three or more fields, and gas usage is not particularly of concern for the events in question. If there are fewer than three fields, all of the fields should be indexed.
13 event ETHDeposited(address indexed sender, uint256 amount); 16 event LPBurnedForETH(address indexed sender, uint256 amount); 19 event LPSwappedForVaultLP(address indexed vaultLPToken, address indexed sender, uint256 amount);
16 event LPBurnedForDETH(address indexed savETHVaultLPToken, address indexed sender, uint256 amount);
19 event DETHRedeemed(address depositor, uint256 amount); 22 event ETHWithdrawnForStaking(address withdrawalAddress, address liquidStakingManager, uint256 amount); 121 event CurrentStamp(uint256 stamp, uint256 last, bool isConditionTrue);
https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/liquid-staking/SavETHVault.sol
25 event ETHDeposited(address sender, uint256 amount); 28 event ETHWithdrawn(address receiver, address admin, uint256 amount); 31 event ERC20Recovered(address admin, address recipient, uint256 amount); 34 event WETHUnwrapped(address admin, uint256 amount);
42 event UpdateAccruedETH(uint256 unprocessed); 45 event CollateralizedSLOTReCalibrated(bytes BLSPubKey); 48 event KNOTRegistered(bytes BLSPubKey); 51 event KnotDeRegistered(bytes BLSPubKey); 57 event Staked(bytes BLSPubKey, uint256 amount); 60 event UnStaked(bytes BLSPubKey, uint256 amount); 63 event ETHClaimed(bytes BLSPubKey, address indexed user, address recipient, uint256 claim, bool indexed isCollateralizedClaim);
https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/syndicate/Syndicate.sol
36 event WhitelistingStatusChanged(address indexed dao, bool updatedStatus); 39 event NodeRunnerWhitelistingStatusChanged(address indexed nodeRunner, bool updatedStatus); 48 event WalletCredited(address indexed smartWallet, uint256 amount); 51 event KnotStaked(bytes _blsPublicKeyOfKnot, address indexed trigerringAddress); 54 event StakehouseCreated(string stakehouseTicker, address indexed stakehouse); 57 event StakehouseJoined(bytes blsPubKey); 63 event DormantRepresentative(address indexed associatedSmartWallet, address representative); 66 event ETHWithdrawnFromSmartWallet(address indexed associatedSmartWallet, bytes blsPublicKeyOfKnot, address nodeRunner); 69 event NetworkTickerUpdated(string newTicker); 84 event DAOCommissionUpdated(uint256 old, uint256 newCommission); 87 event NewLSDValidatorRegistered(address indexed nodeRunner, bytes blsPublicKey);
16 event ETHWithdrawnByDepositor(address depositor, uint256 amount); 19 event LPTokenBurnt(bytes blsPublicKeyOfKnot, address token, address depositor, uint256 amount); 22 event NewLPTokenIssued(bytes blsPublicKeyOfKnot, address token, address firstDepositor, uint256 amount); 25 event LPTokenMinted(bytes blsPublicKeyOfKnot, address token, address depositor, uint256 amount);
#0 - c4-judge
2022-12-01T23:41:19Z
dmvt marked the issue as grade-b