Revest Finance Vulnerabilities: More than Re-entrancy

What’s the Revest Finance FNFT

  • mintTimeLock: the underlying asset will be unlocked after a period of time.
  • mintValueLock: the underlying asset will be unlocked when its value rises above or falls below a prescribed value.
  • mintAddressLock: the underlying asset will be unlocked by a prescribed account.
  • FNFTHandler: inherited from the ERC-1155 token. It creates a new FNFT with the incrementing fnftId for every lock. The lock prescribes the total supply of the new FNFT at the creation. The FNFT can not be minted in another way but can be burned for unlocking underlying assets.
  • LockManager: records the unlocking conditions for each lock when creating and decides if the lock can be unlocked when unlocking.
  • TokenVault: receives and sends the underlying assets and records the metadata for each FNFT, such as the value of a specified FNFT.
// Now, we transfer to the token vault
if(fnft.asset != address(0)){
IERC20(fnft.asset).safeTransferFrom(_msgSender(), vault, quantity * amount);
}
ITokenVault(vault).handleMultipleDeposits(fnftId, newFNFTId, fnft.depositAmount + amount);emit FNFTAddionalDeposited(_msgSender(), newFNFTId, quantity, amount);

What’s the Re-entrancy vulnerability

function mint(
address account,
uint id,
uint amount,
bytes memory data
) external override onlyRevestController {
require(amount > 0, "Invalid amount");
require(supply[id] == 0, "Repeated mint for the same FNFT");
supply[id] += amount;
fnftsCreated += 1;
_mint(account, id, amount, data);
}

the New Zero-day Vulnerability

function handleMultipleDeposits(
uint fnftId,
uint newFNFTId,
uint amount
) external override onlyRevestController {
require(amount >= fnfts[fnftId].depositAmount, 'E003');
IRevest.FNFTConfig storage config = fnfts[fnftId];
config.depositAmount = amount;
mapFNFTToToken(fnftId, config);
if(newFNFTId != 0) {
mapFNFTToToken(newFNFTId, config);
}
}

The workaround to fix the vulnerability

function handleMultipleDeposits(
uint fnftId,
uint newFNFTId,
uint amount
) external override onlyRevestController {
require(amount >= fnfts[fnftId].depositAmount, 'E003');
IRevest.FNFTConfig memory config = fnfts[fnftId];
config.depositAmount = amount;
if(newFNFTId != 0) {
mapFNFTToToken(newFNFTId, config);
} else {
mapFNFTToToken(fnftId, config);
}
}

Takeaway

--

--

--

A Blockchain Security and Data Company.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

What is Proof of Stake (PoS)? — Adaas Capital — Proof of Stake consensus mechanism in Blockchain

ALL YOU NEED ABOUT THE FLOKI ETH CONTRACT UPGRADE

Introducing AURELIO AMM, an efficient way to stake XAU-pegged tokens

WalletSwap Integrates FIO Protocol Features To Further Enhance Their User Experience

Bitcoin ETF: Everything You Need To Know

What Makes One Cryptocurrency Different from Another?

Getting Bitch Slapped Hard by Crypto

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
BlockSec

BlockSec

A Blockchain Security and Data Company.

More from Medium

Solana Exploit: $50 Million Stolen⚠️

Capture The Ether: predict the block hash

Beosin’s Analysis of the ZEED Exploit : The hacker has self-destructed the contract before…

Cross-chain bridge protocol, why it always attracts hackers