sherlock-audit / 2023-12-flatmoney-judging

9 stars 7 forks source link

alexzoid - Mint Points Reverts When Locked Amount Less Than Mint Amount #242

Closed sherlock-admin2 closed 5 months ago

sherlock-admin2 commented 5 months ago

alexzoid

medium

Mint Points Reverts When Locked Amount Less Than Mint Amount

Summary

Minting points process is disrupted when a user has fewer points than the amount intended to mint.

Vulnerability Detail

There is an underflow issue when mintAmount exceeds lockedAmount. This situation occurs when a user attempts to mint more tokens than currently locked, leading to a revert.

https://github.com/sherlock-audit/2023-12-flatmoney/blob/main/flatcoin-v1/src/PointsModule.sol#L142-L155

    function _setMintUnlockTime(address account, uint256 mintAmount) internal returns (uint256 newUnlockTime) {
        uint256 lockedAmount = _lockedAmount[account];
        uint256 unlockTimeBefore = unlockTime[account];

        if (unlockTimeBefore <= block.timestamp) {
            newUnlockTime = block.timestamp + unlockTaxVest;
        } else {
            uint256 newUnlockTimeAmount = (block.timestamp + unlockTaxVest) * mintAmount;
            uint256 oldUnlockTimeAmount = unlockTimeBefore * (lockedAmount - mintAmount); // <----------------
            newUnlockTime = (newUnlockTimeAmount + oldUnlockTimeAmount) / lockedAmount;
        }

        unlockTime[account] = newUnlockTime;
    }

Complicating the issue, the PointsModule._setMintUnlockTime function is indirectly called during critical operations like executing a pending order via DelayedOrder.executeOrder() and opening leverage with LeverageModule.executeOpen().

Impact

This is a medium-severity issue because it disrupts core functionalities such as deposit execution and leverage opening due to the minting points function reverting when a user's existing points are fewer than the mint amount.

Code Snippet

https://github.com/sherlock-audit/2023-12-flatmoney/blob/main/flatcoin-v1/src/PointsModule.sol#L150

Tool used

Manual Review

Recommendation

Implement a check to ensure the user's locked points are greater than or equal to the mint amount:

diff --git a/flatcoin-v1/src/PointsModule.sol b/flatcoin-v1/src/PointsModule.sol
index a3dabcb..5a6832a 100644
--- a/flatcoin-v1/src/PointsModule.sol
+++ b/flatcoin-v1/src/PointsModule.sol
@@ -147,7 +147,7 @@ contract PointsModule is ModuleUpgradeable, ERC20LockableUpgradeable {
             newUnlockTime = block.timestamp + unlockTaxVest;
         } else { 
             uint256 newUnlockTimeAmount = (block.timestamp + unlockTaxVest) * mintAmount;
-            uint256 oldUnlockTimeAmount = unlockTimeBefore * (lockedAmount - mintAmount);
+            uint256 oldUnlockTimeAmount = lockedAmount >= mintAmount ? unlockTimeBefore * (lockedAmount - mintAmount) : 0;
             newUnlockTime = (newUnlockTimeAmount + oldUnlockTimeAmount) / lockedAmount;
         }
sherlock-admin commented 5 months ago

1 comment(s) were left on this issue during the judging contest.

takarez commented:

invalid

nevillehuang commented 4 months ago

Invalid, in _mintTo(), _setMintUnlockTime() is only executed after _lock() is executed where lockedAmount has already been incremented here