Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ERC4626 mint uses wrong amount #27

Open
code423n4 opened this issue Feb 20, 2022 · 2 comments
Open

ERC4626 mint uses wrong amount #27

code423n4 opened this issue Feb 20, 2022 · 2 comments
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working

Comments

@code423n4
Copy link
Contributor

Lines of code

https://github.com/Rari-Capital/solmate/blob/8c0e278900fe552fa0739975bde21c6a07d84ccf/src/mixins/ERC4626.sol#L67

Vulnerability details

Impact

The docs/video say ERC4626.sol is in scope as its part of TurboSafe

The ERC4626.mint function mints amount instead of shares.
This will lead to issues when the asset <> shares are not 1-to-1 as will be the case for most vaults over time.
Usually, the asset amount is larger than the share amount as vaults receive asset yield.
Therefore, when minting, shares should be less than amount.
Users receive a larger share amount here which can be exploited to drain the vault assets.

function mint(uint256 shares, address to) public virtual returns (uint256 amount) {
    amount = previewMint(shares); // No need to check for rounding error, previewMint rounds up.

    // Need to transfer before minting or ERC777s could reenter.
    asset.safeTransferFrom(msg.sender, address(this), amount);
    _mint(to, amount);

    emit Deposit(msg.sender, to, amount, shares);

    afterDeposit(amount, shares);
}

POC

Assume vault.totalSupply() = 1000, totalAssets = 1500

  • call mint(shares=1000). Only need to pay 1000 asset amount but receive 1000 shares => vault.totalSupply() = 2000, totalAssets = 2500.
  • call redeem(shares=1000). Receive (1000 / 2000) * 2500 = 1250 amounts. Make a profit of 250 asset tokens.
  • repeat until shares <> assets are 1-to-1

Recommended Mitigation Steps

In deposit:

function mint(uint256 shares, address to) public virtual returns (uint256 amount) {
-    _mint(to, amount);
+    _mint(to, shares);
}
@code423n4 code423n4 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Feb 20, 2022
code423n4 added a commit that referenced this issue Feb 20, 2022
@Joeysantoro
Copy link
Collaborator

#18

@Joeysantoro Joeysantoro added the duplicate This issue or pull request already exists label Feb 24, 2022
@GalloDaSballo
Copy link
Collaborator

The warden has identified what is most likely a small oversight, which would have drastic consequences in the internal accounting of the Vault.
Because of impact, I agree with high severity.

Will make this finding primary because it shows full details and a POC.

The sponsor has mitigated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants