Open code423n4 opened 3 years ago
Known issue which will be handled by ops - low risk as gro protocol is the first depositor
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.
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), seeGToken.factor()
. The first user can manipulate this factor such that it always returns0
.Example:
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() = 1e18because the person is the first minter and it mints
amount * factor / _BASE = 1e18`ctrl.mintGToken
call also increases total assets:pnl.increaseGTokenLastAmount(...)
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.GToken.factor()
always returnstotalSupplyBase().mul(BASE).div(totalAssets) = 1 * 1e18 / (2 * 1e18) = 0
Impact
The resulting
factor
is 0 and thus any user deposits bydepositGToken
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.