> ## Documentation Index
> Fetch the complete documentation index at: https://docs.phylax.systems/llms.txt
> Use this file to discover all available pages before exploring further.

# Visor Finance Unrestricted Mint

> Visor Finance allowed anyone to mint rewardTokens

This is a fairly simple bug that let anyone mint rewardTokens.

Background: [https://x.com/storming0x/status/1473321779250802693](https://x.com/storming0x/status/1473321779250802693)

## What Happened

* The deposit function lets anyone mint rewardTokens if
  * the from address is a contract and has an owner and where msg.sender == owner
* It is intended that the from address sends the underlying token to this contract
  * But it does not check whether delegatedTransferERC20 is implemented correctly
  * it can be a noop
* The attacker can mint rewardTokens to himself

## Assertion Pattern

While this is an obvious bug, an invariant could have prevented an exploit of the bug.

Invariant:

```solidity theme={null}
function assertionIsSolvent() public view {
    require(visr.balanceOf(address(adopter)) >= vvisr.totalSupply(), "Reward tokens are undercollateralized");
}
```

Alternatively, the assertion could test the correct behavior of the previous transaction.
The assertion could be triggered by a call to the deposit function.

```solidity theme={null}
function assertion_triggerDeposit_remainsSolvent() public view {
    // Get pre-transaction state
    PhEvm.ForkId memory preFork = _preTx();
    uint256 preBalanceCollateral = visr.balanceOf(address(adopter));
    uint256 preTotalSupplyRewards = vvisr.totalSupply();

    // Get post-transaction state
    PhEvm.ForkId memory postFork = _postTx();
    uint256 postBalanceCollateral = visr.balanceOf(address(adopter));
    uint256 postTotalSupplyRewards = vvisr.totalSupply();

    // Compare ratios using cross-multiplication to avoid precision loss
    // preBalance / preSupply >= postBalance / postSupply
    // => preBalance * postSupply >= postBalance * preSupply
    require(
        preBalanceCollateral * postTotalSupplyRewards >= postBalanceCollateral * preTotalSupplyRewards,
        "Reward tokens are undercollateralized"
    );
}
```
