Griefing opportunity may cause users to lose funds
Description
The calculation of lastMul
to account for rebase tokens is incorrect and can lead to devaluation of user funds deposited in the vault.
function updateBalance(uint fnftId, uint incomingDeposit) internal {
...
if(asset != address(0)){
currentAmount = IERC20(asset).balanceOf(address(this));
} else {
// Keep us from zeroing out zero assets
currentAmount = lastBal;
}
tracker.lastMul = lastBal == 0 ? multiplierPrecision : multiplierPrecision * currentAmount / lastBal;
...
}
The TokenVault
supports rebase tokens with a dynamic supply to achieve certain economic goals, such as pegging a token to an asset.
In TokenVault
, we can see that the currentAmount
is the balance of the TokenVault
divided by lastBal
. This checks whether the asset has rebased since the last interaction, signaling an increase or decrease in supply.
However, an attacker may transfer ERC20 tokens directly to the vault, inflating currentAmount
, leading to an inflated lastMul
, thus emulating a rebase. The deposit with inflated lastMul
would be devalued when lastMul
is reset back in the next updateBalance
call.
Proof of Concept
A sample proof-of-concept can be found here↗.
The output is as follows:
Minted one FNFT with id -> 0
Current value of FNFT-0 is 10
Transferred 10 tokens to fake a rebase
Minted another FNFT with id -> 1 and 100 depositAmount
The value should be 100
But the value is 50
The PoC mints two FNFTs. The first one proceeds as normal. Then, tokens are transferred directly to the vault. This transfer emulates a "fake" rebase. As a result, when the second FNFT is minted, it has value 50 rather than the correct value of 100.
Impact
The victim minting a FNFT following the fake rebase action permanently loses funds. This poses a very large griefing vector for Revest.
Recommendations
Alter the logic to properly account for Rebase Tokens.
Remediation
The Revest team has fixed this issue by proposing a move to a new and improved TokenVaultV2 design, and by deprecating the handling of rebase tokens in TokenVault.