LSD Network - Stakehouse contest - 0x4non's results

A permissionless 3 pool liquid staking solution for Ethereum.

General Information

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

Stakehouse Protocol

Findings Distribution

Researcher Performance

Rank: 18/92

Findings: 4

Award: $1,279.93

QA:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: c7e7eff

Also found by: 0x4non, 9svR6w, HE1M, Jeiwan, Trust, aphak5010, arcoun, cccz, clems4ever, corerouter, koxuan, rotcivegaf, unforgiven

Labels

bug
3 (High Risk)
partial-25
duplicate-147

Awards

10.2142 USDC - $10.21

External Links

Lines of code

https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/SyndicateRewardsProcessor.sol#L63

Vulnerability details

Impact

The variable claimed that keeps tracking of the total amount claimed per user per token its being being resetting with a wrong value. This impacts on the line due calculation on SyndicateRewardsProcessor.sol#L61

            uint256 due = ((accumulatedETHPerLPShare * balance) / PRECISION) - claimed[_user][_token];

Proof of Concept

Yo could create a contract that mint LP, then in one transaction loop a transfer function with no value and use the received ether to redeposit and repeat.

Tools Used

manual revision

On SyndicateRewardsProcessor.sol#L63 instead of

claimed[_user][_token] = due;

You could do

claimed[_user][_token] += due;

#0 - c4-judge

2022-11-21T22:07:47Z

dmvt marked the issue as duplicate of #59

#1 - c4-judge

2022-11-29T16:46:59Z

dmvt marked the issue as partial-25

#2 - C4-Staff

2022-12-21T05:47:22Z

JeeberC4 marked the issue as duplicate of #147

Findings Information

🌟 Selected for report: unforgiven

Also found by: 0x4non

Labels

bug
3 (High Risk)
satisfactory
duplicate-260

Awards

1012.6328 USDC - $1,012.63

External Links

#0 - c4-judge

2022-11-21T21:25:48Z

dmvt marked the issue as duplicate of #260

#1 - c4-judge

2022-12-01T23:58:05Z

dmvt marked the issue as satisfactory

Findings Information

🌟 Selected for report: rotcivegaf

Also found by: 0x4non, clems4ever, datapunk

Labels

bug
3 (High Risk)
partial-50
satisfactory
duplicate-328

Awards

205.0581 USDC - $205.06

External Links

Lines of code

https://github.com/code-423n4/2022-11-stakehouse/blob/39a3a84615725b7b2ce296861352117793e4c853/contracts/liquid-staking/SyndicateRewardsProcessor.sol#L67 https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantMevAndFeesPool.sol#L146 https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/StakingFundsVault.sol#L315

Vulnerability details

Impact

Multiple reentrancy issues mainly trigger by a low call ETH transfer.

Proof of Concept

Everytime you use the _distributeETHRewardsToUserForToken method on SyndicateRewardsProcessor.sol#L67 there are many reentrancy opportunities for an attacker.

For example, a contract can call the function transfer of GiantLP several times to transfer an amount from and to self. Because the update of the claimed would not be done until it is executed the function _afterTokenTransfer, the due amount calculated in _distributeETHRewardsToUserForToken of SyndicateRewardsProcessor contract and the lastInteractedTimestamp of GiantLP contract will be incorrect.

Tools Used

Manual revision

You could keep adding nonReentrant modifiers, but i think the safest call here is to wrap ETH into WETH an transfer it as a normal ERC20 to avoid unwanted callbacks.

#0 - c4-judge

2022-11-21T22:02:25Z

dmvt marked the issue as duplicate of #35

#1 - c4-judge

2022-11-29T15:23:02Z

dmvt marked the issue as satisfactory

#2 - c4-judge

2022-11-29T15:54:10Z

dmvt marked the issue as partial-50

#3 - C4-Staff

2022-12-21T00:17:14Z

JeeberC4 marked the issue as duplicate of #35

#4 - liveactionllama

2022-12-22T09:24:59Z

Duplicate of #328

QA

Low

Unresolved TODO that could lead to ether stuck

On Syndicate.sol#L195 you have an unresolved todo that could lead to ETH stuck on the contract.

Non critical

Pragma too open

The codebase uses floating pragma. All contracts should be compiled with same pragma version. Locking the pragma ensures that contracts do not accidentally get deployed using either an outdated buggy compiler version or a compiler version different from what the code has been tested with. Recommendation: use a fixed solc version on contracts, and open progma on interfaces.

Files:

Using draft version of Openzeppelin ERC20PermitUpgradeable

On LPToken.sol#L6 you are using draft version of Openzeppelin ERC20PermitUpgradeable. This contract is still a draft and is not considered ready for mainnet use. OpenZeppelin contracts may be considered draft contracts if they have not received adequate security auditing or are liable to change with future development.

Missing a __gap[50] storage variable on Syndicate and LpToken

Upgradeable contract is missing a __gap[50] storage variable to allow for new storage variables in later versions

Recommendation: add __gap variable:

+ uint256[50] __gap;

On this contracts;

Avoid magic numbers

On LiquidStakingManager.sol#L870 instead of the magic number (2 ** 256) - 1 use typeof(uint256).max for approving max; Instead of

sETH.approve(syndicate, (2 ** 256) - 1);

USe

sETH.approve(syndicate, typeof(uint256).max);

Un unused custom errors

Error InvalidBLSPubKey is not being in use; SyndicateErrors.sol#L8 Syndicate.sol#L15

Error KnotSlashed is not being in use; SyndicateErrors.sol#L10 Syndicate.sol#L17

Error NotCollateralizedOwnerAtIndex is not being in use; SyndicateErrors.sol#L20 Syndicate.sol#L27

Events that arent emit

There are some events declared that are never emmited, you should remove them or emit them;

Format code using forge fmt or other tool

Use format first license then pragma

Please review the solidity coding convention; https://docs.soliditylang.org/en/v0.8.17/style-guide.html

The usually convention is license first, then pragma.

You could go with this on;

#0 - c4-judge

2022-12-02T21:38:48Z

dmvt marked the issue as grade-b

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter