MorpheusAI

MorpheusAI
Foundry
22,500 USDC
View results
Submission Details
Severity: low
Valid

Missing access control in `StETHMock::mint` function. Attacker can mint `stETHMock` shares to his account for free.

Summary

The mint function in the StETHMock contract lacks proper access control allowing anyone to call it and mint new shares. This just have check to mint only 1000 shares. This poses a significant security risk as it can lead to unauthorized inflation or manipulation of the token supply. Attacker can create attack contract and call this function in loop to mint so he can mint (1000e18 * totalPooledEther) / totalShares amount of shares to his account many times in one transaction. Decimals is 18 Since openzeppelin's decimals() return 18 by default when not changed.

Vulnerability Details

The StETHMock smart contract exhibits a potential security vulnerability in the mint function. The function lacks proper access control allowing any external address to call it and mint new shares.

We can see in below code snippet there is no access control on mint function. And he can mint (1000e18 * totalPooledEther) / totalShares amount of shares many times as much he wants.
(1000e18 * totalPooledEther) / totalShares is return value of sharesAmount from getSharesByPooledEth(_amount) is called. Attacker can pass max. amount 1000e18. Since decimals() return 18 by default when not changed.

File : contracts/mock/shares/StETHMock.sol
19: function mint(address _account, uint256 _amount) external { //@audit no access control
20: require(_amount <= 1000 * (10 ** decimals()), "StETHMock: amount is too big");
21:
22: uint256 sharesAmount = getSharesByPooledEth(_amount);
23:
24: _mintShares(_account, sharesAmount);
25:
26: totalPooledEther += _amount;
27: }

contracts/mock/shares/StETHMock.sol#L19C5-L27C6

Impact

Attacker can mint (1000e18 * totalPooledEther) / totalShares amount of shares to his account many times as much as he wants.

Tools Used

Manual Review

Recommended Mitigation Steps

Add onlyOwner modifier in the StETHMock::mint function. Since Ownable is inherited by stETHMock contract so onlyOwner modifier is available to use so only owner of this contract can call StETHMock::mint function.

-19: function mint(address _account, uint256 _amount) external {
+19: function mint(address _account, uint256 _amount) external onlyOwner {
20: require(_amount <= 1000 * (10 ** decimals()), "StETHMock: amount is too big");
21:
22: uint256 sharesAmount = getSharesByPooledEth(_amount);
23:
24: _mintShares(_account, sharesAmount);
25:
26: totalPooledEther += _amount;
27: }
Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Lack of access control in `StETHMock:mint` and `WStETHMock::mint`

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.