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

Early user can break minting #107

Open
code423n4 opened this issue Jul 7, 2021 · 2 comments
Open

Early user can break minting #107

code423n4 opened this issue Jul 7, 2021 · 2 comments

Comments

@code423n4
Copy link
Contributor

Handle

cmichel

Vulnerability details

Vulnerability Details

The protocol computes a factor when minting (and burning) tokens which is the exchange rate of rebase to base tokens (base supply / total assets value), see GToken.factor().
The first user can manipulate this factor such that it always returns 0.

Example:

  • Attacker deposits 100.0 DAI and mints 100 * 1e18 PWRD: DepositHandler.depositGToken with dollarAmount = 100.0 = 100 * 1e18, then ctrl.mintGToken(pwrd, msg.sender, 1e18)
    calls gt.mint(account, gt.factor(), amount=1e18) where gt.factor() returns getInitialBase() = 1e18 because the person is the first minter and it mints amount * factor / _BASE = 1e18
  • The ctrl.mintGToken call also increases total assets: pnl.increaseGTokenLastAmount(...)
  • The attacker now burns (withdraws) all minted tokens again except a single wei using one of the withdrawal functions in WithdrawHandler. Because of the withdrawal fee the total assets are only decreased by the post-fee amount (IPnL(pnl).decreaseGTokenLastAmount(pwrd, amount=userBalance - 1, bonus=fee);), i.e., with a 2% withdrawal fee the total assets stay at 2% of 100$ = 2 * 1e18.
  • The result is that GToken.factor() always returns totalSupplyBase().mul(BASE).div(totalAssets) = 1 * 1e18 / (2 * 1e18) = 0

Impact

The resulting factor is 0 and thus any user deposits by depositGToken will mint 0 base tokens to the depositor.
This means all deposits and future value accrues to the attacker who holds the only base tokens.

An attacker could even frontrun the first minter to steal their deposit this way.

Recommended Mitigation Steps

Uniswap solves a similar problem by sending the first 1000 tokens to the zero address which makes the attack 1000x more expensive.
The same should work here, i.e., on first mint (total base supply == 0), lock some of the first minter's tokens by minting ~1% of the initial amount to the zero address instead of to the first minter.

@kitty-the-kat
Copy link
Collaborator

Known issue which will be handled by ops - low risk as gro protocol is the first depositor

@ghoul-sol
Copy link
Collaborator

Even though it's a known issue its consequences are significant. Only because it can be mitigated by ops quite easily, I'll degrade it to medium level.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants