Assessment reports>Revest Finance>Discussion>Re-entrancy points

Re-entrancy points

User control of execution mostly stems from the fact that users exercise full control over asset and pipeToContract in FNFTConfig. Users control ValueLock's oracle and AddressLock's trigger, which can also lead to external, user-controlled calls.

Finally, it is important to keep in mind a callback is called on to whenever an ERC1155 is minted. Although there are so many re-entrancy points, they're not directly exploitable as every external function is marked nonReentrant.

Revest.sol

Revest.sol:{333, 354} - user controls fnftConfig.asset

333: IERC20(fnftConfig.asset).safeTransferFrom(_msgSender(), addressesProvider.getAdmin(), totalERC20Fee);
...
354: IERC20(fnftConfig.asset).safeTransferFrom(_msgSender(), vault, totalQuantity * fnftConfig.depositAmount);

Revest.sol:136 - user controls trigger

136: IAddressLock(trigger).createLock(fnftId, lockId, arguments);

Revest.sol:{203, 248} - user controls pipeToContract

203: IOutputReceiverV3(config.pipeToContract).handleTimelockExtensions(fnftId, endTime, msg.sender);
...
248: IOutputReceiverV3(fnft.pipeToContract).handleAdditionalDeposit(fnftId, amount, quantity, msg.sender);

Revest.sol:358-362 - ERC1155 _mint executes callback on to

358: if(!isSingular) {
359:     getFNFTHandler().mintBatchRec(recipients, quantities, fnftId, totalQuantity, '');
360: } else {
361:     getFNFTHandler().mint(recipients[0], fnftId, quantities[0], '');
362: }

LockManager.sol

LockManager.sol:{60, 158} - user controls lock.valueLock.oracle

60: IOracleDispatch oracle = IOracleDispatch(lock.valueLock.oracle);
...
158: IOracleDispatch oracle = IOracleDispatch(lock.valueLock.oracle);

LockManager.sol:{121, 143} - user controls lock.addressLock

121: IAddressLock(addLock).isUnlockable(fnftId, lockId))
...
143: IAddressLock(lock.addressLock).isUnlockable(fnftId, fnftIdToLockId[fnftId])

TokenVault.sol

TokenVault.sol:{60, 104, 110, 229} - user controls asset

60: currentAmount = IERC20(asset).balanceOf(address(this));
...
104: IERC20(asset).safeTransfer(user, withdrawAmount);
...
110: IERC20(asset).safeTransfer(fnft.pipeToContract, withdrawAmount);
...
229: currentAmount = IERC20(fnfts[fnftId].asset).balanceOf(address(this));

TokenVault.sol:{114, 224} - user controls pipeToContract

114: IOutputReceiver(pipeTo).receiveRevestOutput(fnftId, asset, payable(user), quantity);
...
224: return IOutputReceiver(fnfts[fnftId].pipeToContract).getValue((fnftId));

FNFTHandler.sol (fnft-migration branch)

FNFTHandler.sol:{106, 117} - user controls pipeToContract

106: IOutputReceiverV4(config.pipeToContract).onTransferFNFT(ids[0], operator, from, to, amounts[0], data);
...
117: IOutputReceiverV4(config.pipeToContract).onTransferFNFT(ids[i], operator, from, to, amounts[i], data);
Zellic © 2024Back to top ↑