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

First depositor can inflate share price #253

Closed
code423n4 opened this issue Nov 28, 2022 · 3 comments
Closed

First depositor can inflate share price #253

code423n4 opened this issue Nov 28, 2022 · 3 comments
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working duplicate-275 satisfactory satisfies C4 submission criteria; eligible for awards

Comments

@code423n4
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2022-11-redactedcartel/blob/684627b7889e34ba7799e50074d138361f0f532b/src/vaults/AutoPxGmx.sol#L397
https://github.com/code-423n4/2022-11-redactedcartel/blob/684627b7889e34ba7799e50074d138361f0f532b/src/vaults/AutoPxGlp.sol#L314

Vulnerability details

Impact

A well-known vulnerability for ERC4626 vaults is the inflation of the share price on the first deposit. Because AutoPxGlp and AutoPxGmx use the balance of the underlying asset for totalAssets() and do not have an initial minimum deposit amount, they are also suspectible to this attack. This will cause subsequent depositors to lose significant parts of their deposits due to rounding errors.

Proof Of Concept

Bob deposits a very small amount of GMX such that he gets 1 wei of pxGMX. Afterwards, he transfers 1e18 pxGMX to the vault address. totalAssets() is defined like that:

		/**
        @notice Get the pxGMX custodied by the AutoPxGmx contract
        @return uint256  Amount of pxGMX custodied by the autocompounder
     */
    function totalAssets() public view override returns (uint256) {
        return asset.balanceOf(address(this));
    }

It will therefore now return 1e18 + 1.

When Alice now deposits 2e18 pxGMX, the following calculation will be performed:

assets.mulDivDown(supply, totalAssets() - assets)
= 2e18 * 1 / (1e18 + 1) = 1

Therefore, she receives only 1 share and ~1e18 pxGMX are lost due to rounding.

Recommended Mitigation Steps

There are multiple mitigations (minimium initial deposit, internal total assets, creating dead shares), see the OpenZeppelin issue for an extensive discussion: OpenZeppelin/openzeppelin-contracts#3706

@code423n4 code423n4 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Nov 28, 2022
code423n4 added a commit that referenced this issue Nov 28, 2022
@c4-judge
Copy link
Contributor

c4-judge commented Dec 3, 2022

Picodes marked the issue as duplicate of #407

@c4-judge
Copy link
Contributor

c4-judge commented Jan 1, 2023

Picodes marked the issue as satisfactory

@c4-judge c4-judge added the satisfactory satisfies C4 submission criteria; eligible for awards label Jan 1, 2023
@C4-Staff
Copy link
Contributor

JeeberC4 marked the issue as duplicate of #275

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 duplicate-275 satisfactory satisfies C4 submission criteria; eligible for awards
Projects
None yet
Development

No branches or pull requests

3 participants